Messages in this thread Patch in this message | | | From | Chao Yu <> | Subject | [PATCH v2] f2fs: wait IO writeback in commit_inmem_pages() | Date | Mon, 23 Apr 2018 23:14:25 +0800 |
| |
From: Chao Yu <yuchao0@huawei.com>
Thread A Thread B - f2fs_ioc_commit_atomic_write - commit_inmem_pages - f2fs_submit_merged_write_cond : write data - write_checkpoint - do_checkpoint : commit all node within CP -> SPO - f2fs_do_sync_file - file_write_and_wait_range : wait data writeback
In above race condition, data/node can be flushed in reversed order when coming a checkpoint before f2fs_do_sync_file, after SPOR, it results in atomic written data being corrupted.
This patch adds filemap_fdatawait() in commit_inmem_pages() to keep data and node of atomic file being flushed orderly.
Signed-off-by: Chao Yu <yuchao0@huawei.com> --- v2: - clean up codes suggested by Jaegeuk. fs/f2fs/file.c | 4 ++++ fs/f2fs/segment.c | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index bac059474342..0cfa65c21d3f 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -217,6 +217,9 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, trace_f2fs_sync_file_enter(inode); + if (atomic) + goto write_done; + /* if fdatasync is triggered, let's do in-place-update */ if (datasync || get_dirty_pages(inode) <= SM_I(sbi)->min_fsync_blocks) set_inode_flag(inode, FI_NEED_IPU); @@ -228,6 +231,7 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, return ret; } +write_done: /* if the inode is dirty, let's recover all the time */ if (!f2fs_skip_inode_update(inode, datasync)) { f2fs_write_inode(inode, NULL); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 710d817c4350..31336fc54d8e 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -419,6 +419,8 @@ static int __commit_inmem_pages(struct inode *inode) __revoke_inmem_pages(inode, &fi->inmem_pages, true, false); } else { __revoke_inmem_pages(inode, &revoke_list, false, false); + + err = filemap_fdatawait(inode->i_mapping); } return err; -- 2.16.2.17.g38e79b1fd
| |