ret = PTR_ERR(clone_root);
                                goto out;
                        }
+                       if (!btrfs_grab_fs_root(clone_root)) {
+                               srcu_read_unlock(&fs_info->subvol_srcu, index);
+                               ret = -ENOENT;
+                               goto out;
+                       }
                        spin_lock(&clone_root->root_item_lock);
                        if (!btrfs_root_readonly(clone_root) ||
                            btrfs_root_dead(clone_root)) {
                                spin_unlock(&clone_root->root_item_lock);
+                               btrfs_put_fs_root(clone_root);
                                srcu_read_unlock(&fs_info->subvol_srcu, index);
                                ret = -EPERM;
                                goto out;
                        if (clone_root->dedupe_in_progress) {
                                dedupe_in_progress_warn(clone_root);
                                spin_unlock(&clone_root->root_item_lock);
+                               btrfs_put_fs_root(clone_root);
                                srcu_read_unlock(&fs_info->subvol_srcu, index);
                                ret = -EAGAIN;
                                goto out;
                        ret = PTR_ERR(sctx->parent_root);
                        goto out;
                }
+               if (!btrfs_grab_fs_root(sctx->parent_root)) {
+                       srcu_read_unlock(&fs_info->subvol_srcu, index);
+                       ret = -ENOENT;
+                       sctx->parent_root = ERR_PTR(ret);
+                       goto out;
+               }
 
                spin_lock(&sctx->parent_root->root_item_lock);
                sctx->parent_root->send_in_progress++;
         * is behind the current send position. This is checked while searching
         * for possible clone sources.
         */
-       sctx->clone_roots[sctx->clone_roots_cnt++].root = sctx->send_root;
+       sctx->clone_roots[sctx->clone_roots_cnt++].root =
+               btrfs_grab_fs_root(sctx->send_root);
 
        /* We do a bsearch later */
        sort(sctx->clone_roots, sctx->clone_roots_cnt,
        }
 
        if (sort_clone_roots) {
-               for (i = 0; i < sctx->clone_roots_cnt; i++)
+               for (i = 0; i < sctx->clone_roots_cnt; i++) {
                        btrfs_root_dec_send_in_progress(
                                        sctx->clone_roots[i].root);
+                       btrfs_put_fs_root(sctx->clone_roots[i].root);
+               }
        } else {
-               for (i = 0; sctx && i < clone_sources_to_rollback; i++)
+               for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
                        btrfs_root_dec_send_in_progress(
                                        sctx->clone_roots[i].root);
+                       btrfs_put_fs_root(sctx->clone_roots[i].root);
+               }
 
                btrfs_root_dec_send_in_progress(send_root);
        }
-       if (sctx && !IS_ERR_OR_NULL(sctx->parent_root))
+       if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
                btrfs_root_dec_send_in_progress(sctx->parent_root);
+               btrfs_put_fs_root(sctx->parent_root);
+       }
 
        kvfree(clone_sources_tmp);