Commit b9c3d139 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix a deadlock in the RO path

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 47a5649a
...@@ -932,7 +932,12 @@ int bch2_gc_gens(struct bch_fs *c) ...@@ -932,7 +932,12 @@ int bch2_gc_gens(struct bch_fs *c)
unsigned i; unsigned i;
int ret; int ret;
down_read(&c->state_lock); /*
* Ideally we would be using state_lock and not gc_lock here, but that
* introduces a deadlock in the RO path - we currently take the state
* lock at the start of going RO, thus the gc thread may get stuck:
*/
down_read(&c->gc_lock);
for_each_member_device(ca, c, i) { for_each_member_device(ca, c, i) {
down_read(&ca->bucket_lock); down_read(&ca->bucket_lock);
...@@ -959,7 +964,7 @@ int bch2_gc_gens(struct bch_fs *c) ...@@ -959,7 +964,7 @@ int bch2_gc_gens(struct bch_fs *c)
up_read(&ca->bucket_lock); up_read(&ca->bucket_lock);
} }
err: err:
up_read(&c->state_lock); up_read(&c->gc_lock);
return ret; return ret;
} }
......
...@@ -2003,6 +2003,7 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -2003,6 +2003,7 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
bch2_copygc_stop(ca); bch2_copygc_stop(ca);
if (resize) { if (resize) {
down_write(&c->gc_lock);
down_write(&ca->bucket_lock); down_write(&ca->bucket_lock);
percpu_down_write(&c->mark_lock); percpu_down_write(&c->mark_lock);
} }
...@@ -2025,8 +2026,10 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -2025,8 +2026,10 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
swap(ca->buckets_nouse, buckets_nouse); swap(ca->buckets_nouse, buckets_nouse);
if (resize) if (resize) {
percpu_up_write(&c->mark_lock); percpu_up_write(&c->mark_lock);
up_write(&c->gc_lock);
}
spin_lock(&c->freelist_lock); spin_lock(&c->freelist_lock);
for (i = 0; i < RESERVE_NR; i++) { for (i = 0; i < RESERVE_NR; i++) {
......
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