[PATCH] (was Re: Kernel panic: EXT2-fs panic on 2.5.4-pre3)

From: Andreas Dilger (adilger@turbolabs.com)
Date: Fri Feb 08 2002 - 23:02:36 EST


On Feb 08, 2002 15:43 -0800, Greg KH wrote:
> I got this when unmounting my drive after running e2fsck...
>
> Kernel panic: EXT2-fs panic (device ide0(3,5)): load_block_bitmap:
> block_group >= groups_count - block_group = 131071, groups_count = 33

Well, clearly it has the right to complain, because it is getting a crappy
data as input. The ext2_panic() function should _probably_ be changed to
a BUG(); instead of panic() because then we can at least get a backtrace.

As to where that bad data came from...

I seem to recall trying to track down this exact same problem about a
year ago. A quick search on Google shows that there are a lot of oopses
at the same place with block_group = 131071.

The last time I looked at this bug, I thought it was due to an
uninitialized variable i_prealloc_count, but that wasn't the case.
Really, the only path where this can happen is if ext2_free_blocks()
is called with a bad block or count parameter, in such a way that
block + count overflows a 32-bit int and the check at the beginning of
ext2_free_blocks() does not catch it.

It appears we are trying to free block -1 for some reason:

group 131071 = block -1UL / 32768 blocks/group on a 4kB block fs

If you try to free block = -1 and count >= 1, it will pass the checks
in ext2_free_blocks(). The below patch fixes this, but not necessarily
the original source of the bad block number (I will continue looking
for that). It is still worthwhile to ensure that we are not using a
bogus block+count. It would appear that this is not just random
corrupt data from disk, because of the common occurrence of group 131071,
but I can't see where the bad block is coming from right now.

Patch against 2.4.17-pre8, but it should be the same for all kernels in
recent history.

Cheers, Andreas
====================== ext2-2.4.17-panic.diff =============================
--- linux-2.4.17-pre8.orig/fs/ext2/balloc.c Thu Oct 25 02:02:41 2001
+++ linux-2.4.17-pre8/fs/ext2/balloc.c Fri Feb 8 18:56:22 2002
@@ -269,8 +267,9 @@
         }
         lock_super (sb);
         es = sb->u.ext2_sb.s_es;
- if (block < le32_to_cpu(es->s_first_data_block) ||
- (block + count) > le32_to_cpu(es->s_blocks_count)) {
+ if (block < le32_to_cpu(es->s_first_data_block) ||
+ block + count < block ||
+ block + count >= le32_to_cpu(es->s_blocks_count)) {
                 ext2_error (sb, "ext2_free_blocks",
                             "Freeing blocks not in datazone - "
                             "block = %lu, count = %lu", block, count);
--- linux-2.4.17-pre8.orig/fs/ext3/balloc.c Thu Oct 25 02:02:41 2001
+++ linux-2.4.17-pre8/fs/ext3/balloc.c Fri Feb 8 18:56:22 2002
@@ -269,8 +267,9 @@
         }
         lock_super (sb);
         es = sb->u.ext3_sb.s_es;
- if (block < le32_to_cpu(es->s_first_data_block) ||
- (block + count) > le32_to_cpu(es->s_blocks_count)) {
+ if (block < le32_to_cpu(es->s_first_data_block) ||
+ block + count < block ||
+ block + count >= le32_to_cpu(es->s_blocks_count)) {
                 ext3_error (sb, "ext3_free_blocks",
                             "Freeing blocks not in datazone - "
                             "block = %lu, count = %lu", block, count);

--
Andreas Dilger
http://sourceforge.net/projects/ext2resize/
http://www-mddsp.enel.ucalgary.ca/People/adilger/

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Feb 15 2002 - 21:00:25 EST