bcachefs: Fix a deadlock
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 22 Mar 2019 08:32:29 +0000 (04:32 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:18 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update_leaf.c

index 503cbc5ae309b03dfd31bbd4cc36ad1a9928a5cd..a05fd7104a72854cd6b1b478f1c9e7a15eeee345 100644 (file)
@@ -560,6 +560,8 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
        trans_for_each_update_iter(trans, i)
                BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK);
 
        trans_for_each_update_iter(trans, i)
                BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK);
 
+       btree_trans_lock_write(c, trans);
+
        trans_for_each_update_iter(trans, i) {
                if (i->deferred ||
                    !btree_node_type_needs_gc(i->iter->btree_id))
        trans_for_each_update_iter(trans, i) {
                if (i->deferred ||
                    !btree_node_type_needs_gc(i->iter->btree_id))
@@ -577,12 +579,10 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
                }
        }
 
                }
        }
 
-       btree_trans_lock_write(c, trans);
-
        if (race_fault()) {
                ret = -EINTR;
                trans_restart(" (race)");
        if (race_fault()) {
                ret = -EINTR;
                trans_restart(" (race)");
-               goto out_unlock;
+               goto out;
        }
 
        /*
        }
 
        /*
@@ -592,7 +592,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
         */
        ret = btree_trans_check_can_insert(trans, stopped_at);
        if (ret)
         */
        ret = btree_trans_check_can_insert(trans, stopped_at);
        if (ret)
-               goto out_unlock;
+               goto out;
 
        /*
         * Don't get journal reservation until after we know insert will
 
        /*
         * Don't get journal reservation until after we know insert will
@@ -600,7 +600,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
         */
        ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_NONBLOCK);
        if (ret)
         */
        ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_NONBLOCK);
        if (ret)
-               goto out_unlock;
+               goto out;
 
        if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) {
                if (journal_seq_verify(c))
 
        if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) {
                if (journal_seq_verify(c))
@@ -632,13 +632,13 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
 
        trans_for_each_update(trans, i)
                do_btree_insert_one(trans, i);
 
        trans_for_each_update(trans, i)
                do_btree_insert_one(trans, i);
-out_unlock:
+out:
        BUG_ON(ret &&
               (trans->flags & BTREE_INSERT_JOURNAL_RESERVED) &&
               trans->journal_res.ref);
 
        btree_trans_unlock_write(trans);
        BUG_ON(ret &&
               (trans->flags & BTREE_INSERT_JOURNAL_RESERVED) &&
               trans->journal_res.ref);
 
        btree_trans_unlock_write(trans);
-out:
+
        if (fs_usage) {
                bch2_fs_usage_scratch_put(c, fs_usage);
                percpu_up_read(&c->mark_lock);
        if (fs_usage) {
                bch2_fs_usage_scratch_put(c, fs_usage);
                percpu_up_read(&c->mark_lock);