Commit 50e029c6 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_moving_ctxt_flush_all()

Introduce a new helper to flush all move IOs, and use it in a few places
where we should have been.

The new helper also drops btree locks before waiting on outstanding move
writes, avoiding potential deadlocks.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 6201d91e
...@@ -163,12 +163,18 @@ void bch2_move_ctxt_wait_for_io(struct moving_context *ctxt) ...@@ -163,12 +163,18 @@ void bch2_move_ctxt_wait_for_io(struct moving_context *ctxt)
atomic_read(&ctxt->write_sectors) != sectors_pending); atomic_read(&ctxt->write_sectors) != sectors_pending);
} }
static void bch2_moving_ctxt_flush_all(struct moving_context *ctxt)
{
move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads));
bch2_trans_unlock_long(ctxt->trans);
closure_sync(&ctxt->cl);
}
void bch2_moving_ctxt_exit(struct moving_context *ctxt) void bch2_moving_ctxt_exit(struct moving_context *ctxt)
{ {
struct bch_fs *c = ctxt->trans->c; struct bch_fs *c = ctxt->trans->c;
move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads)); bch2_moving_ctxt_flush_all(ctxt);
closure_sync(&ctxt->cl);
EBUG_ON(atomic_read(&ctxt->write_sectors)); EBUG_ON(atomic_read(&ctxt->write_sectors));
EBUG_ON(atomic_read(&ctxt->write_ios)); EBUG_ON(atomic_read(&ctxt->write_ios));
...@@ -484,8 +490,8 @@ int bch2_move_ratelimit(struct moving_context *ctxt) ...@@ -484,8 +490,8 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
struct bch_fs *c = ctxt->trans->c; struct bch_fs *c = ctxt->trans->c;
u64 delay; u64 delay;
if (ctxt->wait_on_copygc && !c->copygc_running) { if (ctxt->wait_on_copygc && c->copygc_running) {
bch2_trans_unlock_long(ctxt->trans); bch2_moving_ctxt_flush_all(ctxt);
wait_event_killable(c->copygc_running_wq, wait_event_killable(c->copygc_running_wq,
!c->copygc_running || !c->copygc_running ||
kthread_should_stop()); kthread_should_stop());
...@@ -512,7 +518,7 @@ int bch2_move_ratelimit(struct moving_context *ctxt) ...@@ -512,7 +518,7 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
schedule_timeout(delay); schedule_timeout(delay);
if (unlikely(freezing(current))) { if (unlikely(freezing(current))) {
move_ctxt_wait_event(ctxt, list_empty(&ctxt->reads)); bch2_moving_ctxt_flush_all(ctxt);
try_to_freeze(); try_to_freeze();
} }
} while (delay); } while (delay);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment