• Liu Bo's avatar
    Btrfs: fix race between direct io and autodefrag · ecb8bea8
    Liu Bo authored
    The bug is from running xfstests 209 with autodefrag.
    
    The race is as follows:
           t1                       t2(autodefrag)
       direct IO
         invalidate pagecache
         dio(old data)             add_inode_defrag
         invalidate pagecache
       endio
    
       direct IO
         invalidate pagecache
                                    run_defrag
                                      readpage(old data)
                                      set page dirty (old data)
         dio(new data, rewrite)
         invalidate pagecache (*)
         endio
    
    t2(autodefrag) will get old data into pagecache via readpage and set
    pagecache dirty.  Meanwhile, invalidate pagecache(*) will fail due to
    dirty flags in pages.  So the old data may be flushed into disk by
    flush thread, which will lead to data loss.
    
    And so does the case of user defragment progs.
    
    The patch fixes this race by holding i_mutex when we readpage and set page dirty.
    Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
    Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    ecb8bea8
ioctl.c 80.1 KB