]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: fix reloc root cleanup in merge_reloc_roots()
authorFilipe Manana <fdmanana@suse.com>
Fri, 12 Jun 2026 10:52:55 +0000 (11:52 +0100)
committerDavid Sterba <dsterba@suse.com>
Tue, 14 Jul 2026 05:02:13 +0000 (07:02 +0200)
If the root we got has zero root refs in its root item, we are resetting
the root's ->reloc_root without using barriers like we do everywhere else.
Sashiko complained about this while reviewing another patch, and it's
correct (see the Link tag below).

Also, we should not clear BTRFS_ROOT_DEAD_RELOC_TREE from the root unless
the root points to the reloc root we have.

Fix this by using clear_reloc_root(), which issues the memory barrier
after setting the root's ->reloc_root to NULL and before clearing the bit
BTRFS_ROOT_DEAD_RELOC_TREE from the root.

Link: https://sashiko.dev/#/patchset/cf84f1a217c719e25b6b69e4298dd7afd36c9427.1781194426.git.fdmanana%40suse.com
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/relocation.c

index a8d0acb0ad35fb40f0ae30d90d7ae20b184979b1..75bf2e5fcb6ed9869a78b52f6bf733d6b42b4093 100644 (file)
@@ -1948,11 +1948,10 @@ again:
                } else {
                        if (!IS_ERR(root)) {
                                if (root->reloc_root == reloc_root) {
-                                       root->reloc_root = NULL;
+                                       clear_reloc_root(root);
+                                       /* Drop the ref for root->reloc_root. */
                                        btrfs_put_root(reloc_root);
                                }
-                               clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE,
-                                         &root->state);
                                btrfs_put_root(root);
                        }