Commit 261af2f1 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Make sure bch2_move_ratelimit() also waits for move_ops



This adds move_ctxt_wait_event_timeout(), which can sleep for a timeout
while also issueing pending moves as reads complete.

Co-developed-by: default avatarDaniel Hill <daniel@gluo.nz>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 50e029c6
Loading
Loading
Loading
Loading
+4 −13
Original line number Diff line number Diff line
@@ -500,22 +500,13 @@ int bch2_move_ratelimit(struct moving_context *ctxt)
	do {
		delay = ctxt->rate ? bch2_ratelimit_delay(ctxt->rate) : 0;


		if (delay) {
			if (delay > HZ / 10)
				bch2_trans_unlock_long(ctxt->trans);
			else
				bch2_trans_unlock(ctxt->trans);
			set_current_state(TASK_INTERRUPTIBLE);
		}

		if ((current->flags & PF_KTHREAD) && kthread_should_stop()) {
			__set_current_state(TASK_RUNNING);
		if ((current->flags & PF_KTHREAD) && kthread_should_stop())
			return 1;
		}

		if (delay)
			schedule_timeout(delay);
			move_ctxt_wait_event_timeout(ctxt,
					freezing(current) || kthread_should_stop(),
					delay);

		if (unlikely(freezing(current))) {
			bch2_moving_ctxt_flush_all(ctxt);
+19 −0
Original line number Diff line number Diff line
@@ -38,6 +38,25 @@ struct moving_context {
	wait_queue_head_t	wait;
};

#define move_ctxt_wait_event_timeout(_ctxt, _cond, _timeout)			\
({										\
	int _ret = 0;								\
	while (true) {								\
		bool cond_finished = false;					\
		bch2_moving_ctxt_do_pending_writes(_ctxt);			\
										\
		if (_cond)							\
			break;							\
		bch2_trans_unlock_long((_ctxt)->trans);				\
		_ret = __wait_event_timeout((_ctxt)->wait,			\
			     bch2_moving_ctxt_next_pending_write(_ctxt) ||	\
			     (cond_finished = (_cond)), _timeout);		\
		if (_ret || ( cond_finished))					\
			break;							\
	}									\
	_ret;									\
})

#define move_ctxt_wait_event(_ctxt, _cond)				\
do {									\
	bool cond_finished = false;					\