]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_update_interior.c
Update bcachefs sources to 0010403265 bcachefs: Fix spurious alloc errors on forced...
[bcachefs-tools-debian] / libbcachefs / btree_update_interior.c
index 5143896e1b29e1f07e71d106789ad69587ba887b..edc11c22308c1dfa4de71cce501604d4da08fcea 100644 (file)
@@ -544,6 +544,19 @@ static void btree_update_nodes_written(struct btree_update *as)
        unsigned i;
        int ret;
 
+       /*
+        * If we're already in an error state, it might be because a btree node
+        * was never written, and we might be trying to free that same btree
+        * node here, but it won't have been marked as allocated and we'll see
+        * spurious disk usage inconsistencies in the transactional part below
+        * if we don't skip it:
+        */
+       ret = bch2_journal_error(&c->journal);
+       if (ret)
+               goto err;
+
+       BUG_ON(!journal_pin_active(&as->journal));
+
        /*
         * We did an update to a parent node where the pointers we added pointed
         * to child nodes that weren't written yet: now, the child nodes have
@@ -567,8 +580,10 @@ static void btree_update_nodes_written(struct btree_update *as)
                              BTREE_INSERT_JOURNAL_RESERVED,
                              btree_update_nodes_written_trans(&trans, as));
        bch2_trans_exit(&trans);
-       BUG_ON(ret && !bch2_journal_error(&c->journal));
 
+       bch2_fs_fatal_err_on(ret && !bch2_journal_error(&c->journal), c,
+                            "error %i in btree_update_nodes_written()", ret);
+err:
        if (b) {
                /*
                 * @b is the node we did the final insert into:
@@ -699,17 +714,7 @@ static void btree_update_reparent(struct btree_update *as,
        child->b = NULL;
        child->mode = BTREE_INTERIOR_UPDATING_AS;
 
-       /*
-        * When we write a new btree root, we have to drop our journal pin
-        * _before_ the new nodes are technically reachable; see
-        * btree_update_nodes_written().
-        *
-        * This goes for journal pins that are recursively blocked on us - so,
-        * just transfer the journal pin to the new interior update so
-        * btree_update_nodes_written() can drop it.
-        */
        bch2_journal_pin_copy(&c->journal, &as->journal, &child->journal, NULL);
-       bch2_journal_pin_drop(&c->journal, &child->journal);
 }
 
 static void btree_update_updated_root(struct btree_update *as, struct btree *b)
@@ -956,6 +961,10 @@ bch2_btree_update_start(struct btree_trans *trans, enum btree_id id,
        if (ret)
                goto err;
 
+       bch2_journal_pin_add(&c->journal,
+                            atomic64_read(&c->journal.seq),
+                            &as->journal, NULL);
+
        mutex_lock(&c->btree_interior_update_lock);
        list_add_tail(&as->list, &c->btree_interior_update_list);
        mutex_unlock(&c->btree_interior_update_lock);