The following race could lead to inconsistent SIT bitmap:
Task A Task B
====== ======
f2fs_write_checkpoint
block_operations
f2fs_lock_all
down_write(node_change)
down_write(node_write)
... sync ...
up_write(node_change)
f2fs_file_write_iter
set_inode_flag(FI_NO_PREALLOC)
......
f2fs_write_begin(index=0, has inline data)
prepare_write_begin
__do_map_lock(AIO) =>
down_read(node_change)
f2fs_convert_inline_page => update SIT
__do_map_lock(AIO) => up_read(node_change)
f2fs_flush_sit_entries <= inconsistent SIT
finish write checkpoint
sudden-power-off
If SPO occurs after checkpoint is finished, SIT bitmap will be set
incorrectly. This patch uses node_write to avoid the race condition.
Signed-off-by: Sheng Yong <[email protected]>
---
fs/f2fs/data.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 106f116466bf..dc5b251aee86 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2355,7 +2355,9 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
if (inode->i_nlink)
set_inline_node(ipage);
} else {
+ down_read(&sbi->node_write);
err = f2fs_convert_inline_page(&dn, page);
+ up_read(&sbi->node_write);
if (err)
goto out;
if (dn.data_blkaddr == NULL_ADDR)
--
2.17.1
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel