f2fs: fix to avoid data update racing between GC and DIO
authorChao Yu <yuchao0@huawei.com>
Wed, 13 Jul 2016 01:18:29 +0000 (09:18 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 15 Jul 2016 22:21:22 +0000 (15:21 -0700)
commit82e0a5aa5ddf794b3e1b21fcd091228736871882
tree4cc2beb40b6756219c2da15a5546ec9772f0ec0e
parent44a83499dda714d9262a9bf4fdac8c077893c9e6
f2fs: fix to avoid data update racing between GC and DIO

Datas in file can be operated by GC and DIO simultaneously, so we will
face race case as below:

For write case:
Thread A Thread B
- generic_file_direct_write
 - invalidate_inode_pages2_range
 - f2fs_direct_IO
  - do_blockdev_direct_IO
   - do_direct_IO
    - get_more_blocks
- f2fs_gc
 - do_garbage_collect
  - gc_data_segment
   - move_data_page
    - do_write_data_page
    migrate data block to new block address
   - dio_bio_submit
   update user data to old block address

For read case:
Thread A                                Thread B
- generic_file_direct_write
 - invalidate_inode_pages2_range
 - f2fs_direct_IO
  - do_blockdev_direct_IO
   - do_direct_IO
    - get_more_blocks
- f2fs_balance_fs
 - f2fs_gc
  - do_garbage_collect
   - gc_data_segment
    - move_data_page
     - do_write_data_page
     migrate data block to new block address
  - write_checkpoint
   - do_checkpoint
    - clear_prefree_segments
     - f2fs_issue_discard
                                             discard old block adress
   - dio_bio_submit
   update user buffer from obsolete block address

In order to fix this, for one file, we should let DIO and GC getting exclusion
against with each other.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/gc.c
fs/f2fs/super.c