Whamcloud - gitweb
e2fsck: fix mysterious "FILE SYSTEM WAS MODIFIED" with no changes
authorTheodore Ts'o <tytso@mit.edu>
Thu, 16 Jun 2011 05:13:42 +0000 (01:13 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 16 Jun 2011 05:22:02 +0000 (01:22 -0400)
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>
12 files changed:
e2fsck/e2fsck.h
e2fsck/problem.c
e2fsck/problem.h
e2fsck/super.c
e2fsck/unix.c
tests/f_baddir/expect.1
tests/f_dup/expect.1
tests/f_dup2/expect.1
tests/f_end-bitmap/expect.1
tests/f_lpf/expect.1
tests/f_summary_counts/expect.1
tests/f_unused_itable/expect.1

index 486a71b..b4a1a88 100644 (file)
@@ -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 */
 
index fb90007..c5bebf8 100644 (file)
@@ -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 */
index 38b3c78..8379e0c 100644 (file)
@@ -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
index 5d6aa7a..3f9e333 100644 (file)
@@ -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))
index a43f0c9..7e95ca8 100644 (file)
@@ -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,
index 3973506..cf46a60 100644 (file)
@@ -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
 
index ce36906..e7128f3 100644 (file)
@@ -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
index 79a5f1a..0476005 100644 (file)
@@ -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
index 3348a2b..87e2fd6 100644 (file)
@@ -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
 
 
index 6c0a746..4f2853c 100644 (file)
@@ -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
index 5c528bb..ddb14bd 100644 (file)
@@ -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
index d77e82a..08a9700 100644 (file)
@@ -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