bcachefs: Don't allocate memory while holding journal reservation
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 30 Mar 2020 16:33:30 +0000 (12:33 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:37 +0000 (17:08 -0400)
This fixes a lockdep splat - allocating memory can call
bch2_clear_page_bits() which takes mark_lock.

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

index f09423c83c4a8573f8b1b35a6edba7b6f202fdf7..e8dd19cae7ca50c799d095fe3e8cd39a2de9caf5 100644 (file)
@@ -713,13 +713,6 @@ again:
 
                bch2_btree_add_journal_pin(c, b, res.seq);
                six_unlock_write(&b->c.lock);
-
-               /*
-                * b->write_blocked prevented it from being written, so
-                * write it now if it needs to be written:
-                */
-               btree_node_write_if_need(c, b, SIX_LOCK_intent);
-               six_unlock_intent(&b->c.lock);
                break;
 
        case BTREE_INTERIOR_UPDATING_AS:
@@ -746,6 +739,16 @@ again:
        bch2_journal_res_put(&c->journal, &res);
        bch2_journal_preres_put(&c->journal, &as->journal_preres);
 
+       /* Do btree write after dropping journal res: */
+       if (b) {
+               /*
+                * b->write_blocked prevented it from being written, so
+                * write it now if it needs to be written:
+                */
+               btree_node_write_if_need(c, b, SIX_LOCK_intent);
+               six_unlock_intent(&b->c.lock);
+       }
+
        btree_update_nodes_reachable(as, res.seq);
 free_update:
        __bch2_btree_update_free(as);