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>

authored by

Chao Yu and committed by
Jaegeuk Kim
d3238691 edd748e6

+21 -2
+21 -2
fs/f2fs/segment.c
··· 558 558 wait_for_completion(&cmd.wait); 559 559 atomic_dec(&fcc->issing_flush); 560 560 } else { 561 - llist_del_all(&fcc->issue_list); 562 - atomic_set(&fcc->issing_flush, 0); 561 + struct llist_node *list; 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 584 return cmd.ret;