[patch] 2.2.14: block_write badly broken

From: Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz)
Date: Sat Jan 08 2000 - 20:33:48 EST


Hi.

block_write does bad things in 2.2.14.

If read_ahead is too small and blocksize too large (in my case: reada_head
8, blocksize 4096) it tries to read 0 blocks, returns error because buffer
is not uptodate and doesn't release buffer.

You can't reliably write to device:
4151 write(1, "\353<\220MSDOS5.0\0\2\10\1\0\2\0"..., 32768) = 32768
4151 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
4151 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
4151 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
4151 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 23040) = 20480
4151 write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2560) = -1 EIO (I/O error)

This patch fixes it.

--- linux/fs/block_dev.c_ Sun Jan 9 01:46:18 2000
+++ linux/fs/block_dev.c Sun Jan 9 02:18:40 2000
@@ -92,6 +92,7 @@
                       blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
                       if (block + blocks > size) blocks = size - block;
                       if (blocks > NBUF) blocks=NBUF;
+ if (!blocks) blocks = 1;
                       for(i=1; i<blocks; i++)
                       {
                         bhlist[i] = getblk (dev, block+i, blocksize);
@@ -105,8 +106,10 @@
                     ll_rw_block(READ, blocks, bhlist);
                     for(i=1; i<blocks; i++) brelse(bhlist[i]);
                     wait_on_buffer(bh);
- if (!buffer_uptodate(bh))
+ if (!buffer_uptodate(bh)) {
+ brelse(bh);
                           return written ? written : -EIO;
+ }
                   };
                 };
 #endif

Mikulas

-
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/



This archive was generated by hypermail 2b29 : Sat Jan 15 2000 - 21:00:13 EST