err = ret;
                                        goto out;
                                }
+                       } else {
+                               if (!btrfs_grab_fs_root(fs_root)) {
+                                       err = -ENOENT;
+                                       goto out;
+                               }
+                               btrfs_put_fs_root(fs_root);
                        }
                }
 
                        list_add_tail(&reloc_root->root_list, &reloc_roots);
                        goto out_free;
                }
+               if (!btrfs_grab_fs_root(fs_root)) {
+                       err = -ENOENT;
+                       goto out_free;
+               }
 
                err = __add_reloc_root(reloc_root);
                BUG_ON(err < 0); /* -ENOMEM or logic error */
                fs_root->reloc_root = reloc_root;
+               btrfs_put_fs_root(fs_root);
        }
 
        err = btrfs_commit_transaction(trans);
        if (err == 0) {
                /* cleanup orphan inode in data relocation tree */
                fs_root = read_fs_root(fs_info, BTRFS_DATA_RELOC_TREE_OBJECTID);
-               if (IS_ERR(fs_root))
+               if (IS_ERR(fs_root)) {
                        err = PTR_ERR(fs_root);
-               else
-                       err = btrfs_orphan_cleanup(fs_root);
+               } else {
+                       if (btrfs_grab_fs_root(fs_root)) {
+                               err = btrfs_orphan_cleanup(fs_root);
+                               btrfs_put_fs_root(fs_root);
+                       }
+               }
        }
        return err;
 }