This doesn't surprise me. We should add some checks to simply not allow the file system growing greater than 16TB if the 64-bit feature is not set for now. Making this work is going to be tricky, because enabling the 64-bit feature doubles the size of the block group descriptors, which means we have to make room for them. This could involve moving files out of the way, as well as moving the inode table. This means that we may want to enable the 64-bit feature flag if there is an expectation that the filesystem might be grown to a size large I'm not sure I understand that last sentence; it's not parsing as an understandable English sentence, sorry. Are you saying that both attempts to grow and shrink the filesystem is failing? If so, how? Are you getting an error message? Is it appearing to succeed but the file system size isn't changing? Thanks for the bug report, - Ted --
Sounds like I must enable 64-bit feature when mkfs.
Then it will work, right?
But base on my test, it will occur core dump when resize:
(gdb) bt
#0 0x00000000004160bf in ext2fs_test_bit64 ()
#1 0x0000000000416318 in ba_test_bmap ()
#2 0x0000000000410629 in ext2fs_test_generic_bmap ()
#3 0x0000000000410656 in ext2fs_test_block_bitmap_range2 ()
#4 0x000000000040873d in ext2fs_get_free_blocks2 ()
#5 0x000000000040936d in ext2fs_allocate_group_table ()
#6 0x0000000000404456 in adjust_fs_info ()
#7 0x0000000000404a81 in resize_fs ()
#8 0x00000000004069c7 in main ()
I do the following modification
(to enable "EXT4_FEATURE_INCOMPAT_64BIT" and "EXT2_FLAG_64BITS"):
misc/mke2fs.c :
@@ -1530,6 +1945,8 @@ static void PRS(int argc, char *argv[])
EXT2_BLOCK_SIZE(&fs_param));
exit(1);
}
+ fs_param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
ext2fs_blocks_count_set(&fs_param, fs_blocks_count);
resize/resize2fs.c :
@@ -585,6 +598,9 @@ static errcode_t adjust_superblock(ext2_resize_t
rfs, blk64_t new_size)
if (retval)
return retval;
+ fs->super->s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
retval = adjust_fs_info(fs, rfs->old_fs, rfs->reserve_blocks, new_size);
lib/ext2fs/openfs.c :
@@ -109,6 +109,8 @@ errcode_t ext2fs_open2(const char *name, const
char *io_options,
memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
fs->flags = flags;
+ fs->flags |= EXT2_FLAG_64BITS;
Sorry for my poor English. The last sentence means "succeed but the
file system size isn't changing".
I also remove "flex_bg" feature in this case.
Thanks.
--
On 2010-06-22, at 03:15, Hsuan-Ting wrote: Yes, that you can't just set this flag on an existing filesystem and expect it to work. The only possibility to do this is to have resize2fs move the inode tables in groups where there are group descriptor tables (as if it were growing the filesystem) and then write 64-byte group descriptors. Cheers, Andreas --
Hi Andreas ,
If the size is not big enough, "-O 64bit" will get the following error messages:
"/dev/sda3: Cannot create filesystem with requested number of inodes
while setting up superblock"
And base on my trace, I think "-O 64bit" won't always work.
It will check the blocks count as the following code in mke2fs.c:
if ((fs_blocks_count > MAX_32_NUM) &&
!(fs_param.s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) &&
get_bool_from_profile(fs_types, "auto_64-bit_support", 0)) {
fs_param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
fs_param.s_feature_compat &= ~EXT2_FEATURE_COMPAT_RESIZE_INODE;
}
So I do the above modification to force 64bit feature enabling.
I also find some strange things when mkfs:
If the size(ex. 91.3G) isn't big enough it will use "floppy" settings
in mke2fs.conf instead of "ext4".
I do the following steps, it seems work but still has core dump messages:
1. remove "resize_inode" and "flex_bg" features ,and let "floppy"
settings the same as "ext4" in mke2fs.conf
2. build linera raid with a small partition of 1 disks (91.3G)
3. mkfs.ext4 to this raid
5. grow this linear raid (91.3G + 9 x 2TB disks)
6. do resize2fs
6. get the following core dump:
[458783.472100] resize2fs[27376]: segfault at 7fa420f14000 ip
0000000000416055 sp 00007fff533a99e8 error 4 in
resize2fs[400000+1e000]
Segmentation fault (core dumped)
(gdb) bt
#0 0x000000000041606f in ext2fs_test_bit64 ()
Cannot access memory at address 0x7fff2be12328
8. but the fs size have grown (16.3T)
So I think if the 64bit feature is enabled when mkfs, it will reserve
more room in file system
And we can grow it up bigger than 16TB.
It seems there are some issues in "master" still, I'll try "pu" branch later.
Thanks.
-HsuanTing
--
Hi Andreas ,
Sorry, please forgot what I said before.
Base on the log(some build raid error), it seems
I didn't stop the old raid before starting this new test.
So this result isn't correct.
-HsuanTing
Thanks.
--
Hi Ted,
I try to :
1. force to enable 64bits feature even the size <16TB
2. fix the "block_bmap" overflow issue when resizing.
It seems OK when resize to >16TB .
(the content of the test file is correct).
But after it grown up, it will get error when do fsck.
My modification is as the following:
lib/ext2fs/openfs.c
@@ -109,6 +109,8 @@ errcode_t ext2fs_open2(const char *name, const
char *io_options,
memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
fs->flags = flags;
+ fs->flags |= EXT2_FLAG_64BITS;
/* don't overwrite sb backups unless flag is explicitly cleared */
fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
fs->umask = 022;
misc/mke2fs.c
@@ -1530,6 +1531,8 @@ static void PRS(int argc, char *argv[])
EXT2_BLOCK_SIZE(&fs_param));
exit(1);
}
+ fs_param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
ext2fs_blocks_count_set(&fs_param, fs_blocks_count);
resize/resize2fs.c
index 064c4c4..e28f5f2 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -294,7 +294,8 @@ errcode_t adjust_fs_info(ext2_filsys fs, ext2_filsys old_fs,
blk64_t overhead = 0;
blk64_t rem;
blk64_t blk, group_block;
- ext2_ino_t real_end;
+ __u64 real_end;
blk64_t adj, old_numblocks, numblocks, adjblocks;
unsigned long i, j, old_desc_blocks, max_group;
unsigned int meta_bg, meta_bg_size;
@@ -381,9 +382,9 @@ retry:
fs->inode_map);
if (retval) goto errout;
- real_end = ((EXT2_BLOCKS_PER_GROUP(fs->super)
- * fs->group_desc_count)) - 1 +
- fs->super->s_first_data_block;
+ real_end = ((__u64)(EXT2_BLOCKS_PER_GROUP(fs->super)
+ * (__u64)fs->group_desc_count)) - 1ULL +
+ ...No, this will completely break the ext2/3/4 on-disk format. What you need to make sure is that when resize2fs is resizing the filesystem that it limits the total number of inodes in the filesystem to 2^32-1. I guess that means the groups beyond the 2^32nd inode will have no inode table at all, which is a bit strange, but something that we need to expect in e2fsck. I guess the alternative would be to allocate the inode table, but we couldn't (yet?) use those inodes without significant work to support 64-bit inode numbers. Probably the first step in that direction would be the "dirdata" patch that we have to allow storing extra data in directory entries. Cheers, Andreas --
Hi Andreas, I've follow your steps, fill nearly the whole filesystem before resizing. After resizing and do fsck, the files seems OK. My test steps is as following: 1. build a linear raid ( 1 X 2TB disk ) 2. fill nearly the whole filesystem (copy 133 * "test folders" to this volume, test folders include "kernel source" + 10G HD video + pdf files + small video) 3. grown the linear raid to >16TB (10 x 2TB) 4. do resize ( resize -fpF /dev/md2 ) 5. after resize the "df" result isn't correct, and it will occur error when "rm" files ("df" its "Used colum" show "114.3M", actually it must be "1.5T") ("rm error" I add after these steps) 6. do "fsck.ext4 -yvf", then "df" is correct 7. copy 30 * "test folders" again to fill new space 8. Do some roughly verification, the content of files and rm command seems OK: (roughly verification: "diff -r" to compare one test kernel source with original, play video and open pdf files) Now I'm doing "llverfs -l" and run a script to recursive do "diff -r" for verifying all test kernel souce. If it occurs error, I'll update later. If you have any new idea of these error(df and fsck) or any opinions, please let me know. I'm still trying to find these error root cause. Thanks. "rm error": [511874.472848] EXT4-fs error (device md2): mb_free_blocks: double-free of inode 16391's block 66051(bit 515 in group 2) [511874.483885] Aborting journal on device md2-8. [511874.488741] EXT4-fs (md2): Remounting filesystem read-only [511874.494928] EXT4-fs error (device md2) in ext4_reserve_inode_write: Journal has aborted [511874.503288] EXT4-fs error (device md2) in ext4_reserve_inode_write: Journal has aborted [511874.511791] EXT4-fs error (device md2) in ext4_ext_remove_space: Journal has aborted [511874.520125] EXT4-fs error (device md2) in ext4_reserve_inode_write: Journal has aborted [511874.528676] EXT4-fs error (device md2) in ext4_ext_truncate: Journal has aborted [511874.536581] EXT4-fs error (device md2) ...
