All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sargun Dhillon <sargun@sargun.me>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 6/8] btrfs: Add code to check if a qgroup's subvol exists
Date: Sat, 20 May 2017 08:39:46 +0000	[thread overview]
Message-ID: <20170520083944.GA4244@ircssh-2.c.rugged-nimbus-611.internal> (raw)
In-Reply-To: <20170520083826.GA4176@ircssh-2.c.rugged-nimbus-611.internal>

This patch is to prepare for following patches in this patchset. The
purpose is to make it so that we can prevent accidental removal of
qgroups that are actively in use.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
---
 fs/btrfs/ioctl.c  |  4 ++--
 fs/btrfs/qgroup.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 fs/btrfs/qgroup.h |  3 ++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b10d7bb..2b1a8c1 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2554,7 +2554,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
 	 */
 	if (!btrfs_test_opt(fs_info, QGROUP_KEEP)) {
 		ret = btrfs_remove_qgroup(trans, fs_info,
-					  dest->root_key.objectid);
+					  dest->root_key.objectid, 0);
 		if (ret && ret != -ENOENT)
 			pr_info("Could not automatically delete qgroup: %d\n", ret);
 	}
@@ -4974,7 +4974,7 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
 	if (sa->create) {
 		ret = btrfs_create_qgroup(trans, fs_info, sa->qgroupid);
 	} else {
-		ret = btrfs_remove_qgroup(trans, fs_info, sa->qgroupid);
+		ret = btrfs_remove_qgroup(trans, fs_info, sa->qgroupid, 0);
 	}
 
 	err = btrfs_end_transaction(trans);
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 588248b..a0699fd 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1247,6 +1247,45 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
 	return ret;
 }
 
+/*
+ * Meant to only operate on level-0 qroupid.
+ *
+ * It returns 1 if a matching subvolume is found; 0 if none is found.
+ * < 0 if there is an error.
+ */
+static int btrfs_subvolume_exists(struct btrfs_fs_info *fs_info, u64 qgroupid)
+{
+	struct btrfs_path *path;
+	struct btrfs_key key;
+	int err, ret = 0;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	key.objectid = qgroupid;
+	key.type = BTRFS_ROOT_BACKREF_KEY;
+	key.offset = 0;
+
+	err = btrfs_search_slot_for_read(fs_info->tree_root, &key, path, 1, 0);
+	if (err == 1)
+		goto out;
+
+	if (err) {
+		ret = err;
+		goto out;
+	}
+
+	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+	if (key.objectid != qgroupid || key.type != BTRFS_ROOT_BACKREF_KEY)
+		goto out;
+
+	ret = 1;
+out:
+	btrfs_free_path(path);
+	return ret;
+}
+
 /* Must be called with qgroup_ioctl_lock held */
 static int __btrfs_create_qgroup(struct btrfs_trans_handle *trans,
 				 struct btrfs_fs_info *fs_info, u64 qgroupid)
@@ -1333,10 +1372,19 @@ static int __btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
 }
 
 int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
-			struct btrfs_fs_info *fs_info, u64 qgroupid)
+			struct btrfs_fs_info *fs_info, u64 qgroupid,
+			int check_in_use)
 {
 	int ret;
 
+	if (check_in_use && btrfs_qgroup_level(qgroupid) == 0) {
+		ret = btrfs_subvolume_exists(fs_info, qgroupid);
+		if (ret < 0)
+			return ret;
+		if (ret)
+			return -EBUSY;
+	}
+
 	mutex_lock(&fs_info->qgroup_ioctl_lock);
 	ret = __btrfs_remove_qgroup(trans, fs_info, qgroupid);
 	mutex_unlock(&fs_info->qgroup_ioctl_lock);
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index fb6c7da..fc08bdb 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -127,7 +127,8 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
 int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
 			struct btrfs_fs_info *fs_info, u64 qgroupid);
 int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
-			struct btrfs_fs_info *fs_info, u64 qgroupid);
+			struct btrfs_fs_info *fs_info, u64 qgroupid,
+			int check_in_use);
 int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
 		       struct btrfs_fs_info *fs_info, u64 qgroupid,
 		       struct btrfs_qgroup_limit *limit);
-- 
2.9.3


  parent reply	other threads:[~2017-05-20  8:39 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-20  8:38 [PATCH 0/8] BtrFS: QGroups uapi improvements Sargun Dhillon
2017-05-20  8:38 ` [PATCH 1/8] btrfs: Split up btrfs_remove_qgroup, no logic changes Sargun Dhillon
2017-05-20  8:39 ` [PATCH 2/8] btrfs: Fail on removing qgroup if del_qgroup_item fails Sargun Dhillon
2017-05-22  1:14   ` Qu Wenruo
2017-05-22  1:30     ` Sargun Dhillon
2017-05-20  8:39 ` [PATCH 3/8] btrfs: Split up btrfs_create_qgroup, no logic changes Sargun Dhillon
2017-05-20  8:39 ` [PATCH 4/8] btrfs: autoremove qgroup by default, and add a mount flag to override Sargun Dhillon
2017-05-20 19:32   ` Sargun Dhillon
2017-05-22  1:20   ` Qu Wenruo
2017-05-22  1:58     ` Sargun Dhillon
2017-05-22  2:03       ` Qu Wenruo
2017-05-22 17:31         ` Sargun Dhillon
2017-05-23  0:48           ` Qu Wenruo
2017-05-20  8:39 ` [PATCH 5/8] btrfs: qgroup.h whitespace change Sargun Dhillon
2017-05-26 19:08   ` David Sterba
2017-05-20  8:39 ` Sargun Dhillon [this message]
2017-05-22  1:39   ` [PATCH 6/8] btrfs: Add code to check if a qgroup's subvol exists Qu Wenruo
2017-05-22  3:04     ` Sargun Dhillon
2017-05-22  3:40       ` Qu Wenruo
2017-05-20  8:39 ` [PATCH 7/8] btrfs: Add code to prevent qgroup creation for a non-existent subvol Sargun Dhillon
2017-05-23  4:54   ` kbuild test robot
2017-05-23  6:27   ` kbuild test robot
2017-05-20  8:40 ` [PATCH 8/8] btrfs: Add new ioctl uapis for qgroup creation / removal Sargun Dhillon
2017-05-22  1:51   ` Qu Wenruo

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=20170520083944.GA4244@ircssh-2.c.rugged-nimbus-611.internal \
    --to=sargun@sargun.me \
    --cc=linux-btrfs@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.