]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: remove the changed list for backref cache
authorJosef Bacik <josef@toxicpanda.com>
Thu, 3 Oct 2024 15:43:04 +0000 (11:43 -0400)
committerDavid Sterba <dsterba@suse.com>
Mon, 13 Jan 2025 13:53:14 +0000 (14:53 +0100)
Now that we're not updating the backref cache when we switch transids we
can remove the changed list.

We're going to keep the new_bytenr field because it serves as a good
sanity check for the backref cache and relocation, and can prevent us
from making extent tree corruption worse.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/backref.c
fs/btrfs/backref.h
fs/btrfs/relocation.c

index 04f53ca548e188124e6dc498b574183adf04d21f..f686f01cdd9b8b46cca38927a53a3b1c36537630 100644 (file)
@@ -3022,7 +3022,6 @@ void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
        cache->rb_root = RB_ROOT;
        for (i = 0; i < BTRFS_MAX_LEVEL; i++)
                INIT_LIST_HEAD(&cache->pending[i]);
-       INIT_LIST_HEAD(&cache->changed);
        INIT_LIST_HEAD(&cache->detached);
        INIT_LIST_HEAD(&cache->leaves);
        INIT_LIST_HEAD(&cache->pending_edge);
@@ -3190,7 +3189,6 @@ void btrfs_backref_release_cache(struct btrfs_backref_cache *cache)
        }
        ASSERT(list_empty(&cache->pending_edge));
        ASSERT(list_empty(&cache->useless_node));
-       ASSERT(list_empty(&cache->changed));
        ASSERT(list_empty(&cache->detached));
        ASSERT(RB_EMPTY_ROOT(&cache->rb_root));
        ASSERT(!cache->nr_nodes);
index e8c22cccb5c13286fc8b41190c689b0abc7e0cf7..a810253d7b8a4d1d4f22ece186691e876be068ec 100644 (file)
@@ -393,8 +393,6 @@ struct btrfs_backref_cache {
        struct list_head pending[BTRFS_MAX_LEVEL];
        /* List of backref nodes with no child node */
        struct list_head leaves;
-       /* List of blocks that have been COWed in current transaction */
-       struct list_head changed;
        /* List of detached backref node. */
        struct list_head detached;
 
index ab2de2d1b2beed3cabb15611900e2b86e78f33d4..5af1907e230b3c7d922c2cb894f9baddc1dcc172 100644 (file)
@@ -2113,14 +2113,13 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
                if (next->new_bytenr != root->node->start) {
                        /*
                         * We just created the reloc root, so we shouldn't have
-                        * ->new_bytenr set and this shouldn't be in the changed
-                        *  list.  If it is then we have multiple roots pointing
-                        *  at the same bytenr which indicates corruption, or
-                        *  we've made a mistake in the backref walking code.
+                        * ->new_bytenr set yet. If it is then we have multiple
+                        *  roots pointing at the same bytenr which indicates
+                        *  corruption, or we've made a mistake in the backref
+                        *  walking code.
                         */
                        ASSERT(next->new_bytenr == 0);
-                       ASSERT(list_empty(&next->list));
-                       if (next->new_bytenr || !list_empty(&next->list)) {
+                       if (next->new_bytenr) {
                                btrfs_err(trans->fs_info,
        "bytenr %llu possibly has multiple roots pointing at the same bytenr %llu",
                                          node->bytenr, next->bytenr);
@@ -2131,8 +2130,6 @@ struct btrfs_root *select_reloc_root(struct btrfs_trans_handle *trans,
                        btrfs_put_root(next->root);
                        next->root = btrfs_grab_root(root);
                        ASSERT(next->root);
-                       list_add_tail(&next->list,
-                                     &rc->backref_cache.changed);
                        mark_block_processed(rc, next);
                        break;
                }
@@ -2442,7 +2439,7 @@ next:
 
        if (!ret && node->pending) {
                btrfs_backref_drop_node_buffer(node);
-               list_move_tail(&node->list, &rc->backref_cache.changed);
+               list_del_init(&node->list);
                node->pending = 0;
        }
 
@@ -2605,8 +2602,7 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
                        /*
                         * This block was the root block of a root, and this is
                         * the first time we're processing the block and thus it
-                        * should not have had the ->new_bytenr modified and
-                        * should have not been included on the changed list.
+                        * should not have had the ->new_bytenr modified.
                         *
                         * However in the case of corruption we could have
                         * multiple refs pointing to the same block improperly,
@@ -2616,8 +2612,7 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
                         * normal user in the case of corruption.
                         */
                        ASSERT(node->new_bytenr == 0);
-                       ASSERT(list_empty(&node->list));
-                       if (node->new_bytenr || !list_empty(&node->list)) {
+                       if (node->new_bytenr) {
                                btrfs_err(root->fs_info,
                                  "bytenr %llu has improper references to it",
                                          node->bytenr);
@@ -2640,7 +2635,6 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
                        btrfs_put_root(node->root);
                        node->root = btrfs_grab_root(root);
                        ASSERT(node->root);
-                       list_add_tail(&node->list, &rc->backref_cache.changed);
                } else {
                        path->lowest_level = node->level;
                        if (root == root->fs_info->chunk_root)