diff options
author | Theodore Ts'o <tytso@mit.edu> | 2011-06-16 01:13:42 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-06-16 01:22:02 -0400 |
commit | a3efe4842054175d01b465fbe0b29b9be8b800a1 (patch) | |
tree | e00375edf712715a27328af15306accf366efc2a | |
parent | 96367ad3bc849220651b20f41340b48e07e82b04 (diff) | |
download | e2fsprogs-a3efe4842054175d01b465fbe0b29b9be8b800a1.tar.gz |
e2fsck: fix mysterious "FILE SYSTEM WAS MODIFIED" with no changes
Commit 2a77a784a3 (firest released in e2fsprogs 1.33) compared
superblock summary free blocks and inode counts with the allocation
bitmap counts before starting the file system check proper, and if
they differed, set the superblock and marked it as dirty. If no other
file systme changes were required, this would cause a "*** FILE SYSTEM
WAS MODIFIED ***" message without any explanation of what e2fsck had
changed.
We fix this by only setting the superblock summary free block/inodes
counts if we are skipping a full check, and in non-preen mode, e2fsck
will now print an explicit message stating how the superblock had been
updated.
In a full check, any updates to the superblock free blocks/inodes
fields will be noted in pass5.
This change requires changing a few test results (essentially
reversing the changes made in commit 2a77a784a3).
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | e2fsck/e2fsck.h | 4 | ||||
-rw-r--r-- | e2fsck/problem.c | 10 | ||||
-rw-r--r-- | e2fsck/problem.h | 6 | ||||
-rw-r--r-- | e2fsck/super.c | 19 | ||||
-rw-r--r-- | e2fsck/unix.c | 31 | ||||
-rw-r--r-- | tests/f_baddir/expect.1 | 3 | ||||
-rw-r--r-- | tests/f_dup/expect.1 | 2 | ||||
-rw-r--r-- | tests/f_dup2/expect.1 | 2 | ||||
-rw-r--r-- | tests/f_end-bitmap/expect.1 | 3 | ||||
-rw-r--r-- | tests/f_lpf/expect.1 | 2 | ||||
-rw-r--r-- | tests/f_summary_counts/expect.1 | 6 | ||||
-rw-r--r-- | tests/f_unused_itable/expect.1 | 3 |
12 files changed, 58 insertions, 33 deletions
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 486a71b0..b4a1a88d 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -212,10 +212,12 @@ struct e2fsck_struct { char *io_options; int flags; /* E2fsck internal flags */ int options; + int blocksize; /* blocksize */ blk64_t use_superblock; /* sb requested by user */ blk64_t superblock; /* sb used to open fs */ - int blocksize; /* blocksize */ blk64_t num_blocks; /* Total number of blocks */ + blk64_t free_blocks; + ino_t free_inodes; int mount_flags; blkid_cache blkid; /* blkid cache */ diff --git a/e2fsck/problem.c b/e2fsck/problem.c index fb900071..c5bebf85 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -402,6 +402,16 @@ static struct e2fsck_problem problem_table[] = { N_("One or more @b @g descriptor checksums are invalid. "), PROMPT_FIX, PR_PREEN_OK }, + /* Free inodes count wrong */ + { PR_0_FREE_INODE_COUNT, + N_("Setting free @is count to %j (was %i)\n"), + PROMPT_NONE, PR_PREEN_NOMSG }, + + /* Free blocks count wrong */ + { PR_0_FREE_BLOCK_COUNT, + N_("Setting free @bs count to %c (was %b)\n"), + PROMPT_NONE, PR_PREEN_NOMSG }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 38b3c784..8379e0cf 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -227,6 +227,12 @@ struct problem_context { /* Block group checksum (latch question) */ #define PR_0_GDT_CSUM_LATCH 0x00003E +/* Free inodes count wrong */ +#define PR_0_FREE_INODE_COUNT 0x00003F + +/* Free blocks count wrong */ +#define PR_0_FREE_BLOCK_COUNT 0x000040 + /* * Pass 1 errors diff --git a/e2fsck/super.c b/e2fsck/super.c index 5d6aa7a3..3f9e3331 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -690,23 +690,8 @@ void check_super_block(e2fsck_t ctx) return; } - /* - * Update the global counts from the block group counts. This - * is needed for an experimental patch which eliminates - * locking the entire filesystem when allocating blocks or - * inodes; if the filesystem is not unmounted cleanly, the - * global counts may not be accurate. - */ - if ((free_blocks != ext2fs_free_blocks_count(sb)) || - (free_inodes != sb->s_free_inodes_count)) { - if (ctx->options & E2F_OPT_READONLY) - ext2fs_unmark_valid(fs); - else { - ext2fs_free_blocks_count_set(sb, free_blocks); - sb->s_free_inodes_count = free_inodes; - ext2fs_mark_super_dirty(fs); - } - } + ctx->free_blocks = free_blocks; + ctx->free_inodes = free_inodes; if ((ext2fs_free_blocks_count(sb) > ext2fs_blocks_count(sb)) || (sb->s_free_inodes_count > sb->s_inodes_count)) diff --git a/e2fsck/unix.c b/e2fsck/unix.c index a43f0c9b..7e95ca88 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -287,6 +287,7 @@ static int is_on_batt(void) static void check_if_skip(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; + struct problem_context pctx; const char *reason = NULL; unsigned int reason_arg = 0; long next_check; @@ -349,6 +350,36 @@ static void check_if_skip(e2fsck_t ctx) fputs(_(", check forced.\n"), stdout); return; } + + /* + * Update the global counts from the block group counts. This + * is needed since modern kernels don't update the global + * counts so as to avoid locking the entire file system. So + * if the filesystem is not unmounted cleanly, the global + * counts may not be accurate. Update them here if we can, + * for the benefit of users who might examine the file system + * using dumpe2fs. (This is for cosmetic reasons only.) + */ + clear_problem_context(&pctx); + pctx.ino = fs->super->s_free_inodes_count; + pctx.ino2 = ctx->free_inodes; + if ((pctx.ino != pctx.ino2) && + !(ctx->options & E2F_OPT_READONLY) && + fix_problem(ctx, PR_0_FREE_INODE_COUNT, &pctx)) { + fs->super->s_free_inodes_count = ctx->free_inodes; + ext2fs_mark_super_dirty(fs); + } + clear_problem_context(&pctx); + pctx.blk = ext2fs_free_blocks_count(fs->super); + pctx.blk2 = ctx->free_blocks; + if ((pctx.blk != pctx.blk2) && + !(ctx->options & E2F_OPT_READONLY) && + fix_problem(ctx, PR_0_FREE_BLOCK_COUNT, &pctx)) { + ext2fs_free_blocks_count_set(fs->super, ctx->free_blocks); + ext2fs_mark_super_dirty(fs); + } + + /* Print the summary message when we're skipping a full check */ printf(_("%s: clean, %u/%u files, %llu/%llu blocks"), ctx->device_name, fs->super->s_inodes_count - fs->super->s_free_inodes_count, fs->super->s_inodes_count, diff --git a/tests/f_baddir/expect.1 b/tests/f_baddir/expect.1 index 39735061..cf46a60c 100644 --- a/tests/f_baddir/expect.1 +++ b/tests/f_baddir/expect.1 @@ -39,6 +39,9 @@ Pass 5: Checking group summary information Block bitmap differences: -22 Fix? yes +Free blocks count wrong (74, counted=75). +Fix? yes + Inode bitmap differences: -13 Fix? yes diff --git a/tests/f_dup/expect.1 b/tests/f_dup/expect.1 index ce369062..e7128f34 100644 --- a/tests/f_dup/expect.1 +++ b/tests/f_dup/expect.1 @@ -27,7 +27,7 @@ Pass 5: Checking group summary information Free blocks count wrong for group #0 (44, counted=60). Fix? yes -Free blocks count wrong (44, counted=60). +Free blocks count wrong (62, counted=60). Fix? yes Padding at end of block bitmap is not set. Fix? yes diff --git a/tests/f_dup2/expect.1 b/tests/f_dup2/expect.1 index 79a5f1a0..0476005d 100644 --- a/tests/f_dup2/expect.1 +++ b/tests/f_dup2/expect.1 @@ -34,7 +34,7 @@ Pass 5: Checking group summary information Free blocks count wrong for group #0 (8, counted=22). Fix? yes -Free blocks count wrong (8, counted=22). +Free blocks count wrong (26, counted=22). Fix? yes Padding at end of block bitmap is not set. Fix? yes diff --git a/tests/f_end-bitmap/expect.1 b/tests/f_end-bitmap/expect.1 index 3348a2b3..87e2fd64 100644 --- a/tests/f_end-bitmap/expect.1 +++ b/tests/f_end-bitmap/expect.1 @@ -8,9 +8,6 @@ Pass 5: Checking group summary information Free blocks count wrong for group #0 (44, counted=63). Fix? yes -Free blocks count wrong (44, counted=63). -Fix? yes - Padding at end of block bitmap is not set. Fix? yes diff --git a/tests/f_lpf/expect.1 b/tests/f_lpf/expect.1 index 6c0a746c..4f2853c5 100644 --- a/tests/f_lpf/expect.1 +++ b/tests/f_lpf/expect.1 @@ -30,7 +30,7 @@ Fix? yes Free blocks count wrong for group #0 (24, counted=33). Fix? yes -Free blocks count wrong (24, counted=33). +Free blocks count wrong (38, counted=33). Fix? yes Inode bitmap differences: +13 diff --git a/tests/f_summary_counts/expect.1 b/tests/f_summary_counts/expect.1 index 5c528bb4..ddb14bd6 100644 --- a/tests/f_summary_counts/expect.1 +++ b/tests/f_summary_counts/expect.1 @@ -7,18 +7,12 @@ Pass 5: Checking group summary information Free blocks count wrong for group #0 (200, counted=80). Fix? yes -Free blocks count wrong (200, counted=80). -Fix? yes - Free inodes count wrong for group #0 (250, counted=5). Fix? yes Directories count wrong for group #0 (150, counted=2). Fix? yes -Free inodes count wrong (250, counted=5). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 11/16 files (0.0% non-contiguous), 20/100 blocks diff --git a/tests/f_unused_itable/expect.1 b/tests/f_unused_itable/expect.1 index d77e82a5..08a97001 100644 --- a/tests/f_unused_itable/expect.1 +++ b/tests/f_unused_itable/expect.1 @@ -22,9 +22,6 @@ Fix? yes Free inodes count wrong for group #1 (64, counted=58). Fix? yes -Free inodes count wrong (117, counted=109). -Fix? yes - test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** test_filesys: 19/128 files (0.0% non-contiguous), 165/1000 blocks |