Merge branch 'nvme-5.2-rc-next' of git://git.infradead.org/nvme into for-linus
[sfrench/cifs-2.6.git] / fs / btrfs / relocation.c
index a459ecddcce4e62d61b0758580156e0820fef559..22a3c69864fac6fb4d771c67d41da6a6e19e8a5c 100644 (file)
@@ -2177,22 +2177,30 @@ static int clean_dirty_subvols(struct reloc_control *rc)
        struct btrfs_root *root;
        struct btrfs_root *next;
        int ret = 0;
+       int ret2;
 
        list_for_each_entry_safe(root, next, &rc->dirty_subvol_roots,
                                 reloc_dirty_list) {
-               struct btrfs_root *reloc_root = root->reloc_root;
+               if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
+                       /* Merged subvolume, cleanup its reloc root */
+                       struct btrfs_root *reloc_root = root->reloc_root;
 
-               clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
-               list_del_init(&root->reloc_dirty_list);
-               root->reloc_root = NULL;
-               if (reloc_root) {
-                       int ret2;
+                       clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
+                       list_del_init(&root->reloc_dirty_list);
+                       root->reloc_root = NULL;
+                       if (reloc_root) {
 
-                       ret2 = btrfs_drop_snapshot(reloc_root, NULL, 0, 1);
+                               ret2 = btrfs_drop_snapshot(reloc_root, NULL, 0, 1);
+                               if (ret2 < 0 && !ret)
+                                       ret = ret2;
+                       }
+                       btrfs_put_fs_root(root);
+               } else {
+                       /* Orphan reloc tree, just clean it up */
+                       ret2 = btrfs_drop_snapshot(root, NULL, 0, 1);
                        if (ret2 < 0 && !ret)
                                ret = ret2;
                }
-               btrfs_put_fs_root(root);
        }
        return ret;
 }
@@ -2480,6 +2488,9 @@ again:
                        }
                } else {
                        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,
+                                     &rc->dirty_subvol_roots);
                }
        }