From: zhengliang <[email protected]> [ Upstream commit a0770e13c8da83bdb64738c0209ab02dd3cfff8b ]
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 <[email protected]>
Signed-off-by: Zheng Liang <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
fs/f2fs/super.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4c169ba50c0f..06b75737b1a0 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -668,6 +668,10 @@ static int f2fs_drop_inode(struct inode *inode)
sb_start_intwrite(inode->i_sb);
f2fs_i_size_write(inode, 0);
+ f2fs_submit_merged_write_cond(F2FS_I_SB(inode),
+ inode, NULL, 0, DATA);
+ truncate_inode_pages_final(inode->i_mapping);
+
if (F2FS_HAS_BLOCKS(inode))
f2fs_truncate(inode);
--
2.20.1
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
