• Hisashi Hifumi's avatar
    VFS: fix dio write returning EIO when try_to_release_page fails · 6ccfa806
    Hisashi Hifumi authored
    Dio write returns EIO when try_to_release_page fails because bh is
    still referenced.
    
    The patch
    
        commit 3f31fddf
        Author: Mingming Cao <cmm@us.ibm.com>
        Date:   Fri Jul 25 01:46:22 2008 -0700
    
            jbd: fix race between free buffer and commit transaction
    
    was merged into 2.6.27-rc1, but I noticed that this patch is not enough
    to fix the race.
    
    I did fsstress test heavily to 2.6.27-rc1, and found that dio write still
    sometimes got EIO through this test.
    
    The patch above fixed race between freeing buffer(dio) and committing
    transaction(jbd) but I discovered that there is another race, freeing
    buffer(dio) and ext3/4_ordered_writepage.
    
    : background_writeout()
         ->write_cache_pages()
           ->ext3_ordered_writepage()
         	   walk_page_buffers() -> take a bh ref
     	   block_write_full_page() -> unlock_page
    		: <- end_page_writeback
                    : <- race! (dio write->try_to_release_page fails)
          	   walk_page_buffers() ->release a bh ref
    
    ext3_ordered_writepage holds bh ref and does unlock_page remaining
    taking a bh ref, so this causes the race and failure of
    try_to_release_page.
    
    To fix this race, I used the approach of falling back to buffered
    writes if try_to_release_page() fails on a page.
    
    [akpm@linux-foundation.org: cleanups]
    Signed-off-by: default avatarHisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp>
    Cc: Chris Mason <chris.mason@oracle.com>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Mingming Cao <cmm@us.ibm.com>
    Cc: Zach Brown <zach.brown@oracle.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    6ccfa806
filemap.c 70.2 KB