From: Marcos Paulo de Souza <mpdesouza@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: dsterba@suse.com, wqu@suse.com,
Marcos Paulo de Souza <mpdesouza@suse.com>
Subject: [PATCH] btrfs: Add new flag to rescan quota after subvolume creation
Date: Fri, 21 May 2021 11:38:11 -0300 [thread overview]
Message-ID: <20210521143811.16227-1-mpdesouza@suse.com> (raw)
Adding a new subvolume/snapshot makes the qgroup data inconsistent, so
add a new flag to inform the subvolume ioctl to do a quota rescan right
after the subvolume/snapshot creation.
Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
---
This is an attempt to help snapper to create snapshots with 'timeline'
cleanup-policy to keep the qgroup data consistent after a new snapshot is
created.
Please let me know if you know a better place to add this functionality.
fs/btrfs/ioctl.c | 58 +++++++++++++++++++++++++++++---------
include/uapi/linux/btrfs.h | 8 ++++--
2 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 5dc2fd843ae3..64b4aa744486 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1704,6 +1704,22 @@ static noinline int btrfs_ioctl_resize(struct file *file,
return ret;
}
+static long do_quota_rescan(struct file *file)
+{
+ struct inode *inode = file_inode(file);
+ struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+ int ret;
+
+ ret = mnt_want_write_file(file);
+ if (ret)
+ return ret;
+
+ ret = btrfs_qgroup_rescan(fs_info);
+
+ mnt_drop_write_file(file);
+ return ret;
+}
+
static noinline int __btrfs_ioctl_snap_create(struct file *file,
const char *name, unsigned long fd, int subvol,
bool readonly,
@@ -1793,6 +1809,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
struct btrfs_ioctl_vol_args_v2 *vol_args;
int ret;
bool readonly = false;
+ bool quota_rescan = false;
struct btrfs_qgroup_inherit *inherit = NULL;
if (!S_ISDIR(file_inode(file)->i_mode))
@@ -1808,6 +1825,15 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
goto free_args;
}
+ if (vol_args->flags & BTRFS_SUBVOL_QGROUP_RESCAN) {
+ if (!capable(CAP_SYS_ADMIN)) {
+ ret = -EPERM;
+ goto free_args;
+ }
+
+ quota_rescan = true;
+ }
+
if (vol_args->flags & BTRFS_SUBVOL_RDONLY)
readonly = true;
if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
@@ -1843,6 +1869,22 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
subvol, readonly, inherit);
if (ret)
goto free_inherit;
+
+ if (quota_rescan) {
+ ret = do_quota_rescan(file);
+ /*
+ * EINVAL is returned if quota is not enabled. There is already
+ * a warning issued if quota rescan is started when quota is not
+ * enabled, so skip a warning here if it is the case.
+ */
+ if (ret < 0 && ret != -EINVAL)
+ btrfs_warn(btrfs_sb(file_inode(file)->i_sb),
+ "Couldn't execute quota rescan after snapshot creation: %d",
+ ret);
+ else
+ ret = 0;
+ }
+
free_inherit:
kfree(inherit);
free_args:
@@ -4277,35 +4319,25 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg)
static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg)
{
- struct inode *inode = file_inode(file);
- struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
struct btrfs_ioctl_quota_rescan_args *qsa;
int ret;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- ret = mnt_want_write_file(file);
- if (ret)
- return ret;
-
qsa = memdup_user(arg, sizeof(*qsa));
- if (IS_ERR(qsa)) {
- ret = PTR_ERR(qsa);
- goto drop_write;
- }
+ if (IS_ERR(qsa))
+ return PTR_ERR(qsa);
if (qsa->flags) {
ret = -EINVAL;
goto out;
}
- ret = btrfs_qgroup_rescan(fs_info);
+ ret = do_quota_rescan(file);
out:
kfree(qsa);
-drop_write:
- mnt_drop_write_file(file);
return ret;
}
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 5df73001aad4..8779aa4b3aad 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -47,11 +47,14 @@ struct btrfs_ioctl_vol_args {
#define BTRFS_SUBVOL_SPEC_BY_ID (1ULL << 4)
+#define BTRFS_SUBVOL_QGROUP_RESCAN (1ULL << 5)
+
#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED \
(BTRFS_SUBVOL_RDONLY | \
BTRFS_SUBVOL_QGROUP_INHERIT | \
BTRFS_DEVICE_SPEC_BY_ID | \
- BTRFS_SUBVOL_SPEC_BY_ID)
+ BTRFS_SUBVOL_SPEC_BY_ID | \
+ BTRFS_SUBVOL_QGROUP_RESCAN)
#define BTRFS_FSID_SIZE 16
#define BTRFS_UUID_SIZE 16
@@ -119,7 +122,8 @@ struct btrfs_ioctl_qgroup_limit_args {
/* Supported flags for BTRFS_IOC_SNAP_CREATE_V2 and BTRFS_IOC_SUBVOL_CREATE_V2 */
#define BTRFS_SUBVOL_CREATE_ARGS_MASK \
(BTRFS_SUBVOL_RDONLY | \
- BTRFS_SUBVOL_QGROUP_INHERIT)
+ BTRFS_SUBVOL_QGROUP_INHERIT | \
+ BTRFS_SUBVOL_QGROUP_RESCAN)
/* Supported flags for BTRFS_IOC_SNAP_DESTROY_V2 */
#define BTRFS_SUBVOL_DELETE_ARGS_MASK \
--
2.26.2
next reply other threads:[~2021-05-21 14:38 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-21 14:38 Marcos Paulo de Souza [this message]
2021-05-25 16:20 ` [PATCH] btrfs: Add new flag to rescan quota after subvolume creation David Sterba
2021-06-09 17:44 ` Marcos Paulo de Souza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210521143811.16227-1-mpdesouza@suse.com \
--to=mpdesouza@suse.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=wqu@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).