From 8a8f36540bbf5d4397cf476e216e9a720b5c1d8e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 12 Oct 2009 21:59:37 -0400 Subject: [PATCH] e2fsck: Fix handling of non-zero i_blocks_high field E2fsck was not properly printing the i_blocks field in filesystem corruption messages, and it was not properly checking i_blocks_hi and i_blocks_lo, either. This commit fixes this. Thanks to Felipe Conteras for pointing this out. Signed-off-by: "Theodore Ts'o" --- e2fsck/message.c | 7 ++++--- e2fsck/pass1.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/e2fsck/message.c b/e2fsck/message.c index 5e28812..9aaedc5 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -258,7 +258,7 @@ static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch, /* * This function expands '%IX' expressions */ -static _INLINE_ void expand_inode_expression(char ch, +static _INLINE_ void expand_inode_expression(ext2_filsys fs, char ch, struct problem_context *ctx) { struct ext2_inode *inode; @@ -292,7 +292,8 @@ static _INLINE_ void expand_inode_expression(char ch, printf("%u", large_inode->i_extra_isize); break; case 'b': - if (inode->i_flags & EXT4_HUGE_FILE_FL) + if (fs->super->s_feature_ro_compat & + EXT4_FEATURE_RO_COMPAT_HUGE_FILE) printf("%llu", inode->i_blocks + (((long long) inode->osd2.linux2.l_i_blocks_hi) << 32)); @@ -528,7 +529,7 @@ void print_e2fsck_message(e2fsck_t ctx, const char *msg, expand_at_expression(ctx, *cp, pctx, &first, recurse); } else if (cp[0] == '%' && cp[1] == 'I') { cp += 2; - expand_inode_expression(*cp, pctx); + expand_inode_expression(fs, *cp, pctx); } else if (cp[0] == '%' && cp[1] == 'D') { cp += 2; expand_dirent_expression(fs, *cp, pctx); diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 9b12005..2531e57 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -1792,6 +1792,15 @@ static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx, ext2fs_extent_free(ehandle); } +static blk64_t ext2fs_inode_i_blocks(ext2_filsys fs, + struct ext2_inode *inode) +{ + return (inode->i_blocks | + (fs->super->s_feature_ro_compat & + EXT4_FEATURE_RO_COMPAT_HUGE_FILE ? + (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0)); +} + /* * This subroutine is called on each inode to account for all of the * blocks used by that inode. @@ -1972,7 +1981,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, if (LINUX_S_ISREG(inode->i_mode) && (inode->i_size_high || inode->i_size & 0x80000000UL)) ctx->large_files++; - if ((pb.num_blocks != inode->i_blocks) || + if ((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) || ((fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && (inode->i_flags & EXT4_HUGE_FILE_FL) && -- 1.8.3.1