diff -urN 2.2.13/fs/ext2/balloc.c ext2/fs/ext2/balloc.c --- 2.2.13/fs/ext2/balloc.c Sun Oct 31 23:31:31 1999 +++ ext2/fs/ext2/balloc.c Sat Nov 6 02:32:48 1999 @@ -603,6 +603,8 @@ unlock_super (sb); return 0; } + if (!buffer_uptodate(bh)) + wait_on_buffer(bh); memset(bh->b_data, 0, sb->s_blocksize); mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1); diff -urN 2.2.13/fs/ext2/fsync.c ext2/fs/ext2/fsync.c --- 2.2.13/fs/ext2/fsync.c Sun Oct 31 23:31:31 1999 +++ ext2/fs/ext2/fsync.c Sat Nov 6 04:25:40 1999 @@ -45,10 +45,21 @@ if (!bh) return 0; if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse (bh); - return -1; + /* There can be a parallell read(2) that started read-I/O + on the buffer so we can't assume that there's been + an I/O error without first waiting I/O completation. */ + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + { + brelse (bh); + return -1; + } } if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) { + if (wait) + /* when we return from fsync all the blocks + must be _just_ stored on disk */ + wait_on_buffer(bh); brelse (bh); return 0; } @@ -68,10 +79,21 @@ if (!bh) return 0; if (wait && buffer_req(bh) && !buffer_uptodate(bh)) { - brelse (bh); - return -1; + /* There can be a parallell read(2) that started read-I/O + on the buffer so we can't assume that there's been + an I/O error without first waiting I/O completation. */ + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) + { + brelse (bh); + return -1; + } } if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) { + if (wait) + /* when we return from fsync all the blocks + must be _just_ stored on disk */ + wait_on_buffer(bh); brelse (bh); return 0; } diff -urN 2.2.13/fs/ext2/inode.c ext2/fs/ext2/inode.c --- 2.2.13/fs/ext2/inode.c Sun Oct 31 23:31:31 1999 +++ ext2/fs/ext2/inode.c Sat Nov 6 21:48:10 1999 @@ -121,6 +121,8 @@ "cannot get block %lu", result); return 0; } + if (!buffer_uptodate(bh)) + wait_on_buffer(bh); memset(bh->b_data, 0, inode->i_sb->s_blocksize); mark_buffer_uptodate(bh, 1); mark_buffer_dirty(bh, 1);