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]