Commit d40a43af authored by Yunlei He's avatar Yunlei He Committed by Jaegeuk Kim

f2fs: fix an infinite loop when flush nodes in cp

Thread A			Thread B

- write_checkpoint
 - block_operations
   -blk_start_plug
    -sync_node_pages		- f2fs_do_sync_file
				 - fsync_node_pages
				  - f2fs_wait_on_page_writeback

Thread A wait for global F2FS_DIRTY_NODES decreased to zero,
it start a plug list, some requests have been added to this list.
Thread B lock one dirty node page, and wait this page write back.
But this page has been in plug list of thread A with PG_writeback flag.
Thread A keep on running and its plug list has no chance to finish,
so it seems a deadlock between cp and fsync path.

This patch add a wait on page write back before set node page dirty
to avoid this problem.
Signed-off-by: default avatarYunlei He <heyunlei@huawei.com>
Signed-off-by: default avatarPengyang Hou <houpengyang@huawei.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 36951b38
...@@ -1410,6 +1410,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, ...@@ -1410,6 +1410,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
"Retry to write fsync mark: ino=%u, idx=%lx", "Retry to write fsync mark: ino=%u, idx=%lx",
ino, last_page->index); ino, last_page->index);
lock_page(last_page); lock_page(last_page);
f2fs_wait_on_page_writeback(last_page, NODE, true);
set_page_dirty(last_page); set_page_dirty(last_page);
unlock_page(last_page); unlock_page(last_page);
goto retry; goto retry;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment