linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] btrfs-progs: qgroup-verify: Check if qgroup limit is exceeded
@ 2018-11-13  6:47 Qu Wenruo
  0 siblings, 0 replies; only message in thread
From: Qu Wenruo @ 2018-11-13  6:47 UTC (permalink / raw)
  To: linux-btrfs

For case where we exceed qgroup limits, we should also report it as an
error.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 qgroup-verify.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/qgroup-verify.c b/qgroup-verify.c
index f5885589f02c..ab9b5f284d66 100644
--- a/qgroup-verify.c
+++ b/qgroup-verify.c
@@ -54,6 +54,11 @@ struct qgroup_info {
 	u64 exclusive_compressed;
 };
 
+struct qgroup_limit {
+	u64 max_rfer;
+	u64 max_excl;
+};
+
 struct qgroup_count {
 	u64 qgroupid;
 	int subvol_exists;
@@ -63,6 +68,8 @@ struct qgroup_count {
 
 	struct qgroup_info info;
 
+	struct qgroup_limit limit;
+
 	struct rb_node rb_node;
 
 	/* Parents when we are a child group */
@@ -926,6 +933,48 @@ static void read_qgroup_status(struct extent_buffer *eb, int slot,
 	counts->scan_progress = btrfs_qgroup_status_rescan(eb, status_item);
 }
 
+static void read_qgroup_limit(struct extent_buffer *leaf, int slot)
+{
+	struct btrfs_key key;
+	struct btrfs_qgroup_limit_item *qli;
+	struct qgroup_count *count;
+	u64 flags;
+
+	btrfs_item_key_to_cpu(leaf, &key, slot);
+	qli = btrfs_item_ptr(leaf, slot, struct btrfs_qgroup_limit_item);
+	flags = btrfs_qgroup_limit_flags(leaf, qli);
+
+	/*
+	 * Despite the deprecated LIMIT_RSV_* flags, for CMPR (compressed)
+	 * limit it doesn't really work either.
+	 * As qgroup works at extent level, all numbers are at compressed size
+	 * already.
+	 */
+	if (flags & (__BTRFS_QGROUP_LIMIT_RSV_RFER |
+		     __BTRFS_QGROUP_LIMIT_RSV_EXCL |
+		     BTRFS_QGROUP_LIMIT_RFER_CMPR |
+		     BTRFS_QGROUP_LIMIT_EXCL_CMPR)) {
+		warning("ignoring deprecated limit flags for qgroup %llu/%llu",
+			btrfs_qgroup_level(key.offset),
+			btrfs_qgroup_subvid(key.offset));
+	}
+	count = find_count(key.offset);
+	if (!count) {
+		warning(
+	"found orphan QGROUP_LIMIT item, qgroup %llu/%llu doesn't exist",
+			btrfs_qgroup_level(key.offset),
+			btrfs_qgroup_subvid(key.offset));
+		return;
+	}
+	memset(&count->limit, 0, sizeof(struct qgroup_limit));
+	if (flags & BTRFS_QGROUP_LIMIT_MAX_RFER)
+		count->limit.max_rfer =
+			btrfs_qgroup_limit_max_referenced(leaf, qli);
+	if (flags & BTRFS_QGROUP_LIMIT_MAX_EXCL)
+		count->limit.max_excl =
+			btrfs_qgroup_limit_max_exclusive(leaf, qli);
+}
+
 static int load_quota_info(struct btrfs_fs_info *info)
 {
 	int ret;
@@ -979,6 +1028,10 @@ loop:
 				continue;
 			}
 
+			if (key.type == BTRFS_QGROUP_LIMIT_KEY) {
+				read_qgroup_limit(leaf, i);
+				continue;
+			}
 			if (key.type == BTRFS_QGROUP_STATUS_KEY) {
 				read_qgroup_status(leaf, i, &counts);
 				continue;
@@ -1308,6 +1361,31 @@ static int report_qgroup_difference(struct qgroup_count *count, int verbose)
 	return is_different;
 }
 
+bool report_qgroup_limit_error(struct qgroup_count *count)
+{
+	struct qgroup_info *info = &count->info;
+	struct qgroup_limit *limit = &count->limit;
+	bool ret = false;
+
+	if (limit->max_excl && limit->max_excl < info->exclusive) {
+		printf("Exclusive limit for qgroup id: %llu/%llu is exceeded\n",
+			btrfs_qgroup_level(count->qgroupid),
+			btrfs_qgroup_subvid(count->qgroupid));
+		print_fields(limit->max_excl, info->exclusive, "limit",
+			     "exclusive");
+		ret = true;
+	}
+	if (limit->max_rfer && limit->max_rfer < info->referenced) {
+		printf("Referenced limit for qgroup id: %llu/%llu is exceeded\n",
+			btrfs_qgroup_level(count->qgroupid),
+			btrfs_qgroup_subvid(count->qgroupid));
+		print_fields(limit->max_rfer, info->referenced, "limit",
+			     "referenced");
+		ret = true;
+	}
+	return ret;
+}
+
 /*
  * Report qgroups errors
  * Return 0 if nothing wrong.
@@ -1352,6 +1430,10 @@ int report_qgroups(int all)
 			list_add_tail(&c->bad_list, &bad_qgroups);
 			found_err = true;
 		}
+		if (report_qgroup_limit_error(c)) {
+			list_add_tail(&c->bad_list, &bad_qgroups);
+			found_err = true;
+		}
 
 		node = rb_next(node);
 	}
-- 
2.19.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-11-13  6:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-13  6:47 [PATCH] btrfs-progs: qgroup-verify: Check if qgroup limit is exceeded Qu Wenruo

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).