tags 291571 +pending
thanks

On Fri, Jan 21, 2005 at 05:01:57PM +0100, Wichert Akkerman wrote:
> Package: e2fsprogs
> Version: 1.35-6
> Severity: normal
> 
> I hit an interesting filesystem problem today, see
> http://lkml.org/lkml/2005/1/21/118 . I ran e2fsck on the filesystem
> with this unexpected result:
> 
> e2fsck 1.35 (28-Feb-2004)
> /dev/md4: clean, 16/132480 files, -15514/264960 blocks

I'm not sure how the corruption happened in the first place, but
you're right that e2fsck should have noticed the problem and forced a
check.  Thanks for pointing this out; the following patch will be in
the next version of e2fsprogs.

                                                - Ted

# This is a BitKeeper generated diff -Nru style patch.
#
# tests/f_summary_counts/script
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +4 -0
# 
# tests/f_summary_counts/name
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +1 -0
# 
# tests/f_summary_counts/image.gz
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +11 -0
# 
# tests/f_summary_counts/expect.2
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +7 -0
# 
# tests/f_summary_counts/expect.1
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +25 -0
# 
# ChangeSet
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] 
#   E2fsck will now check the individual block group inode and block free 
counts,
#   as well as the filesystem-wide inode and block free counts.  If any of the
#   free counts is too large, force a full filesystem check.  (Addresses 
#   Debian Bug #291571)
# 
# tests/f_summary_counts/script
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +0 -0
#   BitKeeper file 
/usr/projects/e2fsprogs/e2fsprogs/tests/f_summary_counts/script
# 
# tests/f_summary_counts/name
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +0 -0
#   BitKeeper file /usr/projects/e2fsprogs/e2fsprogs/tests/f_summary_counts/name
# 
# tests/f_summary_counts/image.gz
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +0 -0
#   BitKeeper file 
/usr/projects/e2fsprogs/e2fsprogs/tests/f_summary_counts/image.gz
# 
# tests/f_summary_counts/expect.2
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +0 -0
#   BitKeeper file 
/usr/projects/e2fsprogs/e2fsprogs/tests/f_summary_counts/expect.2
# 
# tests/f_summary_counts/expect.1
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +0 -0
#   BitKeeper file 
/usr/projects/e2fsprogs/e2fsprogs/tests/f_summary_counts/expect.1
# 
# tests/ChangeLog
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +4 -0
#   Update log
# 
# e2fsck/unix.c
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +3 -1
#   unix.c (main, check_if_skip): Set the valid flag earlier, and if
#       it is cleared by the superblock tests, then assume that
#       the filesystem contains errors and must be checked.
#   
# 
# e2fsck/super.c
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +54 -38
#   super.c (check_super_block): Check the individual block group
#       block and inode free counts, as well as the filesystem
#       block and free counts.  If any of the block/inode
#       free counts is too large, force a full filesystem check.
#       (Addresses Debian Bug: #291571)
# 
# e2fsck/ChangeLog
#   2005/01/25 03:09:24-05:00 [EMAIL PROTECTED] +12 -0
#   Update log
# 
diff -Nru a/e2fsck/ChangeLog b/e2fsck/ChangeLog
--- a/e2fsck/ChangeLog  2005-01-25 03:09:40 -05:00
+++ b/e2fsck/ChangeLog  2005-01-25 03:09:40 -05:00
@@ -1,3 +1,15 @@
+2005-01-25  Theodore Ts'o  <[EMAIL PROTECTED]>
+
+       * unix.c (main, check_if_skip): Set the valid flag earlier, and if
+               it is cleared by the superblock tests, then assume that
+               the filesystem contains errors and must be checked.
+
+       * super.c (check_super_block): Check the individual block group
+               inode and block free counts, as well as the filesystem
+               inode and block free counts.  If any of the block/inode
+               free counts is too large, force a full filesystem check.
+               (Addresses Debian Bug: #291571)
+
 2005-01-21  Theodore Ts'o  <[EMAIL PROTECTED]>
 
        * super.c (check_resize_inode): If resize feature is set, but
diff -Nru a/e2fsck/super.c b/e2fsck/super.c
--- a/e2fsck/super.c    2005-01-25 03:09:40 -05:00
+++ b/e2fsck/super.c    2005-01-25 03:09:40 -05:00
@@ -431,6 +431,7 @@
        ext2_filsys fs = ctx->fs;
        blk_t   first_block, last_block;
        struct ext2_super_block *sb = fs->super;
+       struct ext2_group_desc *gd;
        blk_t   blocks_per_group = fs->super->s_blocks_per_group;
        blk_t   bpg_max;
        int     inodes_per_block;
@@ -542,56 +543,86 @@
        /*
         * Verify the group descriptors....
         */
-       first_block =  fs->super->s_first_data_block;
+       first_block =  sb->s_first_data_block;
        last_block = first_block + blocks_per_group;
 
-       for (i = 0; i < fs->group_desc_count; i++) {
+       for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
                pctx.group = i;
                
                if (i == fs->group_desc_count - 1)
-                       last_block = fs->super->s_blocks_count;
-               if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
-                   (fs->group_desc[i].bg_block_bitmap >= last_block)) {
-                       pctx.blk = fs->group_desc[i].bg_block_bitmap;
+                       last_block = sb->s_blocks_count;
+               if ((gd->bg_block_bitmap < first_block) ||
+                   (gd->bg_block_bitmap >= last_block)) {
+                       pctx.blk = gd->bg_block_bitmap;
                        if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
-                               fs->group_desc[i].bg_block_bitmap = 0;
+                               gd->bg_block_bitmap = 0;
                }
-               if (fs->group_desc[i].bg_block_bitmap == 0) {
+               if (gd->bg_block_bitmap == 0) {
                        ctx->invalid_block_bitmap_flag[i]++;
                        ctx->invalid_bitmaps++;
                }
-               if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
-                   (fs->group_desc[i].bg_inode_bitmap >= last_block)) {
-                       pctx.blk = fs->group_desc[i].bg_inode_bitmap;
+               if ((gd->bg_inode_bitmap < first_block) ||
+                   (gd->bg_inode_bitmap >= last_block)) {
+                       pctx.blk = gd->bg_inode_bitmap;
                        if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
-                               fs->group_desc[i].bg_inode_bitmap = 0;
+                               gd->bg_inode_bitmap = 0;
                }
-               if (fs->group_desc[i].bg_inode_bitmap == 0) {
+               if (gd->bg_inode_bitmap == 0) {
                        ctx->invalid_inode_bitmap_flag[i]++;
                        ctx->invalid_bitmaps++;
                }
-               if ((fs->group_desc[i].bg_inode_table < first_block) ||
-                   ((fs->group_desc[i].bg_inode_table +
+               if ((gd->bg_inode_table < first_block) ||
+                   ((gd->bg_inode_table +
                      fs->inode_blocks_per_group - 1) >= last_block)) {
-                       pctx.blk = fs->group_desc[i].bg_inode_table;
+                       pctx.blk = gd->bg_inode_table;
                        if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
-                               fs->group_desc[i].bg_inode_table = 0;
+                               gd->bg_inode_table = 0;
                }
-               if (fs->group_desc[i].bg_inode_table == 0) {
+               if (gd->bg_inode_table == 0) {
                        ctx->invalid_inode_table_flag[i]++;
                        ctx->invalid_bitmaps++;
                }
-               free_blocks += fs->group_desc[i].bg_free_blocks_count;
-               free_inodes += fs->group_desc[i].bg_free_inodes_count;
-               first_block += fs->super->s_blocks_per_group;
-               last_block += fs->super->s_blocks_per_group;
+               free_blocks += gd->bg_free_blocks_count;
+               free_inodes += gd->bg_free_inodes_count;
+               first_block += sb->s_blocks_per_group;
+               last_block += sb->s_blocks_per_group;
+
+               if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
+                   (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
+                   (gd->bg_used_dirs_count > sb->s_inodes_per_group))
+                       ext2fs_unmark_valid(fs);
+
        }
+
+       /*
+        * 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 != sb->s_free_blocks_count) ||
+           (free_inodes != sb->s_free_inodes_count)) {
+               if (ctx->options & E2F_OPT_READONLY)
+                       ext2fs_unmark_valid(fs);
+               else {
+                       sb->s_free_blocks_count = free_blocks;
+                       sb->s_free_inodes_count = free_inodes;
+                       ext2fs_mark_super_dirty(fs);
+               }
+       }
+       
+       if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
+           (sb->s_free_inodes_count > sb->s_inodes_count))
+               ext2fs_unmark_valid(fs);
+
+
        /*
         * If we have invalid bitmaps, set the error state of the
         * filesystem.
         */
        if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
-               fs->super->s_state &= ~EXT2_VALID_FS;
+               sb->s_state &= ~EXT2_VALID_FS;
                ext2fs_mark_super_dirty(fs);
        }
 
@@ -610,21 +641,6 @@
        }
 #endif
 
-       /*
-        * 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 (!(ctx->options & E2F_OPT_READONLY) &&
-           ((free_blocks != fs->super->s_free_blocks_count) ||
-            (free_inodes != fs->super->s_free_inodes_count))) {
-               fs->super->s_free_blocks_count = free_blocks;
-               fs->super->s_free_inodes_count = free_inodes;
-               ext2fs_mark_super_dirty(fs);
-       }
-       
        /*
         * For the Hurd, check to see if the filetype option is set,
         * since it doesn't support it.
diff -Nru a/e2fsck/unix.c b/e2fsck/unix.c
--- a/e2fsck/unix.c     2005-01-25 03:09:40 -05:00
+++ b/e2fsck/unix.c     2005-01-25 03:09:40 -05:00
@@ -262,7 +262,8 @@
            cflag || swapfs)
                return;
        
-       if (fs->super->s_state & EXT2_ERROR_FS)
+       if ((fs->super->s_state & EXT2_ERROR_FS) ||
+           !ext2fs_test_valid(fs))
                reason = _(" contains a file system with errors");
        else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
                reason = _(" was not cleanly unmounted");
@@ -1060,6 +1061,7 @@
 
        if (ctx->superblock)
                set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
+       ext2fs_mark_valid(fs);
        check_super_block(ctx);
        if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
                fatal_error(ctx, 0);
diff -Nru a/tests/ChangeLog b/tests/ChangeLog
--- a/tests/ChangeLog   2005-01-25 03:09:40 -05:00
+++ b/tests/ChangeLog   2005-01-25 03:09:40 -05:00
@@ -1,3 +1,7 @@
+2005-01-25  Theodore Ts'o  <[EMAIL PROTECTED]>
+
+       * f_summary_counts: New test case
+
 2005-01-21  Theodore Ts'o  <[EMAIL PROTECTED]>
 
        * r_resize_inode: Skip this test if resize2fs is not compiled (due
diff -Nru a/tests/f_summary_counts/expect.1 b/tests/f_summary_counts/expect.1
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/tests/f_summary_counts/expect.1   2005-01-25 03:09:40 -05:00
@@ -0,0 +1,25 @@
+test_filesys contains a file system with errors, check forced.
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+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
+Exit status is 1
diff -Nru a/tests/f_summary_counts/expect.2 b/tests/f_summary_counts/expect.2
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/tests/f_summary_counts/expect.2   2005-01-25 03:09:40 -05:00
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/16 files (0.0% non-contiguous), 20/100 blocks
+Exit status is 0
Binary files a/tests/f_summary_counts/image.gz and 
b/tests/f_summary_counts/image.gz differ
diff -Nru a/tests/f_summary_counts/name b/tests/f_summary_counts/name
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/tests/f_summary_counts/name       2005-01-25 03:09:40 -05:00
@@ -0,0 +1 @@
+incorrect inode/block free counts
diff -Nru a/tests/f_summary_counts/script b/tests/f_summary_counts/script
--- /dev/null   Wed Dec 31 16:00:00 196900
+++ b/tests/f_summary_counts/script     2005-01-25 03:09:40 -05:00
@@ -0,0 +1,4 @@
+FSCK_OPT=-y
+SECOND_FSCK_OPT=-yf
+
+. $cmd_dir/run_e2fsck


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to