aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-08-31 18:56:06 +0800
committerMister Oyster <oysterized@gmail.com>2017-10-04 15:35:26 +0200
commit458163bbd7e00b2c9d4117b2683a61bb3365a8e7 (patch)
tree129790bf39868ad6c1496db2635fa1e187e4b3b5
parent11c74a94cb4925ccacc26bce3690240f9a71dbfe (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 21680ef97..6fc2a5f18 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -596,8 +596,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;