48-bit extents in e2fsprogs
RFC PATCH 8/12 48-bit extents in e2fsprogs
This patch contains the changes to support 48-bit block numbers in extents.
This patch is not complete, the new function block_iterate_extents() was not updated.
e2fsck/pass1.c | 15 +++++++++------ lib/ext2fs/bmap.c | 6 +++--- lib/ext2fs/ext3_extents.h | 30 ++++++++++++++++++++++++++++++ lib/ext2fs/extent.c | 16 ++++++---------- 4 files changed, 48 insertions(+), 19 deletions(-)
lib/ext2fs/extent.c +6 -10
@@ -105,8 +105,7 @@ errcode_t ext2fs_extent_verify(ext2_fils struct ext3_extent_idx *ix, int ix_len) {ext_show_extent (ex ); -/* FIXME: 48-bit support */ -if (ex->ee_start >EXT2_BLOCKS_COUNT (fs->super)) +if (EXT4_EE_START (ex) >EXT2_BLOCKS_COUNT (fs->super))return EXT2_ET_EXTENT_LEAF_BAD ;if (ex->ee_len ==0 )
@@ -120,19 +119,18 @@ errcode_t ext2fs_extent_verify(ext2_filsif (ex->ee_block ==0 )return EXT2_ET_EXTENT_LEAF_BAD ; -/* FIXME: 48-bit support */ /* extents must be in logical offset order */ if (ex->ee_block < ex_prev->ee_block + ex_prev->ee_len)return EXT2_ET_EXTENT_LEAF_BAD ;/* extents must not overlap physical blocks */ -if ((ex->ee_start < ex_prev->ee_start + ex_prev->ee_len) && - (ex->ee_start + ex->ee_len > ex_prev->ee_start)) +if ((EXT4_EE_START (ex) < +EXT4_EE_START (ex_prev) + ex_prev->ee_len) && + (EXT4_EE_START (ex) + ex->ee_len >EXT4_EE_START (ex_prev)))return EXT2_ET_EXTENT_LEAF_BAD ; }if (ix) { -/* FIXME: 48-bit support */ if (ex->ee_block < ix->ei_block)return EXT2_ET_EXTENT_LEAF_BAD ;
@@ -148,8 +146,7 @@ errcode_t ext2fs_extent_index_verify(ext struct ext3_extent_idx *ix_prev) {ext_show_index (ix); -/* FIXME: 48-bit support */ -if (ix->ei_leaf >EXT2_BLOCKS_COUNT (fs->super)) +if (EXT4_EI_LEAF (ix) >EXT2_BLOCKS_COUNT (fs->super))return EXT2_ET_EXTENT_INDEX_BAD ;if (ix_prev ==NULL )
@@ -193,10 +190,9 @@ errcode_t ext2fs_extent_split_internal(s ++eh->eh_entries; ex->ee_len = offs; -/* FIXME: 48-bit support */ ex_new->ee_len -= offs; ex_new->ee_block += offs; - ex_new->ee_start += offs; +EXT4_EE_START_SET (ex_new,EXT4_EE_START (ex_new) + offs);return 0 ; }
lib/ext2fs/ext3_extents.h +30 -0
@@ -87,6 +87,36 @@ struct ext3_extent_idx {__u16 ei_unused; }; +#ifdef _EXT4FS_ +#define EXT4_EE_START (e) (((__u64)(e)->ee_start_hi << 32) + (e)->ee_start) +#define EXT4_EI_LEAF (ix) (((__u64)(ix)->ei_leaf_hi << 32) + (ix)->ei_leaf) + +#define EXT4_EE_START_SET (e,blk) \ + do { \ + (e)->ee_start = (blk); \ + (e)->ee_start_hi = (blk) >> 32; \ + } while(0) + +#define EXT4_EI_LEAF_SET (e,blk) \ + do { \ + (ix)->ei_leaf = (blk); \ + (ix)->ei_leaf_hi = (blk) >> 32; \ + } while(0) +#else +#define EXT4_EE_START (e) ((e)->ee_start) +#define EXT4_EI_LEAF (ix) ((ix)->ei_leaf) + +#define EXT4_EE_START_SET (e,blk) \ + do { \ + (e)->ee_start = (blk); \ + } while(0) + +#define EXT4_EI_LEAF_SET (e,blk) \ + do { \ + (ix)->ei_leaf = (blk); \ + } while(0) +#endif +/* * each block (leaves and indexes), even inode-stored has header */
lib/ext2fs/bmap.c +3 -3
@@ -52,8 +52,8 @@ static errcode_t block_bmap_extents(voidcontinue ;if (block < ex->ee_block + ex->ee_len) -/* FIXME: 48-bit */ - *phys_blk = ex->ee_start + block - ex->ee_block; + *phys_blk =EXT4_EE_START (ex) + + (block - ex->ee_block);/* only the first extent > block could hold the block * otherwise the extents would overlap */
@@ -72,7 +72,7 @@ static errcode_t block_bmap_extents(voidif (block < ix->ei_block)continue ; - ret =io_channel_read_blk (fs->io, ix->ei_leaf,1 , + ret =io_channel_read_blk (fs->io,EXT4_EI_LEAF (ix),1 , block_buf);if (ret) goto free_buf;
e2fsck/pass1.c +9 -6
@@ -1604,6 +1604,10 @@ static int e2fsck_ext_block_verify(struce2fsck_t ctx = p->ctx;struct problem_context *pctx = p->pctx;int i, problem =0 ; +int flag_64bit; + + flag_64bit = p->ctx->fs->super->s_feature_incompat & +EXT4_FEATURE_INCOMPAT_64BIT ;if (ext2fs_extent_header_verify (eh, buflen))return PR_1_EXTENT_IDX_BAD ;
@@ -1618,9 +1622,8 @@ static int e2fsck_ext_block_verify(strucstruct ext3_extent *ex =EXT_FIRST_EXTENT (eh), *ex_prev =NULL ;for (i =0 ; i < eh->eh_entries; i++, ex++) { -/* FIXME: 48-bit check for s_blocks_count_hi */ -if (ex->ee_start_hi &&fix_problem (ctx,PR_1_EXTENT_HI , - pctx)) { +if (!flag_64bit && ex->ee_start_hi && +fix_problem (ctx,PR_1_EXTENT_HI , pctx)) { ex->ee_start_hi =0 ; problem =PR_1_EXTENT_CHANGED ; }
@@ -1644,9 +1647,9 @@ static int e2fsck_ext_block_verify(strucstruct ext3_extent_idx *ix =EXT_FIRST_INDEX (eh), *ix_prev =NULL ;for (i =0 ; i < eh->eh_entries; i++, ix++) { -/* FIXME: 48-bit check for s_blocks_count_hi */ -if (ix->ei_leaf_hi &&fix_problem (ctx,PR_1_EXTENT_HI , - pctx)) { +if (!flag_64bit && + ix->ei_leaf_hi && +fix_problem (ctx,PR_1_EXTENT_HI , pctx)) { ix->ei_leaf_hi = ix->ei_unused =0 ; problem =PR_1_EXTENT_CHANGED ; }
Quoted 19 lines · Valerie Clement
lib/ext2fs/ext3_extents.h +19
-0+#ifdef _EXT4FS_ +#define EXT4_EE_START (e) (((__u64)(e)->ee_start_hi << 32) + (e)->ee_start) +#define EXT4_EI_LEAF (ix) (((__u64)(ix)->ei_leaf_hi << 32) + (ix)->ei_leaf) + +#define EXT4_EE_START_SET (e,blk) \ + do { \ + (e)->ee_start = (blk); \ + (e)->ee_start_hi = (blk) >> 32; \ + } while(0) + +#define EXT4_EI_LEAF_SET (e,blk) \ + do { \ + (ix)->ei_leaf = (blk); \ + (ix)->ei_leaf_hi = (blk) >> 32; \ + } while(0) +#else +#define EXT4_EE_START (e) ((e)->ee_start) +#define EXT4_EI_LEAF (ix) ((ix)->ei_leaf) +
lib/ext2fs/ext3_extents.h struct ext3_extent_idx { · line 118
Quoted 10 lines
lib/ext2fs/ext3_extents.h +10
-0+#define EXT4_EE_START_SET (e,blk) \ + do { \ + (e)->ee_start = (blk); \ + } while(0) + +#define EXT4_EI_LEAF_SET (e,blk) \ + do { \ + (ix)->ei_leaf = (blk); \ + } while(0) +#endif
Ideally this would also be conditional upon INCOMPAT_64BIT and the fs > 2^32 blocks, because some older versions of the extents code didn't clear the ee_start_hi and ei_lead fields correctly.
That said, I'm not always sure we have access to a superblock somehow in every function where we need this macro, and we've been shipping extents patches and e2fsck which has fixed this problem, but not all of our customers/partners are using the latest lustre or e2fsprogs, or have necessarily run e2fsck on their filesystems..
Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.