Commit 9e2c3c2e authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix lost rebalance wakeups



Fix a missing wakeup in

'bcachefs set-file-option' -> xattr option update -> inode_write

this was missing because the wakeup needs to happen after transaction
commit. Also, add a 'kick' counter, to make sure we don't miss a wakeup
that occured right after we finished checking the rebalance_work btree.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent dc37dcca
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -124,8 +124,9 @@ int __must_check bch2_write_inode(struct bch_fs *c,
		goto err;

	struct bch_extent_rebalance new_r = bch2_inode_rebalance_opts_get(c, &inode_u);
	bool rebalance_changed = memcmp(&old_r, &new_r, sizeof(new_r));

	if (memcmp(&old_r, &new_r, sizeof(new_r))) {
	if (rebalance_changed) {
		ret = bch2_set_rebalance_needs_scan_trans(trans, inode_u.bi_inum);
		if (ret)
			goto err;
@@ -146,6 +147,9 @@ int __must_check bch2_write_inode(struct bch_fs *c,
	if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
		goto retry;

	if (rebalance_changed)
		bch2_rebalance_wakeup(c);

	bch2_fs_fatal_err_on(bch2_err_matches(ret, ENOENT), c,
			     "%s: inode %llu:%llu not found when updating",
			     bch2_err_str(ret),
+4 −2
Original line number Diff line number Diff line
@@ -527,7 +527,7 @@ static void rebalance_wait(struct bch_fs *c)
		r->state		= BCH_REBALANCE_waiting;
	}

	bch2_kthread_io_clock_wait(clock, r->wait_iotime_end, MAX_SCHEDULE_TIMEOUT);
	bch2_kthread_io_clock_wait_once(clock, r->wait_iotime_end, MAX_SCHEDULE_TIMEOUT);
}

static bool bch2_rebalance_enabled(struct bch_fs *c)
@@ -544,6 +544,7 @@ static int do_rebalance(struct moving_context *ctxt)
	struct bch_fs_rebalance *r = &c->rebalance;
	struct btree_iter rebalance_work_iter, extent_iter = {};
	struct bkey_s_c k;
	u32 kick = r->kick;
	int ret = 0;

	bch2_trans_begin(trans);
@@ -593,7 +594,8 @@ static int do_rebalance(struct moving_context *ctxt)
	if (!ret &&
	    !kthread_should_stop() &&
	    !atomic64_read(&r->work_stats.sectors_seen) &&
	    !atomic64_read(&r->scan_stats.sectors_seen)) {
	    !atomic64_read(&r->scan_stats.sectors_seen) &&
	    kick == r->kick) {
		bch2_moving_ctxt_flush_all(ctxt);
		bch2_trans_unlock_long(trans);
		rebalance_wait(c);
+3 −5
Original line number Diff line number Diff line
@@ -39,13 +39,11 @@ int bch2_set_fs_needs_rebalance(struct bch_fs *);

static inline void bch2_rebalance_wakeup(struct bch_fs *c)
{
	struct task_struct *p;

	rcu_read_lock();
	p = rcu_dereference(c->rebalance.thread);
	c->rebalance.kick++;
	guard(rcu)();
	struct task_struct *p = rcu_dereference(c->rebalance.thread);
	if (p)
		wake_up_process(p);
	rcu_read_unlock();
}

void bch2_rebalance_status_to_text(struct printbuf *, struct bch_fs *);
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ enum bch_rebalance_states {

struct bch_fs_rebalance {
	struct task_struct __rcu	*thread;
	u32				kick;
	struct bch_pd_controller pd;

	enum bch_rebalance_states	state;