• Chao Yu's avatar
    f2fs: atomic: fix to avoid racing w/ GC · 1a0bd289
    Chao Yu authored
    Case #1:
    SQLite App		GC Thread		Kworker		Shrinker
    - f2fs_ioc_start_atomic_write
    
    - f2fs_ioc_commit_atomic_write
     - f2fs_commit_atomic_write
      - filemap_write_and_wait_range
      : write atomic_file's data to cow_inode
    								echo 3 > drop_caches
    								to drop atomic_file's
    								cache.
    			- f2fs_gc
    			 - gc_data_segment
    			  - move_data_page
    			   - set_page_dirty
    
    						- writepages
    						 - f2fs_do_write_data_page
    						 : overwrite atomic_file's data
    						   to cow_inode
      - f2fs_down_write(&fi->i_gc_rwsem[WRITE])
      - __f2fs_commit_atomic_write
      - f2fs_up_write(&fi->i_gc_rwsem[WRITE])
    
    Case #2:
    SQLite App		GC Thread		Kworker
    - f2fs_ioc_start_atomic_write
    
    						- __writeback_single_inode
    						 - do_writepages
    						  - f2fs_write_cache_pages
    						   - f2fs_write_single_data_page
    						    - f2fs_do_write_data_page
    						    : write atomic_file's data to cow_inode
    			- f2fs_gc
    			 - gc_data_segment
    			  - move_data_page
    			   - set_page_dirty
    
    						- writepages
    						 - f2fs_do_write_data_page
    						 : overwrite atomic_file's data to cow_inode
    - f2fs_ioc_commit_atomic_write
    
    In above cases racing in between atomic_write and GC, previous
    data in atomic_file may be overwrited to cow_file, result in
    data corruption.
    
    This patch introduces PAGE_PRIVATE_ATOMIC_WRITE bit flag in page.private,
    and use it to indicate that there is last dirty data in atomic file,
    and the data should be writebacked into cow_file, if the flag is not
    tagged in page, we should never write data across files.
    
    Fixes: 3db1de0e ("f2fs: change the current atomic write way")
    Cc: Daeho Jeong <daehojeong@google.com>
    Signed-off-by: default avatarChao Yu <chao@kernel.org>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    1a0bd289
f2fs.h 152 KB