f2fs: fix an infinite loop when flush nodes in cp
authorYunlei He <heyunlei@huawei.com>
Wed, 16 Nov 2016 09:26:24 +0000 (17:26 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 25 Nov 2016 18:16:00 +0000 (10:16 -0800)
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: Yunlei He <heyunlei@huawei.com>
Signed-off-by: Pengyang Hou <houpengyang@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/node.c

index 38cc07d49ff3491a78ab7e99147dc50e09f43cf4..1de25f8710168792fa0b7596616b232be334616f 100644 (file)
@@ -1410,6 +1410,7 @@ continue_unlock:
                        "Retry to write fsync mark: ino=%u, idx=%lx",
                                        ino, last_page->index);
                lock_page(last_page);
+               f2fs_wait_on_page_writeback(last_page, NODE, true);
                set_page_dirty(last_page);
                unlock_page(last_page);
                goto retry;