On Wed, Nov 17, 2010 at 12:19:14AM -0800, J.P. Larocque wrote: > Hi Ted and Micah, > > I ran into the problem in e2fsck that prints: > > WARNING: PROGRAMMING BUG IN E2FSCK! > OR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM. > inode_link_info[X] is Y, inode.i_links_count is Z. They should be the same! > > I've sent a full transcript, e2image file with which the problem can > be reproduced, and background information to 555...@bugs.debian.org, > which you can access at > <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=555456>. (I'm > sending this message separately to spare you both from the 2.1MiB > attachment.) > > Hope it helps. Thanks!
Thanks for sending me the test case. I've been able to find a fix for this which will be going into e2fsprogs 1.41.13. - Ted commit 992016c5afde0f77a9ff10c4fc5be02f83eb055c Author: Theodore Ts'o <ty...@mit.edu> Date: Fri Nov 26 19:09:43 2010 -0500 e2fsck: Fix inode nlink accounting that could cause PROGRAMMING BUG errors This fixes two possible causes for the error message: WARNING: PROGRAMMING BUG IN E2FSCK! OR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM. inode_link_info[X] is Y, inode.i_links_count is Z. They should be the same! One cause which can trigger this message is when an inode has an illegal link count > 65500 --- for example, 65535. This was the case in the Debian Bug report #555456. Another cause which could trigger this message is if an ext4 directory previously had more than 65000 subdirectories (thus causing i_link_count to be set to 1), but then some of the subdirectories were deleted, such that i_link_count should now be the actual number of subdirectories. Addresses-Debian-Bug: #555456 Signed-off-by: "Theodore Ts'o" <ty...@mit.edu> diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index d9706ce..515cb84 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -121,6 +121,8 @@ void e2fsck_pass4(e2fsck_t ctx) /* Protect loop from wrap-around if s_inodes_count maxed */ for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) { + int isdir = ext2fs_test_inode_bitmap(ctx->inode_dir_map, i); + if (ctx->flags & E2F_FLAG_SIGNAL_MASK) goto errout; if ((i % fs->super->s_inodes_per_group) == 0) { @@ -153,14 +155,14 @@ void e2fsck_pass4(e2fsck_t ctx) ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); } - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i) && - (link_counted > EXT2_LINK_MAX)) + if (isdir && (link_counted > EXT2_LINK_MAX)) link_counted = 1; if (link_counted != link_count) { e2fsck_read_inode(ctx, i, inode, "pass4"); pctx.ino = i; pctx.inode = inode; - if (link_count != inode->i_links_count) { + if ((link_count != inode->i_links_count) && !isdir && + (inode->i_links_count <= EXT2_LINK_MAX)) { pctx.num = link_count; fix_problem(ctx, PR_4_INCONSISTENT_COUNT, &pctx); @@ -168,10 +170,10 @@ void e2fsck_pass4(e2fsck_t ctx) pctx.num = link_counted; /* i_link_count was previously exceeded, but no longer * is, fix this but don't consider it an error */ - if ((LINUX_S_ISDIR(inode->i_mode) && link_counted > 1 && + if ((isdir && link_counted > 1 && (inode->i_flags & EXT2_INDEX_FL) && link_count == 1 && !(ctx->options & E2F_OPT_NO)) || - (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx))) { + fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) { inode->i_links_count = link_counted; e2fsck_write_inode(ctx, i, inode, "pass4"); } -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org