]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - fs/btrfs/relocation.c
btrfs: reloc: fix reloc root leak and NULL pointer dereference
[mirror_ubuntu-hirsute-kernel.git] / fs / btrfs / relocation.c
index 58f56e01de0d80285a6e11b1d91263a19cf5b736..81b076e4614356f7b264340e0e3a37dad96b7e4a 100644 (file)
@@ -1917,12 +1917,10 @@ again:
                reloc_root = list_entry(reloc_roots.next,
                                        struct btrfs_root, root_list);
 
+               root = read_fs_root(fs_info, reloc_root->root_key.offset);
                if (btrfs_root_refs(&reloc_root->root_item) > 0) {
-                       root = read_fs_root(fs_info,
-                                           reloc_root->root_key.offset);
                        BUG_ON(IS_ERR(root));
                        BUG_ON(root->reloc_root != reloc_root);
-
                        ret = merge_reloc_root(rc, root);
                        btrfs_put_root(root);
                        if (ret) {
@@ -1932,6 +1930,14 @@ again:
                                goto out;
                        }
                } else {
+                       if (!IS_ERR(root)) {
+                               if (root->reloc_root == reloc_root) {
+                                       root->reloc_root = NULL;
+                                       btrfs_put_root(reloc_root);
+                               }
+                               btrfs_put_root(root);
+                       }
+
                        list_del_init(&reloc_root->root_list);
                        /* Don't forget to queue this reloc root for cleanup */
                        list_add_tail(&reloc_root->reloc_dirty_list,