Commit 778ac324 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix deadlock on -ENOSPC w.r.t. partial open buckets



Open buckets on the partial list should not count as allocated when
we're trying to allocate from the partial list.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent e0fafac5
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -162,6 +162,10 @@ static void open_bucket_free_unused(struct bch_fs *c, struct open_bucket *ob)
	       ARRAY_SIZE(c->open_buckets_partial));

	spin_lock(&c->freelist_lock);
	rcu_read_lock();
	bch2_dev_rcu(c, ob->dev)->nr_partial_buckets++;
	rcu_read_unlock();

	ob->on_partial_list = true;
	c->open_buckets_partial[c->open_buckets_partial_nr++] =
		ob - c->open_buckets;
@@ -972,7 +976,7 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
			u64 avail;

			bch2_dev_usage_read_fast(ca, &usage);
			avail = dev_buckets_free(ca, usage, watermark);
			avail = dev_buckets_free(ca, usage, watermark) + ca->nr_partial_buckets;
			if (!avail)
				continue;

@@ -981,6 +985,10 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
					  i);
			ob->on_partial_list = false;

			rcu_read_lock();
			bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
			rcu_read_unlock();

			ret = add_new_bucket(c, ptrs, devs_may_alloc,
					     nr_replicas, nr_effective,
					     have_cache, ob);
@@ -1191,7 +1199,13 @@ void bch2_open_buckets_stop(struct bch_fs *c, struct bch_dev *ca,
			--c->open_buckets_partial_nr;
			swap(c->open_buckets_partial[i],
			     c->open_buckets_partial[c->open_buckets_partial_nr]);

			ob->on_partial_list = false;

			rcu_read_lock();
			bch2_dev_rcu(c, ob->dev)->nr_partial_buckets--;
			rcu_read_unlock();

			spin_unlock(&c->freelist_lock);
			bch2_open_bucket_put(c, ob);
			spin_lock(&c->freelist_lock);
+1 −0
Original line number Diff line number Diff line
@@ -555,6 +555,7 @@ struct bch_dev {
	u64			alloc_cursor[3];

	unsigned		nr_open_buckets;
	unsigned		nr_partial_buckets;
	unsigned		nr_btree_reserve;

	size_t			inc_gen_needs_gc;