bcachefs: Don't keep nodes in btree_reserve locked
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 7 Feb 2022 06:19:39 +0000 (01:19 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:23 +0000 (17:09 -0400)
These nodes aren't reachable by other threads, so there's no need to
keep it locked - and this fixes a bug with the assertion in
bch2_trans_unlock() firing on transaction restart.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/btree_update_interior.c

index 0e7644a3a436e17ece1df34311a74eb9a2eac845..7d5efb32b082d68c69f23f9885c8133b41d10df8 100644 (file)
@@ -243,6 +243,8 @@ retry:
        bch2_alloc_sectors_done(c, wp);
 mem_alloc:
        b = bch2_btree_node_mem_alloc(c);
+       six_unlock_write(&b->c.lock);
+       six_unlock_intent(&b->c.lock);
 
        /* we hold cannibalize_lock: */
        BUG_ON(IS_ERR(b));
@@ -265,6 +267,9 @@ static struct btree *bch2_btree_node_alloc(struct btree_update *as, unsigned lev
 
        b = as->prealloc_nodes[--as->nr_prealloc_nodes];
 
+       six_lock_intent(&b->c.lock, NULL, NULL);
+       six_lock_write(&b->c.lock, NULL, NULL);
+
        set_btree_node_accessed(b);
        set_btree_node_dirty(c, b);
        set_btree_node_need_write(b);
@@ -378,7 +383,8 @@ static void bch2_btree_reserve_put(struct btree_update *as)
        while (as->nr_prealloc_nodes) {
                struct btree *b = as->prealloc_nodes[--as->nr_prealloc_nodes];
 
-               six_unlock_write(&b->c.lock);
+               six_lock_intent(&b->c.lock, NULL, NULL);
+               six_lock_write(&b->c.lock, NULL, NULL);
 
                if (c->btree_reserve_cache_nr <
                    ARRAY_SIZE(c->btree_reserve_cache)) {
@@ -392,10 +398,8 @@ static void bch2_btree_reserve_put(struct btree_update *as)
                        bch2_open_buckets_put(c, &b->ob);
                }
 
-               btree_node_lock_type(c, b, SIX_LOCK_write);
                __btree_node_free(c, b);
                six_unlock_write(&b->c.lock);
-
                six_unlock_intent(&b->c.lock);
        }