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: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
e0fafac5c4
commit
778ac324cc
@ -162,6 +162,10 @@ static void open_bucket_free_unused(struct bch_fs *c, struct open_bucket *ob)
|
|||||||
ARRAY_SIZE(c->open_buckets_partial));
|
ARRAY_SIZE(c->open_buckets_partial));
|
||||||
|
|
||||||
spin_lock(&c->freelist_lock);
|
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;
|
ob->on_partial_list = true;
|
||||||
c->open_buckets_partial[c->open_buckets_partial_nr++] =
|
c->open_buckets_partial[c->open_buckets_partial_nr++] =
|
||||||
ob - c->open_buckets;
|
ob - c->open_buckets;
|
||||||
@ -972,7 +976,7 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
|
|||||||
u64 avail;
|
u64 avail;
|
||||||
|
|
||||||
bch2_dev_usage_read_fast(ca, &usage);
|
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)
|
if (!avail)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -981,6 +985,10 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
|
|||||||
i);
|
i);
|
||||||
ob->on_partial_list = false;
|
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,
|
ret = add_new_bucket(c, ptrs, devs_may_alloc,
|
||||||
nr_replicas, nr_effective,
|
nr_replicas, nr_effective,
|
||||||
have_cache, ob);
|
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;
|
--c->open_buckets_partial_nr;
|
||||||
swap(c->open_buckets_partial[i],
|
swap(c->open_buckets_partial[i],
|
||||||
c->open_buckets_partial[c->open_buckets_partial_nr]);
|
c->open_buckets_partial[c->open_buckets_partial_nr]);
|
||||||
|
|
||||||
ob->on_partial_list = false;
|
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);
|
spin_unlock(&c->freelist_lock);
|
||||||
bch2_open_bucket_put(c, ob);
|
bch2_open_bucket_put(c, ob);
|
||||||
spin_lock(&c->freelist_lock);
|
spin_lock(&c->freelist_lock);
|
||||||
|
@ -555,6 +555,7 @@ struct bch_dev {
|
|||||||
u64 alloc_cursor[3];
|
u64 alloc_cursor[3];
|
||||||
|
|
||||||
unsigned nr_open_buckets;
|
unsigned nr_open_buckets;
|
||||||
|
unsigned nr_partial_buckets;
|
||||||
unsigned nr_btree_reserve;
|
unsigned nr_btree_reserve;
|
||||||
|
|
||||||
size_t inc_gen_needs_gc;
|
size_t inc_gen_needs_gc;
|
||||||
|
Loading…
Reference in New Issue
Block a user