diff options
| author | Chao Yu <yuchao0@huawei.com> | 2018-02-27 22:45:24 +0800 |
|---|---|---|
| committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2018-04-08 03:51:07 -0700 |
| commit | 58edcdbca67ab09ef7631e7a94a5bd5190895631 (patch) | |
| tree | 0c58a0e84a4878b9c1ee158c0ca9646fbcba1b70 | |
| parent | 1e0aeb0af9ed3b16b4c2543aa2c6502a153b897b (diff) | |
f2fs: fix to avoid race in between atomic write and background GC
Sqlite user Background GC
- move_data_block
: move page #1
- f2fs_is_atomic_file
- f2fs_ioc_start_atomic_write
- f2fs_ioc_commit_atomic_write
- commit_inmem_pages
: commit page #1 & set node #2 dirty
- f2fs_submit_page_write
- f2fs_update_data_blkaddr
- set_page_dirty
: set node #2 dirty
- f2fs_do_sync_file
- fsync_node_pages
: commit node #1 & node #2, then sudden power-cut
In a race case, we may check FI_ATOMIC_FILE flag before starting atomic
write flow, then we will commit meta data before data with reversed
order, after a sudden pow-cut, database transaction will be inconsistent.
So we'd better to exclude gc/atomic_write to each other by using lock
instead of flag checking.
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
| -rw-r--r-- | fs/f2fs/file.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index e418fc5b3fed..8ec080550a37 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1713,6 +1713,8 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) inode_lock(inode); + down_write(&F2FS_I(inode)->dio_rwsem[WRITE]); + if (f2fs_is_volatile_file(inode)) goto err_out; @@ -1731,6 +1733,7 @@ static int f2fs_ioc_commit_atomic_write(struct file *filp) ret = f2fs_do_sync_file(filp, 0, LLONG_MAX, 1, false); } err_out: + up_write(&F2FS_I(inode)->dio_rwsem[WRITE]); inode_unlock(inode); mnt_drop_write_file(filp); return ret; |
