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 &&
        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) {