summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-08-31 18:56:06 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2017-09-21 14:15:24 -0700
commitccb0b5d09d8c46c03e91c8e7a62b57fedee0662e (patch)
tree877857b0de5993e15cd1b154781b5b422f031a00
parent3b8bbd990ce57815f0b0b4b60029ba8d173f5912 (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 370b4ca0e294..9d8d32b38073 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -558,8 +558,27 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi)
wait_for_completion(&cmd.wait);
atomic_dec(&fcc->issing_flush);
} else {
- llist_del_all(&fcc->issue_list);
- atomic_set(&fcc->issing_flush, 0);
+ struct llist_node *list;
+
+ list = llist_del_all(&fcc->issue_list);
+ if (!list) {
+ wait_for_completion(&cmd.wait);
+ atomic_dec(&fcc->issing_flush);
+ } else {
+ struct flush_cmd *tmp, *next;
+
+ ret = submit_flush_wait(sbi);
+
+ llist_for_each_entry_safe(tmp, next, list, llnode) {
+ if (tmp == &cmd) {
+ cmd.ret = ret;
+ atomic_dec(&fcc->issing_flush);
+ continue;
+ }
+ tmp->ret = ret;
+ complete(&tmp->wait);
+ }
+ }
}
return cmd.ret;