convert blk_t to 64-bit for ext4 FS in e2fsprogs
RFC PATCH 10/11 convert blk_t to 64-bit for ext4 FS in e2fsprogs
This patch converts blk_t type to __u64 when compiling code with "_EXT4FS_" option. Force the 64-bit feature when the filesystem is greater than 2**32 blocks.
Changes from the previous version:
- ask for confirmation before creating the ext4 filesystem
lib/ext2fs/ext2_fs.h | 3 ++- lib/ext2fs/ext2fs.h | 15 +++++++++++---- misc/mke2fs.c | 14 +++++++++++++- 3 files changed, 26 insertions(+), 6 deletions(-)
misc/mke2fs.c +13 -1
@@ -1273,6 +1273,17 @@ static void PRS(int argc, char *argv[]) ));exit (1 ); } +if (dev_size > ((unsigned )1 <<31 ) && + desc_size <EXT2_MIN_DESC_SIZE_64BIT ) { +fprintf (stderr,_ ("\nWarning: " +"Filesystem greater than 2**32 blocks.\n" +"Force 64-bit incompatible feature ?\n\n" )); +proceed_question (); + fs_param.s_feature_incompat |= +EXT4_FEATURE_INCOMPAT_64BIT ; + fs_param.s_desc_size = +EXT2_MIN_DESC_SIZE_64BIT ; + }EXT2_BLOCKS_COUNT_SET (&fs_param, dev_size);if (sys_page_size >EXT2_BLOCK_SIZE (&fs_param)) fs_param.s_blocks_count &= ~((sys_page_size /
@@ -1445,7 +1456,8 @@ static void PRS(int argc, char *argv[]) fs_param.s_desc_size =EXT2_MIN_DESC_SIZE_64BIT ; } -if (!force &&EXT2_BLOCKS_COUNT (&fs_param) >= ((unsigned )1 <<31 )) { +if (!force && (fs_param.s_desc_size <EXT2_MIN_DESC_SIZE_64BIT ) + &&EXT2_BLOCKS_COUNT (&fs_param) >= ((unsigned )1 <<31 )) {com_err (program_name,0 ,_ ("Filesystem too large. No more than 2**31-1 blocks\n" "\t (8TB using a blocksize of 4k) are currently supported." ));
lib/ext2fs/ext2fs.h +11 -4
@@ -73,7 +73,12 @@ extern "C" {#endif /* EXT2_FLAT_INCLUDES */ typedef __u32 ext2_ino_t ; +#ifdef _EXT4FS_ +#define _EXT2_64BIT_BLK_T 1 +typedef __u64 blk_t ; +#else typedef __u32 blk_t ; +#endif typedef __u64 blk64_t ;typedef __u32 dgrp_t ;typedef __u32 ext2_off_t ;
@@ -491,13 +496,15 @@ struct ext2fs_extent { EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\ EXT2_FEATURE_INCOMPAT_META_BG|\ EXT3_FEATURE_INCOMPAT_RECOVER|\ - EXT3_FEATURE_INCOMPAT_EXTENTS) + EXT3_FEATURE_INCOMPAT_EXTENTS|\ + EXT4_FEATURE_INCOMPAT_64BIT)#else #define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\ EXT2_FEATURE_INCOMPAT_META_BG|\ EXT3_FEATURE_INCOMPAT_RECOVER|\ - EXT3_FEATURE_INCOMPAT_EXTENTS) + EXT3_FEATURE_INCOMPAT_EXTENTS|\ + EXT4_FEATURE_INCOMPAT_64BIT)#endif #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\ EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
@@ -1263,7 +1270,7 @@ _INLINE_ int ext2fs_group_of_ino(ext2_fi _INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group) {return fs->super->s_first_data_block + - (group * fs->super->s_blocks_per_group); + (group * (blk_t )EXT2_BLOCKS_PER_GROUP (fs->super)); }/*
@@ -1274,7 +1281,7 @@ _INLINE_ blk_t ext2fs_group_last_block(ereturn (group == fs->group_desc_count -1 ?EXT2_BLOCKS_COUNT (fs->super) -1 :ext2fs_group_first_block (fs, group) + - (fs->super->s_blocks_per_group -1 )); + (EXT2_BLOCKS_PER_GROUP (fs->super) -1 )); } _INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
lib/ext2fs/ext2_fs.h +2 -1
@@ -678,7 +678,8 @@ struct ext2_super_block {#define EXT2_FEATURE_COMPAT_SUPP 0 -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) +#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT4_FEATURE_INCOMPAT_64BIT)#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
misc/mke2fs.c static void PRS(int argc, char *argv[]) · line 1277
Quoted 6 lines · Valerie Clement
misc/mke2fs.c +5
-0@@ -1273,6 +1273,17 @@ static void PRS(int argc, char *argv[]) +if (dev_size > ((unsigned )1 <<31 ) && + fs_param.s_feature_incompat |= + EXT4_FEATURE_INCOMPAT_64BIT; + fs_param.s_desc_size = +EXT2_MIN_DESC_SIZE_64BIT ;
This should also set EXT4_FEATURE_INCOMPAT_EXTENTS, as that is required for 64-bit filesystems.
misc/mke2fs.c static void PRS(int argc, char *argv[]) · line 1463
Quoted 6 lines
misc/mke2fs.c +2
-1-if (!force &&EXT2_BLOCKS_COUNT (&fs_param) >= ((unsigned )1 <<31 )) { +if (!force && (fs_param.s_desc_size <EXT2_MIN_DESC_SIZE_64BIT ) + &&EXT2_BLOCKS_COUNT (&fs_param) >= ((unsigned )1 <<31 )) {com_err (program_name,0 ,_ ("Filesystem too large. No more than 2**31-1 blocks\n" "\t (8TB using a blocksize of 4k) are currently supported." ));
Ah, is this where you got the (1 << 31) limit from? I thought Eric fixed ext2/ext3 to handle 2^32 - 1 block filesystems, but since there are a large number of bugs for > 8TB filesystems I don't object to forcing INCOMPAT_64BIT for larger ones.
lib/ext2fs/ext2fs.h extern "C" { · line 78
Quoted 7 lines
lib/ext2fs/ext2fs.h +5
-0@@ -73,7 +73,12 @@ extern "C" { +#ifdef _EXT4FS_ +#define _EXT2_64BIT_BLK_T 1 +typedef __u64 blk_t ; +#else typedef __u32 blk_t ; +#endif
This should force the library .so version to be different, so that we don't have applications suddenly failing when the ABI changes.
lib/ext2fs/ext2fs.h _INLINE_ int ext2fs_group_of_ino(ext2_fi · line 1273
Quoted 5 lines
lib/ext2fs/ext2fs.h +1
-0@@ -1263,7 +1270,7 @@ _INLINE_ int ext2fs_group_of_ino(ext2_fi _INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group) {return fs->super->s_first_data_block + + (group * (blk_t )EXT2_BLOCKS_PER_GROUP (fs->super));
The (blk_t) cast should be handled inside the macro to avoid subtle errors. I suspect it already has to do this, or it wouldn't be able to return a large enough value for a 64-bit filesystem?
Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.