2.3.36 blockdevice fs corruption fixes

From: Andrea Arcangeli (andrea@suse.de)
Date: Sat Jan 08 2000 - 11:01:54 EST


This patch fixes fs corruption in the blockdevice layer in 2.3.36.
Probably it's not interesting for 2.4.0 because we'll move the blockdevice
stuff to page cache but as I had not to port it to 2.3.x I just send to
you for getting the race fixed in the meantime...

--- 2.2.13/fs/block_dev.c.~1~ Sun Oct 31 23:31:33 1999
+++ 2.2.13/fs/block_dev.c Wed Dec 15 17:12:07 1999
@@ -67,39 +67,50 @@
                         if (chars != blocksize)
                                 fn = bread;
                         bh = fn(dev, block, blocksize);
+ if (!bh)
+ return written ? written : -EIO;
+ if (!buffer_uptodate(bh))
+ wait_on_buffer(bh);
                 }
 #else
                 bh = getblk(dev, block, blocksize);
+ if (!bh)
+ return written ? written : -EIO;
 
- if (chars != blocksize && !buffer_uptodate(bh)) {
- if(!filp->f_reada ||
- !read_ahead[MAJOR(dev)]) {
- /* We do this to force the read of a single buffer */
- brelse(bh);
- bh = bread(dev,block,blocksize);
- } else {
- /* Read-ahead before write */
- blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
- if (block + blocks > size) blocks = size - block;
- if (blocks > NBUF) blocks=NBUF;
+ if (!buffer_uptodate(bh))
+ {
+ if (chars == blocksize)
+ wait_on_buffer(bh);
+ else
+ {
                     bhlist[0] = bh;
- for(i=1; i<blocks; i++){
- bhlist[i] = getblk (dev, block+i, blocksize);
- if(!bhlist[i]){
- while(i >= 0) brelse(bhlist[i--]);
- return written ? written : -EIO;
- };
- };
+ if (!filp->f_reada || !read_ahead[MAJOR(dev)]) {
+ /* We do this to force the read of a single buffer */
+ blocks = 1;
+ } else {
+ /* Read-ahead before write */
+ blocks = read_ahead[MAJOR(dev)] / (blocksize >> 9) / 2;
+ if (block + blocks > size) blocks = size - block;
+ if (blocks > NBUF) blocks=NBUF;
+ for(i=1; i<blocks; i++)
+ {
+ bhlist[i] = getblk (dev, block+i, blocksize);
+ if (!bhlist[i])
+ {
+ while(i >= 0) brelse(bhlist[i--]);
+ return written ? written : -EIO;
+ }
+ }
+ }
                     ll_rw_block(READ, blocks, bhlist);
                     for(i=1; i<blocks; i++) brelse(bhlist[i]);
                     wait_on_buffer(bh);
-
+ if (!buffer_uptodate(bh))
+ return written ? written : -EIO;
                   };
                 };
 #endif
                 block++;
- if (!bh)
- return written ? written : -EIO;
                 p = offset + bh->b_data;
                 offset = 0;
                 *ppos += chars;

Andrea

-
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:12 EST