• Andrew Morton's avatar
    [PATCH] Fix synchronous writers to wait properly for the result · 8d49bf3f
    Andrew Morton authored
    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.
    8d49bf3f
inode.c 14.9 KB