bug in block_read

Paul Mackerras (paulus@cs.anu.edu.au)
Wed, 30 Sep 1998 15:49:03 +1000


I have found a bug in block_read (fs/block_dev.c), where we can get
into the main do loop starting at line 223 with blocks == 0. This can
happen if the size of the partition being read is not a multiple of
the disk's blocksize, and you try to read near the end of the
partition (in the last partition_size % blocksize bytes). Usually the
blocksize for a scsi disk is 1kB, or 4kB for a swap partition, and the
partition size is in units of 512 bytes, so this situation can arise.

What happens then is that the while loop starting at line 226 (which
calls getblk) runs 0 times, but the do loop starting at line 250
(which calls brelse) runs at least once. Hence brelse gets called
with whatever values happen to be in buflist[]. In my case this
happened to be a buffer_head pointer, so I got a couple of 'VFS:
trying to free free buffer' messages, followed by a panic (from
memory, it was 'VFS: LRU block list corrupted').

I have fixed (or at least worked around) the problem with this patch:

--- linux/fs/block_dev.c Thu Dec 4 09:43:04 1997
+++ pmac/fs/block_dev.c Mon Sep 28 22:46:52 1998
@@ -204,8 +204,11 @@
blocks = rblocks;

}
- if (block + blocks > size)
+ if (block + blocks > size) {
blocks = size - block;
+ if (blocks == 0)
+ return 0;
+ }

/* We do this in a two stage process. We first try to request
as many blocks as we can, then we wait for the first one to

At a quick look, block_write seems to be OK.

Paul.

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