From: Kent Overstreet Date: Sat, 18 Feb 2023 02:04:46 +0000 (-0500) Subject: bcachefs: Don't block on ec_stripe_head_lock with btree locks held X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=af0ee5bcf3012be753ab15ce9c27971e5b34bd74;p=linux.git bcachefs: Don't block on ec_stripe_head_lock with btree locks held Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index ca3e4a18e28ac..236e1bef5f02d 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -1267,18 +1267,30 @@ void bch2_ec_stripe_head_put(struct bch_fs *c, struct ec_stripe_head *h) mutex_unlock(&h->lock); } -struct ec_stripe_head *__bch2_ec_stripe_head_get(struct bch_fs *c, +struct ec_stripe_head *__bch2_ec_stripe_head_get(struct btree_trans *trans, unsigned target, unsigned algo, unsigned redundancy, bool copygc) { + struct bch_fs *c = trans->c; struct ec_stripe_head *h; + int ret; if (!redundancy) return NULL; - mutex_lock(&c->ec_stripe_head_lock); + if (!mutex_trylock(&c->ec_stripe_head_lock)) { + bch2_trans_unlock(trans); + mutex_lock(&c->ec_stripe_head_lock); + + ret = bch2_trans_relock(trans); + if (ret) { + mutex_unlock(&c->ec_stripe_head_lock); + return ERR_PTR(ret); + } + } + list_for_each_entry(h, &c->ec_stripe_head_list, list) if (h->target == target && h->algo == algo && @@ -1477,11 +1489,11 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans, int ret; bool needs_stripe_new; - h = __bch2_ec_stripe_head_get(c, target, algo, redundancy, copygc); - if (!h) { + h = __bch2_ec_stripe_head_get(trans, target, algo, redundancy, copygc); + if (!h) bch_err(c, "no stripe head"); - return NULL; - } + if (IS_ERR_OR_NULL(h)) + return h; needs_stripe_new = !h->s; if (needs_stripe_new) {