@@ -153,6 +153,30 @@ show [options] <path>
To retrieve information after updating the state of qgroups,
force sync of the filesystem identified by *path* before getting information.
+SPECIAL PATHS
+-------------
+For `btrfs qgroup show` subcommand, the ``path`` column may has some special
+strings:
+
+`<toplevel>`
+ The toplevel subvolume
+
+`<under deletion>`
+ The subvolume is unlinked, but not yet fully deleted.
+
+`<squota space holder>`
+ For simple quota mode only.
+ By its design, a fully deleted subvolume may still have accounting on
+ it, so even the subvolume is gone, the numbers are still here for future
+ accounting.
+
+`<stale>`
+ The qgroup has no corresponding subvolume anymore, and the qgroup
+ can be cleaned up under most cases.
+ The only exception is that, if the qgroup numbers are inconsistent and
+ the qgroup numbers are not all zeros, some older kernels may refuse to
+ delete such qgroups until a full rescan.
+
QUOTA RESCAN
------------
@@ -71,6 +71,8 @@ struct qgroup_lookup {
};
struct btrfs_qgroup {
+ struct qgroup_lookup *lookup;
+
struct rb_node rb_node;
struct rb_node sort_node;
/*
@@ -321,6 +323,26 @@ static void print_qgroup_column_add_blank(enum btrfs_qgroup_column_enum column,
printf(" ");
}
+static const char *get_qgroup_path(struct btrfs_qgroup *qgroup)
+{
+ if (qgroup->path)
+ return qgroup->path;
+
+ /* No path but not stale either, the qgroup is being deleted. */
+ if (!qgroup->stale)
+ return "<under deletion>";
+ /*
+ * Squota mode stale qgroup, but not empty.
+ * This is fully deleted but still necessary.
+ */
+ if (qgroup->stale &&
+ (qgroup->lookup->flags & BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE) &&
+ !is_qgroup_empty(qgroup))
+ return "<squota space holder>";
+
+ return "<stale>";
+}
+
static void print_path_column(struct btrfs_qgroup *qgroup)
{
struct btrfs_qgroup_list *list = NULL;
@@ -338,11 +360,8 @@ static void print_path_column(struct btrfs_qgroup *qgroup)
if (count)
pr_verbose(LOG_DEFAULT, " ");
if (level == 0) {
- const char *path = member->path;
-
- if (!path)
- path = "<stale>";
- pr_verbose(LOG_DEFAULT, "%s", path);
+ pr_verbose(LOG_DEFAULT, "%s",
+ get_qgroup_path(qgroup));
} else {
pr_verbose(LOG_DEFAULT, "%llu/%llu", level, sid);
}
@@ -353,7 +372,7 @@ static void print_path_column(struct btrfs_qgroup *qgroup)
} else if (qgroup->path) {
pr_verbose(LOG_DEFAULT, "%s%s", (*qgroup->path ? "" : "<toplevel>"), qgroup->path);
} else {
- pr_verbose(LOG_DEFAULT, "<stale>");
+ pr_verbose(LOG_DEFAULT, "%s", get_qgroup_path(qgroup));
}
}
@@ -805,6 +824,7 @@ static struct btrfs_qgroup *get_or_add_qgroup(int fd,
return ERR_PTR(-ENOMEM);
}
+ bq->lookup = qgroup_lookup;
bq->qgroupid = qgroupid;
INIT_LIST_HEAD(&bq->qgroups);
INIT_LIST_HEAD(&bq->members);
Currently `btrfs qgroup show` command shows any 0 level qgroup withou a root backref as `<stale>`, which is not correct. There are several more cases: - Under deletion The subvolume is not yet full dropped, but unlinked. In that case we would not have a root backref item, but the qgroup is not stale. - Squota space holder This is for squota mode, that a fully dropped subvolume still have extents accounting on the already-gone subvolume. In this case it's not stale either, and future accounting relies on it. This patch would add above special cases, and add an extra `SPECIAL PATHS` section to explain all the cases, including `<stale>`. Signed-off-by: Qu Wenruo <wqu@suse.com> --- Documentation/btrfs-qgroup.rst | 24 ++++++++++++++++++++++++ cmds/qgroup.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 6 deletions(-)