From a47426914745b7d50bb58a3d44b3509c647c637e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 9 Aug 2001 04:14:04 -0400 Subject: [PATCH] pass1.c, pass2.c, problem.c, problem.h: Fix bug introduced by Andreas's symlink code; check_blocks() was unconditionally testing inode_bad_map without checking to see if it existed first. Fixed problem a different way; we now no longer check inode_bad_map at all, since the file might not get deleted in pass 2 anyway. We move the large file feature reconciliation code to to e2fsck_pass2(), and in deallocate_inode() in pass2.c, we decrement the large files counter if we're about to delete a large file. --- e2fsck/ChangeLog | 10 ++++++++++ e2fsck/pass1.c | 27 +-------------------------- e2fsck/pass2.c | 41 ++++++++++++++++++++++++++++++++++++----- e2fsck/problem.c | 10 +++++----- e2fsck/problem.h | 6 +++--- 5 files changed, 55 insertions(+), 39 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 0c5ed97..d2027f3 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,5 +1,15 @@ 2001-08-09 Theodore Tso + * pass1.c, pass2.c, problem.c, problem.h: Fix bug introduced by + Andreas's symlink code; check_blocks() was unconditionally + testing inode_bad_map without checking to see if it + existed first. Fixed problem a different way; we now no + longer check inode_bad_map at all, since the file might + not get deleted in pass 2 anyway. We move the large file + feature reconciliation code to to e2fsck_pass2(), and in + deallocate_inode() in pass2.c, we decrement the large + files counter if we're about to delete a large file. + * unix.c (show_stats): Print the number of large files in verbose mode. diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index ebed95d..692ebcf 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -711,29 +711,6 @@ endit: ext2fs_free_mem((void **) &block_buf); - if (ctx->large_files) { - if (!(sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && - fix_problem(ctx, PR_1_FEATURE_LARGE_FILES, &pctx)) { - sb->s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_LARGE_FILE; - ext2fs_mark_super_dirty(fs); - } - if (sb->s_rev_level == EXT2_GOOD_OLD_REV && - fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { - ext2fs_update_dynamic_rev(fs); - ext2fs_mark_super_dirty(fs); - } - } else if (!ctx->large_files && - (sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { - if (fs->flags & EXT2_FLAG_RW) { - sb->s_feature_ro_compat &= - ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE; - ext2fs_mark_super_dirty(fs); - } - } - #ifdef RESOURCE_TRACK if (ctx->options & E2F_OPT_TIME2) { e2fsck_clear_progbar(ctx); @@ -1249,9 +1226,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, } pctx->num = 0; } - if (!pb.is_dir && - (inode->i_size_high || inode->i_size & 0x80000000UL) && - !ext2fs_test_inode_bitmap(ctx->inode_bad_map, ino)) + if (!pb.is_dir && (inode->i_size_high || inode->i_size & 0x80000000UL)) ctx->large_files++; if (pb.num_blocks != inode->i_blocks) { pctx->num = pb.num_blocks; diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 7575b81..e424eb5 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -76,12 +76,14 @@ struct check_dir_struct { void e2fsck_pass2(e2fsck_t ctx) { - ext2_filsys fs = ctx->fs; - char *buf; + struct ext2_super_block *sb = ctx->fs->super; + struct problem_context pctx; + ext2_filsys fs = ctx->fs; + char *buf; #ifdef RESOURCE_TRACK struct resource_track rtrack; #endif - struct dir_info *dir; + struct dir_info *dir; struct check_dir_struct cd; #ifdef RESOURCE_TRACK @@ -146,6 +148,31 @@ void e2fsck_pass2(e2fsck_t ctx) ext2fs_free_inode_bitmap(ctx->inode_reg_map); ctx->inode_reg_map = 0; } + + clear_problem_context(&pctx); + if (ctx->large_files) { + if (!(sb->s_feature_ro_compat & + EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && + fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) { + sb->s_feature_ro_compat |= + EXT2_FEATURE_RO_COMPAT_LARGE_FILE; + ext2fs_mark_super_dirty(fs); + } + if (sb->s_rev_level == EXT2_GOOD_OLD_REV && + fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { + ext2fs_update_dynamic_rev(fs); + ext2fs_mark_super_dirty(fs); + } + } else if (!ctx->large_files && + (sb->s_feature_ro_compat & + EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { + if (fs->flags & EXT2_FLAG_RW) { + sb->s_feature_ro_compat &= + ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE; + ext2fs_mark_super_dirty(fs); + } + } + #ifdef RESOURCE_TRACK if (ctx->options & E2F_OPT_TIME2) { e2fsck_clear_progbar(ctx); @@ -647,13 +674,17 @@ static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) if (!ext2fs_inode_has_valid_blocks(&inode)) return; - + + if (!LINUX_S_ISDIR(inode.i_mode) && + (inode.i_size_high || inode.i_size & 0x80000000UL)) + ctx->large_files--; + if (inode.i_file_acl) { ext2fs_unmark_block_bitmap(ctx->block_found_map, inode.i_file_acl); ext2fs_unmark_block_bitmap(fs->block_map, inode.i_file_acl); } - + ext2fs_mark_bb_dirty(fs); pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, deallocate_inode_block, ctx); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index b60a8f5..8044e67 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -515,11 +515,6 @@ static const struct e2fsck_problem problem_table[] = { /* Suppress messages prompt */ { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK }, - /* Filesystem contains large files, but has no such flag in sb */ - { PR_1_FEATURE_LARGE_FILES, - N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"), - PROMPT_FIX, 0 }, - /* Imagic flag set on an inode when filesystem doesn't support it */ { PR_1_SET_IMAGIC, N_("@i %i has imagic flag set. "), @@ -936,6 +931,11 @@ static const struct e2fsck_problem problem_table[] = { N_("@a @b @F is invalid (%If).\n"), PROMPT_CLEAR, 0 }, + /* Filesystem contains large files, but has no such flag in sb */ + { PR_2_FEATURE_LARGE_FILES, + N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"), + PROMPT_FIX, 0 }, + /* Pass 3 errors */ /* Pass 3: Checking directory connectivity */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 7dec436..6792ecb 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -297,9 +297,6 @@ struct problem_context { /* Suppress messages prompt */ #define PR_1_SUPPRESS_MESSAGES 0x01002D -/* Filesystem contains large files, but has no such flag in sb */ -#define PR_1_FEATURE_LARGE_FILES 0x01002E - /* Imagic flag set on an inode when filesystem doesn't support it */ #define PR_1_SET_IMAGIC 0x01002F @@ -556,6 +553,9 @@ struct problem_context { /* i_file_acl (extended attribute) is bad */ #define PR_2_FILE_ACL_BAD 0x020032 +/* Filesystem contains large files, but has no such flag in sb */ +#define PR_2_FEATURE_LARGE_FILES 0x020033 + /* * Pass 3 errors */ -- 1.8.3.1