]> git.neil.brown.name Git - history.git/commit
[PATCH] Fix synchronous writers to wait properly for the result
authorAndrew Morton <akpm@digeo.com>
Mon, 10 Feb 2003 08:29:41 +0000 (00:29 -0800)
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Mon, 10 Feb 2003 08:29:41 +0000 (00:29 -0800)
commit8d49bf3f9d4f6d61f0f759f75e79caaee6dcc6e4
treea664f0a82eae712c1051157d38c3ed15714a8a19
parent3d9d68595649eacc0fee8d6cae3081ee78cd9c4a
[PATCH] Fix synchronous writers to wait properly for the result

Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz> points out a bug in
ll_rw_block() usage.

Typical usage is:

mark_buffer_dirty(bh);
ll_rw_block(WRITE, 1, &bh);
wait_on_buffer(bh);

the problem is that if the buffer was locked on entry to this code sequence
(due to in-progress I/O), ll_rw_block() will not wait, and start new I/O.  So
this code will wait on the _old_ I/O, and will then continue execution,
leaving the buffer dirty.

It turns out that all callers were only writing one buffer, and they were all
waiting on that writeout.  So I added a new sync_dirty_buffer() function:

void sync_dirty_buffer(struct buffer_head *bh)
{
lock_buffer(bh);
if (test_clear_buffer_dirty(bh)) {
get_bh(bh);
bh->b_end_io = end_buffer_io_sync;
submit_bh(WRITE, bh);
} else {
unlock_buffer(bh);
}
}

which allowed a fair amount of code to be removed, while adding the desired
data-integrity guarantees.

UFS has its own wrappers around ll_rw_block() which got in the way, so this
operation was open-coded in that case.
30 files changed:
fs/buffer.c
fs/ext2/balloc.c
fs/ext2/ialloc.c
fs/ext2/inode.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/ext3/super.c
fs/jbd/commit.c
fs/jbd/journal.c
fs/jbd/transaction.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_mount.c
fs/jfs/namei.c
fs/jfs/resize.c
fs/minix/inode.c
fs/ntfs/super.c
fs/qnx4/inode.c
fs/reiserfs/journal.c
fs/reiserfs/resize.c
fs/sysv/inode.c
fs/sysv/itree.c
fs/udf/inode.c
fs/ufs/balloc.c
fs/ufs/dir.c
fs/ufs/ialloc.c
fs/ufs/inode.c
fs/ufs/truncate.c
include/linux/buffer_head.h
include/linux/hfs_sysdep.h
kernel/ksyms.c