Skip to contentSkip to conversation

Btrfs: prevent qgroup config corruption by qgroup destroy

PATCH New Arne Jansen 1 participant 3 messages Jan 17, 2013 Btrfs file system

lore
Share & tools
lore
#0 lore raw

cover Btrfs: prevent qgroup config corruption by qgroup destroy

When destroying an active qgroup with qgroup destroy, the internal config will become corrupt. This series adds 2 fixes: the first add a recovery, if the config is already corrupt, and the second prevents the destroy if it is still active.

Arne Jansen (2):
btrfs: ignore orphan qgroup relations
btrfs: prevent qgroup destroy when there are still relations

 fs/btrfs/qgroup.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)
Signature · 1 line
1.7.3.4
#1 lore raw

PATCH 1/2 Btrfs: ignore orphan qgroup relations

If a qgroup that has still assignments is deleted by the user, the corresponding relations are left in the tree. This leads to an unmountable filesystem. With this patch, those relations are simple ignored.

---
 fs/btrfs/qgroup.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
fs/btrfs/qgroup.c +7 -0
index fe9d02c..28f2b39 100644
@@ -379,6 +379,13 @@ next1:
 
 		ret = add_relation_rb(fs_info, found_key.objectid,
 				      found_key.offset);
+		if (ret == -ENOENT) {
+			printk(KERN_WARNING
+				"btrfs: orphan qgroup relation 0x%llx->0x%llx\n",
+				(unsigned long long)found_key.objectid,
+				(unsigned long long)found_key.offset);
+			ret = 0;	/* ignore the error */
+		}
 		if (ret)
 			goto out;
 next2:
Signature · 1 line
1.7.3.4
#2 lore raw

PATCH 2/2 Btrfs: prevent qgroup destroy when there are still relations

In reply to Arne Jansen

Currently you can just destroy a qgroup even though it is in use by other qgroups or has qgroups assigned to it. This patch prevents destruction of qgroups unless they are completely unused. Otherwise destroy will return EBUSY.

---
 fs/btrfs/qgroup.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)
fs/btrfs/qgroup.c +12 -1
index 28f2b39..a5c8562 100644
@@ -963,17 +963,28 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
 			struct btrfs_fs_info *fs_info, u64 qgroupid)
 {
 	struct btrfs_root *quota_root;
+	struct btrfs_qgroup *qgroup;
 	int ret = 0;
 
 	quota_root = fs_info->quota_root;
 	if (!quota_root)
 		return -EINVAL;
 
+	/* check if there are no relations to this qgroup */
+	spin_lock(&fs_info->qgroup_lock);
+	qgroup = find_qgroup_rb(fs_info, qgroupid);
+	if (qgroup) {
+		if (!list_empty(&qgroup->groups) || !list_empty(&qgroup->members)) {
+			spin_unlock(&fs_info->qgroup_lock);
+			return -EBUSY;
+		}
+	}
+	spin_unlock(&fs_info->qgroup_lock);
+
 	ret = del_qgroup_item(trans, quota_root, qgroupid);
 
 	spin_lock(&fs_info->qgroup_lock);
 	del_qgroup_rb(quota_root->fs_info, qgroupid);
-
 	spin_unlock(&fs_info->qgroup_lock);
 
 	return ret;
Signature · 1 line
1.7.3.4