From patchwork Sat May 20 08:40:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sargun Dhillon X-Patchwork-Id: 9738535 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 768716034C for ; Sat, 20 May 2017 08:40:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6BA6F285C8 for ; Sat, 20 May 2017 08:40:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 60890285D4; Sat, 20 May 2017 08:40:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA2A5285C8 for ; Sat, 20 May 2017 08:40:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755785AbdETIkK (ORCPT ); Sat, 20 May 2017 04:40:10 -0400 Received: from mail-io0-f180.google.com ([209.85.223.180]:32810 "EHLO mail-io0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755765AbdETIkJ (ORCPT ); Sat, 20 May 2017 04:40:09 -0400 Received: by mail-io0-f180.google.com with SMTP id p24so59135052ioi.0 for ; Sat, 20 May 2017 01:40:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sargun.me; s=google; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=DON2aV/9+S5Rfz9f8y/05VlZU4eM5c4AhrZxv4TGy24=; b=vK7vBdfsLbLJXAIYWIvqJ5xyN4WHJ2DNI//DEuv2vm+kMyTTd/vU1gpjQDMOfPWKP8 +HfeZ5juYbJbPan90/QhBrRr9OK/gbO7InmpN4izETWXQsgKC/0uxn7HV2Qxt2hefceT sEde3NjNK2iE2HCdUBar574Jhgg8IpwZkeSX4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=DON2aV/9+S5Rfz9f8y/05VlZU4eM5c4AhrZxv4TGy24=; b=ApsJZLAJGKOKslvoafHBdZTu10F6rM2SPnzpCFWQctzjdZ9JVf4v3hSPPF4m69Wjc5 Zu4WlDE1kIiLYkALKfSZcxszovv4uUcxpVJViHLrTtn1D3u+yvxLW4gjqKxGsNsqxKnr jWxKMSZwfDkBkshjyjgEyGvWGSj/fataQFJ00HQlthGm9jDMFVz1ZrLnRlWy6iN9vwHz ts5rwgxCXTHBF3MF3ksjMYZqnx7ps4AYrTBkXZEv1Mfpu2WkWnn9MuCDCxJvdypXA1CI KrqQ08JWYVfesWjPcNG6No6j+NowZGWUnwwAqytFiS7K23GyL4OCZ2+CFDkRChHzXhwt eJqg== X-Gm-Message-State: AODbwcBbJ/87nf4SW524cdOVPVhibfcwgYCGEY7zyfbQbTSbWLqSjegZ tdJJELkVsu12cIkXfzCyYg== X-Received: by 10.107.7.196 with SMTP id g65mr13117549ioi.34.1495269608167; Sat, 20 May 2017 01:40:08 -0700 (PDT) Received: from ircssh-2.c.rugged-nimbus-611.internal (80.60.198.104.bc.googleusercontent.com. [104.198.60.80]) by smtp.gmail.com with ESMTPSA id b72sm5209502itd.31.2017.05.20.01.40.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 20 May 2017 01:40:08 -0700 (PDT) Date: Sat, 20 May 2017 08:40:06 +0000 From: Sargun Dhillon To: linux-btrfs@vger.kernel.org Subject: [PATCH 8/8] btrfs: Add new ioctl uapis for qgroup creation / removal Message-ID: <20170520084005.GA4262@ircssh-2.c.rugged-nimbus-611.internal> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch ties together the work in the previous patches, to introduce semantics around the qgroup creation / removal API that are a bit more intuitive that the current one. It also creates two new args structures which have reserved space for future expansion, as opposed to single datastructure for both creation and removal. The associated semantics are as follows: 1) You cannot create a level 0 qgroup for a subvol which does not exist unless you pass in an override flag. 2) You cannot delete a level 0 qgroup which refers to a subvolume, which currently exists unless you pass in an override flag. Signed-off-by: Sargun Dhillon --- fs/btrfs/ioctl.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/btrfs.h | 23 +++++++++++ 2 files changed, 121 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 5e20643..7bf34b7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4936,6 +4936,100 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) return ret; } +static long btrfs_ioctl_qgroup_create_v2(struct file *file, void __user *arg) +{ + struct btrfs_ioctl_qgroup_create_args_v2 create_args; + struct inode *inode = file_inode(file); + struct btrfs_trans_handle *trans; + struct btrfs_fs_info *fs_info; + struct btrfs_root *root; + int check_subvol_exists; + int ret, err; + + fs_info = btrfs_sb(inode->i_sb); + root = BTRFS_I(inode)->root; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + ret = copy_from_user(&create_args, arg, sizeof(create_args)); + if (ret) + return ret; + + if (!create_args.qgroupid) + return -EINVAL; + + ret = mnt_want_write_file(file); + if (ret) + return ret; + + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out; + } + + check_subvol_exists = !(create_args.flags & + BTRFS_QGROUP_CREATE_IGNORE_UNUSED); + ret = btrfs_create_qgroup(trans, fs_info, create_args.qgroupid, + check_subvol_exists); + + err = btrfs_end_transaction(trans); + if (err && !ret) + ret = err; + +out: + mnt_drop_write_file(file); + return ret; +} + +static long btrfs_ioctl_qgroup_remove_v2(struct file *file, void __user *arg) +{ + struct btrfs_ioctl_qgroup_remove_args_v2 remove_args; + struct inode *inode = file_inode(file); + struct btrfs_trans_handle *trans; + struct btrfs_fs_info *fs_info; + struct btrfs_root *root; + int check_in_use; + int ret, err; + + fs_info = btrfs_sb(inode->i_sb); + root = BTRFS_I(inode)->root; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + ret = copy_from_user(&remove_args, arg, sizeof(remove_args)); + if (ret) + return ret; + + if (!remove_args.qgroupid) + return -EINVAL; + + ret = mnt_want_write_file(file); + if (ret) + return ret; + + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out; + } + + check_in_use = !(remove_args.flags & + BTRFS_QGROUP_REMOVE_NO_CHECK_IN_USE); + ret = btrfs_remove_qgroup(trans, fs_info, remove_args.qgroupid, + check_in_use); + + err = btrfs_end_transaction(trans); + if (err && !ret) + ret = err; + +out: + mnt_drop_write_file(file); + return ret; +} + static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); @@ -5626,6 +5720,10 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_qgroup_assign(file, argp); case BTRFS_IOC_QGROUP_CREATE: return btrfs_ioctl_qgroup_create(file, argp); + case BTRFS_IOC_QGROUP_CREATE_V2: + return btrfs_ioctl_qgroup_create_v2(file, argp); + case BTRFS_IOC_QGROUP_REMOVE_V2: + return btrfs_ioctl_qgroup_remove_v2(file, argp); case BTRFS_IOC_QGROUP_LIMIT: return btrfs_ioctl_qgroup_limit(file, argp); case BTRFS_IOC_QUOTA_RESCAN: diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index a456e53..0a6652d 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h @@ -653,6 +653,25 @@ struct btrfs_ioctl_qgroup_create_args { __u64 create; __u64 qgroupid; }; + +/* Allow the user to delete qgroups even if there isn't a subvol with the id */ +#define BTRFS_QGROUP_CREATE_IGNORE_UNUSED (1ULL << 0) + +struct btrfs_ioctl_qgroup_create_args_v2 { + __u64 qgroupid; + __u64 flags; + __u64 reserved[16]; +}; + +/* Allow the user to delete qgroups even if they are referenced by a subvol */ +#define BTRFS_QGROUP_REMOVE_NO_CHECK_IN_USE (1ULL << 0) + +struct btrfs_ioctl_qgroup_remove_args_v2 { + __u64 qgroupid; + __u64 flags; + __u64 reserved[16]; +}; + struct btrfs_ioctl_timespec { __u64 sec; __u32 nsec; @@ -818,5 +837,9 @@ enum btrfs_err_code { struct btrfs_ioctl_feature_flags[3]) #define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, \ struct btrfs_ioctl_vol_args_v2) +#define BTRFS_IOC_QGROUP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 59, \ + struct btrfs_ioctl_qgroup_create_args_v2) +#define BTRFS_IOC_QGROUP_REMOVE_V2 _IOW(BTRFS_IOCTL_MAGIC, 60, \ + struct btrfs_ioctl_qgroup_remove_args_v2) #endif /* _UAPI_LINUX_BTRFS_H */