Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
unsigned i;
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) {
down_read(&ca->bucket_lock);
up_read(&ca->bucket_lock);
}
err:
- up_read(&c->state_lock);
+ up_read(&c->gc_lock);
return ret;
}
bch2_copygc_stop(ca);
if (resize) {
+ down_write(&c->gc_lock);
down_write(&ca->bucket_lock);
percpu_down_write(&c->mark_lock);
}
swap(ca->buckets_nouse, buckets_nouse);
- if (resize)
+ if (resize) {
percpu_up_write(&c->mark_lock);
+ up_write(&c->gc_lock);
+ }
spin_lock(&c->freelist_lock);
for (i = 0; i < RESERVE_NR; i++) {