Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp4689561ybl; Mon, 13 Jan 2020 18:44:37 -0800 (PST) X-Google-Smtp-Source: APXvYqyIP2noehwHi6ocgHZZa/10xj3Mkl8d2VRWapcj747102MchqaaAIcBQ95IivyFgPdEZMd7 X-Received: by 2002:a05:6808:150:: with SMTP id h16mr14439704oie.130.1578969877326; Mon, 13 Jan 2020 18:44:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578969877; cv=none; d=google.com; s=arc-20160816; b=EE8G4ZuJrity8zmKw4YPRsxqruvtRfEUvP4zwHGFryyvhduVS6w6wKJgbx5g2AH7OP Jb0g/8AXw4KMP5hT74OFigzFq+q82jXS8IaJUjSypSCBLWC2fvt6mGplfNu7Nnw17SBL 8EdvInnUXCWVr0FyfOIkj7UCbCRWMPIUt+t3DZxFqMM+ws+EujH0oP/g+2l+XP40ZK/M ysH4OcAWnDv5YB06H+1peqguLamfC84iidRaAENygKAg36vb2k8ssbWLNf3+EBi5rNtk IQBqULprk1DaMpHU+RwIZJI8UiJ232xucngnKhSZFeI+WGhMxR8Bce7etlK7QzjE8L5J trcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:date:cc:to:from:subject :message-id; bh=wphWdlpEP6qC8H8ri+6QSogegdG+HqMUkfUnxP/NHsU=; b=0OQOq61YLoCGpQgZR42nbDwzgztNELv9+a99cm+5XRxA99pgxsId8DGLuWJGi4oXw0 HeSk2VweBrHbdgqLxRHZHkIF/+BwKlQN086VQMfiMMD8ewaNtsjZhfzY5NMSWRLyD+Th 54atqKRBFFBIfzbmdIYhLOw73+fRmpvhhnTdWeU5vYirAd2Tx160rLb9hG8lcpJ+MBLc i5FU6gmL06oEqFsVwRnkJEiESh9S4F8uAvoVp7dsgo3LwB9YpWOEDHUpimm6xf2BEUpE ZY3dKO4pv0B2ox7ZyEO6p5yOz79ZdOS/R7LM0BsAYcLoGvsr+2XhWZn8ZTaI9YR59zRN me0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c17si7907359otp.131.2020.01.13.18.44.25; Mon, 13 Jan 2020 18:44:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729525AbgANC3C (ORCPT + 99 others); Mon, 13 Jan 2020 21:29:02 -0500 Received: from mx2.suse.de ([195.135.220.15]:52130 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729099AbgANC3C (ORCPT ); Mon, 13 Jan 2020 21:29:02 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 1527FAC68; Tue, 14 Jan 2020 02:29:00 +0000 (UTC) Message-ID: <20b606bcb0efb2defb5ef79cafc6d5b471e9cf28.camel@suse.de> Subject: Re: [PATCH 2/2] btrfs: Introduce new BTRFS_IOC_SNAP_DESTROY_V2 ioctl From: Marcos Paulo de Souza To: Josef Bacik , Marcos Paulo de Souza , linux-kernel@vger.kernel.org Cc: dsterba@suse.com, linux-btrfs@vger.kernel.org, Marcos Paulo de Souza , wqu@suse.com, Chris Mason Date: Mon, 13 Jan 2020 23:31:45 -0300 In-Reply-To: <18611492-2f20-4c09-1208-c39251a54200@toxicpanda.com> References: <20200111043942.15366-1-marcos.souza.org@gmail.com> <20200111043942.15366-3-marcos.souza.org@gmail.com> <18611492-2f20-4c09-1208-c39251a54200@toxicpanda.com> Content-Type: text/plain; charset="UTF-8" User-Agent: Evolution 3.34.2 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 2020-01-13 at 09:37 -0800, Josef Bacik wrote: > On 1/10/20 8:39 PM, Marcos Paulo de Souza wrote: > > From: Marcos Paulo de Souza > > > > This ioctl will be responsible for deleting a subvolume using it's > id. > > This can be used when a system has a file system mounted from a > > subvolume, rather than the root file system, like below: > > > > / > > |- @subvol1 > > |- @subvol2 > > \- @subvol_default > > If only @subvol_default is mounted, we have no path to reach > > @subvol1 and @subvol2, thus no way to delete them. > > This patch introduces a new flag to allow BTRFS_IOC_SNAP_DESTORY_V2 > > to delete subvolume using subvolid. > > > > Also in this patch, add BTRFS_SUBVOL_DELETE_BY_ID flag and add > subvolid > > as a union member of fd in struct btrfs_ioctl_vol_args_v2. > > > > Signed-off-by: Marcos Paulo de Souza > > --- > > fs/btrfs/ctree.h | 8 ++++++ > > fs/btrfs/export.c | 4 +-- > > fs/btrfs/ioctl.c | 53 > ++++++++++++++++++++++++++++++++++++++ > > fs/btrfs/super.c | 2 +- > > include/uapi/linux/btrfs.h | 12 +++++++-- > > 5 files changed, 74 insertions(+), 5 deletions(-) > > > > diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h > > index 569931dd0ce5..421a2f57f9ec 100644 > > --- a/fs/btrfs/ctree.h > > +++ b/fs/btrfs/ctree.h > > @@ -3010,6 +3010,8 @@ int btrfs_defrag_leaves(struct > btrfs_trans_handle *trans, > > int btrfs_parse_options(struct btrfs_fs_info *info, char > *options, > > unsigned long new_flags); > > int btrfs_sync_fs(struct super_block *sb, int wait); > > +char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, > > + u64 subvol_objectid); > > > > static inline __printf(2, 3) __cold > > void btrfs_no_printk(const struct btrfs_fs_info *fs_info, const > char *fmt, ...) > > @@ -3442,6 +3444,12 @@ int btrfs_reada_wait(void *handle); > > void btrfs_reada_detach(void *handle); > > int btree_readahead_hook(struct extent_buffer *eb, int err); > > > > +/* export.c */ > > +struct dentry *btrfs_get_dentry(struct super_block *sb, u64 > objectid, > > + u64 root_objectid, u32 > generation, > > + int check_generation); > > +struct dentry *btrfs_get_parent(struct dentry *child); > > + > > static inline int is_fstree(u64 rootid) > > { > > if (rootid == BTRFS_FS_TREE_OBJECTID || > > diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c > > index 72e312cae69d..027411cdbae7 100644 > > --- a/fs/btrfs/export.c > > +++ b/fs/btrfs/export.c > > @@ -57,7 +57,7 @@ static int btrfs_encode_fh(struct inode *inode, > u32 *fh, int *max_len, > > return type; > > } > > > > -static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 > objectid, > > +struct dentry *btrfs_get_dentry(struct super_block *sb, u64 > objectid, > > u64 root_objectid, u32 > generation, > > int check_generation) > > { > > @@ -152,7 +152,7 @@ static struct dentry *btrfs_fh_to_dentry(struct > super_block *sb, struct fid *fh, > > return btrfs_get_dentry(sb, objectid, root_objectid, > generation, 1); > > } > > > > -static struct dentry *btrfs_get_parent(struct dentry *child) > > +struct dentry *btrfs_get_parent(struct dentry *child) > > { > > struct inode *dir = d_inode(child); > > struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); > > diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c > > index dcceae4c5d28..68da45ad4904 100644 > > --- a/fs/btrfs/ioctl.c > > +++ b/fs/btrfs/ioctl.c > > @@ -2960,6 +2960,57 @@ static noinline int > btrfs_ioctl_snap_destroy(struct file *file, > > return err; > > } > > > > +static noinline int btrfs_ioctl_snap_destroy_v2(struct file *file, > > + void __user *arg) > > +{ > > + struct btrfs_fs_info *fs_info = btrfs_sb(file->f_path.dentry- > >d_sb); > > + struct dentry *dentry, *pdentry; > > + struct btrfs_ioctl_vol_args_v2 *vol_args; > > + char *name, *p; > > + size_t namelen; > > + int err = 0; > > + > > + vol_args = memdup_user(arg, sizeof(*vol_args)); > > + if (IS_ERR(vol_args)) > > + return PTR_ERR(vol_args); > > + > > + if (vol_args->subvolid == 0) > > + return -EINVAL; > > + > > + if (!(vol_args->flags & BTRFS_SUBVOL_DELETE_BY_ID)) > > + return -EINVAL; > > + > > + dentry = btrfs_get_dentry(fs_info->sb, > BTRFS_FIRST_FREE_OBJECTID, > > + vol_args->subvolid, 0, 0); > > + if (IS_ERR(dentry)) { > > + err = PTR_ERR(dentry); > > + return err; > > + } > > + > > + pdentry = btrfs_get_parent(dentry); > > + if (IS_ERR(pdentry)) { > > + err = PTR_ERR(pdentry); > > + goto out_dentry; > > + } > > What happens if we have something like > > /subvol > /subvol2 > /subvol3/subvol4 > /subvol5 > > and we mount /subvol5, and then we try to delete subvol4? We aren't > going to be > able to find the parent dentry for subvol3 right? Cause that thing > isn't linked > into our currently mounted tree, and things will go wonky right? I'm > only > working on like 4 hours of sleep so I could be missing something > obvious here. It works because we don't account the dentry based in the filp pointer, but rather we go through the fs tree by the subvolid and get the dentry from there. Using that dentry we then access the tree again to grab the parent. Am I missing something? It worked in my tests :) > > > + > > + name = get_subvol_name_from_objectid(fs_info, vol_args- > >subvolid); > > + if (IS_ERR(name)) { > > + err = PTR_ERR(name); > > + goto out_pdentry; > > + } > > + p = (char *)kbasename(name); > > + namelen = strlen(p); > > + > > + err = btrfs_subvolume_deleter(file, pdentry, p, namelen); > > We looked up the dentry to send the name into > btrfs_subvolume_deleter(), which > just takes the name and looks up the dentry again? Have the common > function > just take both dentries and have v1 and v2 do their lookup > shenanigans. Thanks, So, this part is only necessary in the deletion by subvolid, since we cannot trust the file pointer of the current subvol delete ioctl because of the possible differented mounted tree, but I think it's doable to have the same function and only check for the SUBVOL_DELETE flag and the subvolid vol_args_v2 member. > > Josef