On Fri, Jan 24, 2020 at 09:32:48AM -0500, Josef Bacik wrote:
> --- a/fs/btrfs/send.c
> +++ b/fs/btrfs/send.c
> @@ -7200,11 +7200,17 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
> 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);
> srcu_read_unlock(&fs_info->subvol_srcu, index);
> + btrfs_put_fs_root(clone_root);
Here and
> ret = -EPERM;
> goto out;
> }
> @@ -7212,6 +7218,7 @@ long btrfs_ioctl_send(struct file *mnt_file, struct btrfs_ioctl_send_args *arg)
> dedupe_in_progress_warn(clone_root);
> spin_unlock(&clone_root->root_item_lock);
> srcu_read_unlock(&fs_info->subvol_srcu, index);
> + btrfs_put_fs_root(clone_root);
here, the order is srcu, put ref. As it's on error handling path anyway
it's no big deal, but I'd rather swap them so the nesting is proper,
tree refs inside srcu section.