Re: Weird ext4 bug: 256P used?

From: Felipe Contreras
Date: Tue Oct 13 2009 - 07:13:55 EST


On Tue, Oct 13, 2009 at 5:11 AM, Theodore Tso <tytso@xxxxxxx> wrote:
> Here's a patch to e2fsprogs which will cause e2fsck to find and fix
> the filesystem corruption. ÂI'm not sure how i_blocks_hi was set to
> the incorect value in the first place, but this should fix the
> filesystem for you (largely a cosmetic issue).
>
> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â- Ted
>
> commit 8a8f36540bbf5d4397cf476e216e9a720b5c1d8e
> Author: Theodore Ts'o <tytso@xxxxxxx>
> Date: Â Mon Oct 12 21:59:37 2009 -0400
>
> Â Â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" <tytso@xxxxxxx>

This patch fixes my problem.
Tested-by: Felipe Contreras <felipe.contreras@xxxxxxxxx>

However, I had one problem compiling:

> 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)

My compiler fails because this function is already defined at
'lib/ext2fs/ext2fs.h' as non static.

> +{
> + Â Â Â 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) &&

--
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/