From: Chao Yu Date: Tue, 27 Feb 2018 14:45:24 +0000 (+0800) Subject: f2fs: fix to avoid race in between atomic write and background GC X-Git-Tag: v4.19~1289^2~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1dc0f8991d4d93194fb7a3ac3164e05e8b24ad02;p=platform%2Fkernel%2Flinux-rpi.git 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 Signed-off-by: Jaegeuk Kim --- diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index c0a8098..6a202e5 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1715,6 +1715,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; @@ -1733,6 +1735,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;