diff options
author | zhengliang <zhengliang6@huawei.com> | 2019-03-03 20:32:25 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2019-03-05 22:57:56 -0500 |
commit | a0770e13c8da83bdb64738c0209ab02dd3cfff8b (patch) | |
tree | 6490c1b76a13fba8587ab7d638440301f7247309 /fs/f2fs/super.c | |
parent | 1ffdc3807589779626924eb600db784d3d943a08 (diff) |
f2fs: fix to data block override node segment by mistake
v4: Rearrange the previous three versions.
The following scenario could lead to data block override by mistake.
TASK A | TASK kworker | TASK B | TASK C
| | |
open | | |
write | | |
close | | |
| f2fs_write_data_pages | |
| f2fs_write_cache_pages | |
| f2fs_outplace_write_data | |
| f2fs_allocate_data_block (get block in seg S, | |
| S is full, and only | |
| have this valid data | |
| block) | |
| allocate_segment | |
| locate_dirty_segment (mark S as PRE) | |
| f2fs_submit_page_write (submit but is not | |
| written on dev) | |
unlink | | |
iput_final | | |
f2fs_drop_inode | | |
f2fs_truncate | | |
(not evict) | | |
| | write_checkpoint |
| | flush merged bio but not wait file data writeback |
| | set_prefree_as_free (mark S as FREE) |
| | | update NODE/DATA
| | | allocate_segment (select S)
| writeback done | |
So we need to guarantee io complete before truncate inode in f2fs_drop_inode.
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Zheng Liang <zhengliang6@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r-- | fs/f2fs/super.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 384d1c248857..e382be2f10f9 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -915,6 +915,10 @@ static int f2fs_drop_inode(struct inode *inode) | |||
915 | sb_start_intwrite(inode->i_sb); | 915 | sb_start_intwrite(inode->i_sb); |
916 | f2fs_i_size_write(inode, 0); | 916 | f2fs_i_size_write(inode, 0); |
917 | 917 | ||
918 | f2fs_submit_merged_write_cond(F2FS_I_SB(inode), | ||
919 | inode, NULL, 0, DATA); | ||
920 | truncate_inode_pages_final(inode->i_mapping); | ||
921 | |||
918 | if (F2FS_HAS_BLOCKS(inode)) | 922 | if (F2FS_HAS_BLOCKS(inode)) |
919 | f2fs_truncate(inode); | 923 | f2fs_truncate(inode); |
920 | 924 | ||