aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-08-31 06:56:06 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2017-09-05 13:50:23 -0400
commitd3238691ed5f7be29f7b8b7cf7c68bbb2924361d (patch)
treea9cca98a6ebe0bd3b764cc91f2ab37ca41675203
parentedd748e6c8e824a8281f8a8450f12c4a95ec61ee (diff)
f2fs: fix to wake up all sleeping flusher
In scenario of remount_ro vs flush, after flush_thread exits in ->remount_fs, flusher will only clean up golbal issue_list, but without waking up flushers waiting on that list, result in hang related user threads. In order to fix this issue, this patch enables the flusher to take charge of issue_flush thread: executes merged flush command, and wake up all sleeping flushers. Fixes: 5eba8c5d1fb3 ("f2fs: fix to access nullified flush_cmd_control pointer") Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/segment.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 1215ca1bd4e2..265c3bc44f2d 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -558,8 +558,27 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi)
558 wait_for_completion(&cmd.wait); 558 wait_for_completion(&cmd.wait);
559 atomic_dec(&fcc->issing_flush); 559 atomic_dec(&fcc->issing_flush);
560 } else { 560 } else {
561 llist_del_all(&fcc->issue_list); 561 struct llist_node *list;
562 atomic_set(&fcc->issing_flush, 0); 562
563 list = llist_del_all(&fcc->issue_list);
564 if (!list) {
565 wait_for_completion(&cmd.wait);
566 atomic_dec(&fcc->issing_flush);
567 } else {
568 struct flush_cmd *tmp, *next;
569
570 ret = submit_flush_wait(sbi);
571
572 llist_for_each_entry_safe(tmp, next, list, llnode) {
573 if (tmp == &cmd) {
574 cmd.ret = ret;
575 atomic_dec(&fcc->issing_flush);
576 continue;
577 }
578 tmp->ret = ret;
579 complete(&tmp->wait);
580 }
581 }
563 } 582 }
564 583
565 return cmd.ret; 584 return cmd.ret;