Commit b0d3ab53 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: Reduce the scope of gc_lock

gc_lock is now only for synchronization between check_alloc_info and
interior btree updates - nothing else
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 132e1a23
...@@ -596,8 +596,6 @@ int bch2_alloc_read(struct bch_fs *c) ...@@ -596,8 +596,6 @@ int bch2_alloc_read(struct bch_fs *c)
struct bch_dev *ca = NULL; struct bch_dev *ca = NULL;
int ret; int ret;
down_read(&c->gc_lock);
if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_bucket_gens) { if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_bucket_gens) {
ret = for_each_btree_key(trans, iter, BTREE_ID_bucket_gens, POS_MIN, ret = for_each_btree_key(trans, iter, BTREE_ID_bucket_gens, POS_MIN,
BTREE_ITER_prefetch, k, ({ BTREE_ITER_prefetch, k, ({
...@@ -646,7 +644,6 @@ int bch2_alloc_read(struct bch_fs *c) ...@@ -646,7 +644,6 @@ int bch2_alloc_read(struct bch_fs *c)
bch2_dev_put(ca); bch2_dev_put(ca);
bch2_trans_put(trans); bch2_trans_put(trans);
up_read(&c->gc_lock);
bch_err_fn(c, ret); bch_err_fn(c, ret);
return ret; return ret;
......
...@@ -538,8 +538,8 @@ struct bch_dev { ...@@ -538,8 +538,8 @@ struct bch_dev {
/* /*
* Buckets: * Buckets:
* Per-bucket arrays are protected by c->mark_lock, bucket_lock and * Per-bucket arrays are protected by c->mark_lock, bucket_lock and
* gc_lock, for device resize - holding any is sufficient for access: * gc_gens_lock, for device resize - holding any is sufficient for
* Or rcu_read_lock(), but only for dev_ptr_stale(): * access: Or rcu_read_lock(), but only for dev_ptr_stale():
*/ */
struct bucket_array __rcu *buckets_gc; struct bucket_array __rcu *buckets_gc;
struct bucket_gens __rcu *bucket_gens; struct bucket_gens __rcu *bucket_gens;
......
...@@ -1240,7 +1240,7 @@ int bch2_gc_gens(struct bch_fs *c) ...@@ -1240,7 +1240,7 @@ int bch2_gc_gens(struct bch_fs *c)
int ret; int ret;
/* /*
* Ideally we would be using state_lock and not gc_lock here, but that * Ideally we would be using state_lock and not gc_gens_lock here, but that
* introduces a deadlock in the RO path - we currently take the state * 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: * lock at the start of going RO, thus the gc thread may get stuck:
*/ */
...@@ -1248,7 +1248,8 @@ int bch2_gc_gens(struct bch_fs *c) ...@@ -1248,7 +1248,8 @@ int bch2_gc_gens(struct bch_fs *c)
return 0; return 0;
trace_and_count(c, gc_gens_start, c); trace_and_count(c, gc_gens_start, c);
down_read(&c->gc_lock);
down_read(&c->state_lock);
for_each_member_device(c, ca) { for_each_member_device(c, ca) {
struct bucket_gens *gens = bucket_gens(ca); struct bucket_gens *gens = bucket_gens(ca);
...@@ -1317,7 +1318,7 @@ int bch2_gc_gens(struct bch_fs *c) ...@@ -1317,7 +1318,7 @@ int bch2_gc_gens(struct bch_fs *c)
ca->oldest_gen = NULL; ca->oldest_gen = NULL;
} }
up_read(&c->gc_lock); up_read(&c->state_lock);
mutex_unlock(&c->gc_gens_lock); mutex_unlock(&c->gc_gens_lock);
if (!bch2_err_matches(ret, EROFS)) if (!bch2_err_matches(ret, EROFS))
bch_err_fn(c, ret); bch_err_fn(c, ret);
......
...@@ -1217,7 +1217,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -1217,7 +1217,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
bucket_gens->nbuckets - bucket_gens->first_bucket; bucket_gens->nbuckets - bucket_gens->first_bucket;
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);
} }
...@@ -1240,7 +1239,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -1240,7 +1239,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
if (resize) { if (resize) {
percpu_up_write(&c->mark_lock); percpu_up_write(&c->mark_lock);
up_write(&ca->bucket_lock); up_write(&ca->bucket_lock);
up_write(&c->gc_lock);
} }
ret = 0; ret = 0;
......
...@@ -85,7 +85,7 @@ static inline struct bucket_array *gc_bucket_array(struct bch_dev *ca) ...@@ -85,7 +85,7 @@ static inline struct bucket_array *gc_bucket_array(struct bch_dev *ca)
return rcu_dereference_check(ca->buckets_gc, return rcu_dereference_check(ca->buckets_gc,
!ca->fs || !ca->fs ||
percpu_rwsem_is_held(&ca->fs->mark_lock) || percpu_rwsem_is_held(&ca->fs->mark_lock) ||
lockdep_is_held(&ca->fs->gc_lock) || lockdep_is_held(&ca->fs->state_lock) ||
lockdep_is_held(&ca->bucket_lock)); lockdep_is_held(&ca->bucket_lock));
} }
...@@ -103,7 +103,7 @@ static inline struct bucket_gens *bucket_gens(struct bch_dev *ca) ...@@ -103,7 +103,7 @@ static inline struct bucket_gens *bucket_gens(struct bch_dev *ca)
return rcu_dereference_check(ca->bucket_gens, return rcu_dereference_check(ca->bucket_gens,
!ca->fs || !ca->fs ||
percpu_rwsem_is_held(&ca->fs->mark_lock) || percpu_rwsem_is_held(&ca->fs->mark_lock) ||
lockdep_is_held(&ca->fs->gc_lock) || lockdep_is_held(&ca->fs->state_lock) ||
lockdep_is_held(&ca->bucket_lock)); lockdep_is_held(&ca->bucket_lock));
} }
......
...@@ -193,6 +193,8 @@ int bch2_run_online_recovery_passes(struct bch_fs *c) ...@@ -193,6 +193,8 @@ int bch2_run_online_recovery_passes(struct bch_fs *c)
{ {
int ret = 0; int ret = 0;
down_read(&c->state_lock);
for (unsigned i = 0; i < ARRAY_SIZE(recovery_pass_fns); i++) { for (unsigned i = 0; i < ARRAY_SIZE(recovery_pass_fns); i++) {
struct recovery_pass_fn *p = recovery_pass_fns + i; struct recovery_pass_fn *p = recovery_pass_fns + i;
...@@ -208,6 +210,8 @@ int bch2_run_online_recovery_passes(struct bch_fs *c) ...@@ -208,6 +210,8 @@ int bch2_run_online_recovery_passes(struct bch_fs *c)
break; break;
} }
up_read(&c->state_lock);
return ret; return ret;
} }
......
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