[patch 10/12] rfc: 2fsprogs update

Alexandre Ratchov
2006-09-26T14:50:13Z

use 48bit block numbers in extents

Signed-off-by: Alexandre Ratchov <alexandre.ratchov@bull.net>

Index: e2fsprogs-1.39/lib/ext2fs/extents.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/extents.c 2006-09-22 20:26:55.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/extents.c 2006-09-22 20:27:12.000000000 +0200
@@ -72,8 +72,7 @@ errcode_t ext2fs_extent_verify(ext2_fils
struct ext4_extent_idx *ix, int ix_len)
{
show_extent(ex);
- /* FIXME: 48-bit support */
- if (ex->ee_start > fs->super->s_blocks_count)
+ if (EXT4_EE_START(ex) > EXT2_BLOCKS_COUNT(fs->super))
return EXT2_ET_EXTENT_LEAF_BAD;

if (ex->ee_len == 0)
@@ -84,19 +83,18 @@ errcode_t ext2fs_extent_verify(ext2_fils
if (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;

@@ -111,8 +109,7 @@ errcode_t ext2fs_extent_index_verify(ext
struct ext4_extent_idx *ix_prev)
{
show_index(ix);
- /* FIXME: 48-bit support */
- if (ix->ei_leaf > fs->super->s_blocks_count)
+ if (EXT4_EI_LEAF(ix) > EXT2_BLOCKS_COUNT(fs->super))
return EXT2_ET_EXTENT_INDEX_BAD;

if (ix_prev == NULL)
@@ -164,10 +161,9 @@ errcode_t ext2fs_extent_split(struct ext
++eh->eh_entries;

ex->ee_len = count;
- /* FIXME: 48-bit support */
ex_new->ee_len -= count;
ex_new->ee_block += count;
- ex_new->ee_start += count;
+ EXT4_EE_START_SET(ex_new, EXT4_EE_START(ex_new) + count);

return 0;
}
@@ -200,7 +196,7 @@ int block_iterate_extents(struct ext4_ex
for (i = 0; i < eh->eh_entries; i++, ex++) {
show_extent(ex);
for (j = 0; j < ex->ee_len; j++) {
- block_address = ex->ee_start + j;
+ block_address = EXT4_EE_START(ex) + j;
flags = (*ctx->func)(ctx->fs, &block_address,
(ex->ee_block + j),
ref_block, i,
@@ -214,15 +210,14 @@ int block_iterate_extents(struct ext4_ex

#ifdef EXT_DEBUG
printf("ugh, extent leaf changed: "
- "block was %u+%u = %u, now %u\n",
- ex->ee_start, j,
- ex->ee_start + j, block_address);
+ "block was %llu+%llu = %llu, now %llu\n",
+ EXT4_EE_START(ex), j,
+ EXT4_EE_START(ex) + j, block_address);
#endif

- /* FIXME: 48-bit support */
if (ex_prev &&
block_address ==
- ex_prev->ee_start + ex_prev->ee_len &&
+ EXT4_EE_START(ex_prev) + ex_prev->ee_len &&
ex->ee_block + j ==
ex_prev->ee_block + ex_prev->ee_len) {
/* can merge block with prev extent */
@@ -235,7 +230,9 @@ int block_iterate_extents(struct ext4_ex
i--; ex--;
break;
} else {
- ex->ee_start++;
+ EXT4_EE_START_SET(
+ ex,
+ EXT4_EE_START(ex) + 1);
ex->ee_block++;
j--;
}
@@ -244,7 +241,7 @@ int block_iterate_extents(struct ext4_ex
} else if (ex->ee_len == 1) {
/* single-block extent is easy -
* change extent directly */
- ex->ee_start = block_address;
+ EXT4_EE_START_SET(ex, block_address);
ret |= BLOCK_CHANGED;

} else if (ext2fs_extent_split(eh, ex, j)) {
@@ -266,7 +263,7 @@ int block_iterate_extents(struct ext4_ex
ret |= BLOCK_ABORT |BLOCK_ERROR;
return ret;
}
- ex->ee_start = block_address;
+ EXT4_EE_START_SET(ex, block_address);
ret |= BLOCK_CHANGED;

} else {
@@ -277,7 +274,7 @@ int block_iterate_extents(struct ext4_ex
ret |= BLOCK_ABORT |BLOCK_ERROR;
return ret;
}
- ex->ee_start = block_address;
+ EXT4_EE_START_SET(ex, block_address);
ret |= BLOCK_CHANGED;
}
}
@@ -287,6 +284,7 @@ int block_iterate_extents(struct ext4_ex
char *block_buf;
struct ext4_extent_idx *ix;
struct ext4_extent_header *nh;
+ blk_t leaf;

ret = ext2fs_get_mem(ctx->fs->blocksize, &block_buf);
if (ret)
@@ -298,39 +296,46 @@ int block_iterate_extents(struct ext4_ex
show_index(ix);
if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
!(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
- ret |= (*ctx->func)(ctx->fs, &ix->ei_leaf,
+ leaf = EXT4_EI_LEAF(ix);
+ ret |= (*ctx->func)(ctx->fs, &leaf,
BLOCK_COUNT_IND, ref_block,
i, ctx->priv_data);
+ EXT4_EI_LEAF_SET(ix, leaf);
if (ret & BLOCK_ABORT)
goto free_buf;
}
- ctx->errcode = ext2fs_read_ext_block(ctx->fs,
- ix->ei_leaf,
- block_buf);
+ ctx->errcode = ext2fs_read_ext_block(
+ ctx->fs, EXT4_EI_LEAF(ix), block_buf);
if (ctx->errcode) {
ret |= BLOCK_ERROR;
goto free_buf;
}
nh = (struct ext4_extent_header *)block_buf;
- if (ext2fs_extent_header_verify(nh,ctx->fs->blocksize)){
+ if (ext2fs_extent_header_verify(
+ nh,ctx->fs->blocksize)) {
ret |= BLOCK_ERROR;
goto free_buf;
}
- flags = block_iterate_extents(nh, ix->ei_leaf, i, ctx);
+ flags = block_iterate_extents(
+ nh, EXT4_EI_LEAF(ix), i, ctx);
if (flags & BLOCK_CHANGED)
ctx->errcode =
- ext2fs_write_ext_block(ctx->fs,
- ix->ei_leaf,
- block_buf);
+ ext2fs_write_ext_block(
+ ctx->fs, EXT4_EI_LEAF(ix),
+ block_buf);
if (flags & BLOCK_ABORT) {
ret |= BLOCK_ABORT;
goto free_buf;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
- !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
- ret |= (*ctx->func)(ctx->fs, &ix->ei_leaf,
- BLOCK_COUNT_IND, ref_block,
- i, ctx->priv_data);
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
+ leaf = EXT4_EI_LEAF(ix);
+ ret |= (*ctx->func)(ctx->fs, &leaf,
+ BLOCK_COUNT_IND,
+ ref_block,
+ i, ctx->priv_data);
+ EXT4_EI_LEAF_SET(ix, leaf);
+ }
}

free_buf:
Index: e2fsprogs-1.39/lib/ext2fs/ext4_extents.h
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/ext4_extents.h 2006-09-22 20:26:55.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/ext4_extents.h 2006-09-22 20:27:12.000000000 +0200
@@ -75,6 +75,13 @@ struct ext4_extent {
__u32 ee_start; /* low 32 bigs of physical block */
};

+#define EXT4_EE_START(e) (((__u64)(e)->ee_start_hi << 32) + (e)->ee_start)
+#define EXT4_EE_START_SET(e,blk) \
+do { \
+ (e)->ee_start = (blk); \
+ (e)->ee_start_hi = (blk) >> 32; \
+} while(0)
+
/*
* this is index on-disk structure
* it's used at all the levels, but the bottom
@@ -87,6 +94,13 @@ struct ext4_extent_idx {
__u16 ei_unused;
};

+#define EXT4_EI_LEAF(ix) (((__u64)(ix)->ei_leaf_hi << 32) + (ix)->ei_leaf)
+#define EXT4_EI_LEAF_SET(e,blk) \
+do { \
+ (ix)->ei_leaf = (blk); \
+ (ix)->ei_leaf_hi = (blk) >> 32; \
+} while(0)
+
/*
* each block (leaves and indexes), even inode-stored has header
*/
@@ -215,15 +229,22 @@ struct ext4_extents_helpers {
* callback must return valid extent (passed or newly created)
*/
typedef int (*ext_prepare_callback)(struct ext4_extents_tree *,
- struct ext4_ext_path *,
- struct ext4_extent *, int);
+ struct ext4_ext_path *,
+ struct ext4_extent *, int);
void ext4_init_tree_desc(struct ext4_extents_tree *, struct inode *);
extern int ext4_extent_tree_init(handle_t *, struct ext4_extents_tree *);
-extern int ext4_ext_calc_credits_for_insert(struct ext4_extents_tree *, struct ext4_ext_path *);
-extern int ext4_ext_insert_extent(handle_t *, struct ext4_extents_tree *, struct ext4_ext_path *, struct ext4_extent *);
-extern int ext4_ext_walk_space(struct ext4_extents_tree *, unsigned long, unsigned long, ext_prepare_callback);
-extern int ext4_ext_remove_space(struct ext4_extents_tree *, unsigned long, unsigned long);
-extern struct ext4_ext_path * ext4_ext_find_extent(struct ext4_extents_tree *, int, struct ext4_ext_path *);
+extern int ext4_ext_calc_credits_for_insert(struct ext4_extents_tree *,
+ struct ext4_ext_path *);
+extern int ext4_ext_insert_extent(handle_t *, struct ext4_extents_tree *,
+ struct ext4_ext_path *,
+ struct ext4_extent *);
+extern int ext4_ext_walk_space(struct ext4_extents_tree *, unsigned long,
+ unsigned long, ext_prepare_callback);
+extern int ext4_ext_remove_space(struct ext4_extents_tree *, unsigned long,
+ unsigned long);
+extern struct ext4_ext_path *ext4_ext_find_extent(struct ext4_extents_tree *,
+ int,
+ struct ext4_ext_path *);

static inline void
ext4_ext_invalidate_cache(struct ext4_extents_tree *tree)
Index: e2fsprogs-1.39/lib/ext2fs/bmap.c
===================================================================
--- e2fsprogs-1.39.orig/lib/ext2fs/bmap.c 2006-09-22 20:26:55.000000000 +0200
+++ e2fsprogs-1.39/lib/ext2fs/bmap.c 2006-09-22 20:27:12.000000000 +0200
@@ -46,7 +46,7 @@ static errcode_t block_bmap_extents(stru
for (i = 0; i < eh->eh_entries; i++, ex++) {
if ((ex->ee_block <= block) &&
(block < ex->ee_block + ex->ee_len)) {
- *phys_blk = ex->ee_start +
+ *phys_blk = EXT4_EE_START(ex) +
(block - ex->ee_block);
return 0;
}
@@ -68,7 +68,7 @@ static errcode_t block_bmap_extents(stru
if (ix->ei_block < 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) {
ret = BLOCK_ERROR;
Index: e2fsprogs-1.39/e2fsck/pass1.c
===================================================================
--- e2fsprogs-1.39.orig/e2fsck/pass1.c 2006-09-22 20:26:55.000000000 +0200
+++ e2fsprogs-1.39/e2fsck/pass1.c 2006-09-22 20:27:37.000000000 +0200
@@ -1509,14 +1509,18 @@ static int e2fsck_ext_block_verify(struc
e2fsck_t ctx = p->ctx;
struct problem_context *pctx = p->pctx;
int i, bad = 0, changed = 0;
+ int flag_64bit;
+
+ flag_64bit = p->ctx->fs->super->s_feature_incompat &
+ EXT4_FEATURE_INCOMPAT_64BIT;

if (eh->eh_depth == 0) {
struct ext4_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;
changed++;
}
@@ -1541,9 +1545,9 @@ static int e2fsck_ext_block_verify(struc
struct ext4_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;
changed++;
}