]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
f2fs: atomic: fix to avoid racing w/ GC
authorChao Yu <chao@kernel.org>
Tue, 25 Jun 2024 03:13:48 +0000 (11:13 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 5 Aug 2024 20:18:36 +0000 (20:18 +0000)
commit1a0bd289a5db1df8df8fab949633a0b8d3f235ee
tree51689b14da2ea12429df0a5e5352d96f5e68f823
parentd72750e4a7528b83a07b65335c35b454a98593d4
f2fs: atomic: fix to avoid racing w/ GC

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: 3db1de0e582c ("f2fs: change the current atomic write way")
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/data.c
fs/f2fs/f2fs.h