The patchset enhanced btrfs qgroup show command.
Firstly, we restructure show_qgroups, make it easy to add new features.
And then we add ''-p'' ''-c'',
''-r'',and ''-e'' options to print the parent
qgroup id, child qgroup id, max referenced size and max exclusive size
of qgroup respectively, add ''-F'' and ''-f''
option to list qgroups that
impact the given path.
Besides that, the users may want to sort qgroups according to some items.
For this case, we introduce ''--sort'' option. With this option,
we can sort
the qgroup by qgroupid, rfer, excl, max_rfer and max_excl.
Notice, we force to print result as a table(as david suggest this
dosen''t matter
for now), and with option ''--block-size'', user can control to
print result,for example,
k,K,m,M,etc.What''s more ''-h'' gives a short cut to
allow people to print result in
human readable format size.
You can pull this patchset from the URL:
git://github.com/wangshilong/Btrfs-progs.git qgroup_v2
This patchset is rebased on david''s intergration-20130924.
Changelog:
v2->v3:
mainly address comments from david.
1)print result as table in default.
2)add ''--block-size'' option
3)add ''-h'' option to print size in human readable format.
4)replace ''-l'' with ''-r'' to print max
referenced size.
5)some codes cleanups.
v1->v2:
rebase the patchset on david''s integration-20130920
Wang Shilong (12):
Btrfs-progs: restructure show_qgroups
Btrfs-progs: introduces ''-p'' option to print the ID of the
parent
qgroups
Btrfs-progs: introduces ''-c'' option to print the ID of the
child
qgroups
Btrfs-progs: introduce ''-r'' option to print max referenced
size of
qgroups
Btrfs-progs: introduce ''-e'' option to print max exclusive
size of
qgroups
Btrfs-progs: list all qgroups impact given path(include ancestral
qgroups)
Btrfs-progs: list all qgroups impact given path(exclude ancestral
qgroups)
Btrfs-progs: enhance btrfs qgroup show to sort qgroups
Btrfs-progs: enhance btrfs qgroup to print the result as a table
Btrfs-progs: add ''--block-size'' option to control print
result
Btrfs-progs: make pretty_size_snprintf() return len
Btrfs-progs: add ''-h'' options to print sizes in human
readable format
cmds-qgroup.c | 197 ++++-----
ctree.h | 11 +
qgroup.c | 1286 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qgroup.h | 73 ++++
utils.c | 59 ++-
utils.h | 6 +-
6 files changed, 1532 insertions(+), 100 deletions(-)
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
The current show_qgroups() just shows a little information, and it is hard to
add some functions which the users need in the future, so i restructure it, make
it easy to add new functions.
In order to improve the scalability of show_qgroups(), i add some important
structures:
struct qgroup_lookup {
struct rb_root root;
}
/*
*store qgroup''s information
*/
struct btrfs_qgroup {
struct rb_node rb_node;
u64 qgroupid;
u64 generation;
u64 rfer;
u64 rfer_cmpr;
u64 excl_cmpr;
u64 flags;
u64 max_rfer;
u64 max_excl;
u64 rsv_rfer;
u64 rsv_excl;
struct list_head qgroups;
struct list_head members;
}
/*
*glue structure to represent the relations
*between qgroups
*/
struct btrfs_qgroup_list {
struct list_head next_qgroups;
struct list_head next_member;
struct btrfs_qgroup *qgroup;
struct btrfs_qgroup *member;
}
The above 3 structures are used to manage all the information
of qgroups.
struct {
char *name;
char *column_name;
int need_print;
} btrfs_qgroup_columns[]
We define a arrary to manage all the columns that can be
outputed, and use a member variant(->need_print) to control
the output of the relative column. Some columns are outputed
by default. But we can change it according to the requirement
of the users.
For example:
if outputing max referenced size of qgroup is needed,the function
''btrfs_qgroup_setup_column()'' will be called, and the
parameter ''BTRFS_QGROUP_MAX_RFER''
(extend in the future) will be passsed to the function. After the function is
done,
when showing qgroups, max referenced size of qgroup will be output.
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 91 +----------
ctree.h | 11 ++
qgroup.c | 509 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qgroup.h | 10 ++
4 files changed, 531 insertions(+), 90 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index ff2a1fa..d3c699f 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -106,95 +106,6 @@ static int qgroup_create(int create, int argc, char **argv)
return 0;
}
-static void print_qgroup_info(u64 objectid, struct btrfs_qgroup_info_item
*info)
-{
- printf("%llu/%llu %lld %lld\n", objectid >> 48,
- objectid & ((1ll << 48) - 1),
- btrfs_stack_qgroup_info_referenced(info),
- btrfs_stack_qgroup_info_exclusive(info));
-}
-
-static int list_qgroups(int fd)
-{
- int ret;
- struct btrfs_ioctl_search_args args;
- struct btrfs_ioctl_search_key *sk = &args.key;
- struct btrfs_ioctl_search_header *sh;
- unsigned long off = 0;
- unsigned int i;
- struct btrfs_qgroup_info_item *info;
-
- memset(&args, 0, sizeof(args));
-
- /* search in the quota tree */
- sk->tree_id = BTRFS_QUOTA_TREE_OBJECTID;
-
- /*
- * set the min and max to backref keys. The search will
- * only send back this type of key now.
- */
- sk->max_type = BTRFS_QGROUP_INFO_KEY;
- sk->min_type = BTRFS_QGROUP_INFO_KEY;
- sk->max_objectid = 0;
- sk->max_offset = (u64)-1;
- sk->max_transid = (u64)-1;
-
- /* just a big number, doesn''t matter much */
- sk->nr_items = 4096;
-
- while (1) {
- ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
- if (ret < 0)
- return ret;
-
- /* the ioctl returns the number of item it found in nr_items */
- if (sk->nr_items == 0)
- break;
-
- off = 0;
-
- /*
- * for each item, pull the key out of the header and then
- * read the root_ref item it contains
- */
- for (i = 0; i < sk->nr_items; i++) {
- sh = (struct btrfs_ioctl_search_header *)(args.buf +
- off);
- off += sizeof(*sh);
-
- if (sh->objectid != 0)
- goto done;
-
- if (sh->type != BTRFS_QGROUP_INFO_KEY)
- goto done;
-
- info = (struct btrfs_qgroup_info_item *)
- (args.buf + off);
- print_qgroup_info(sh->offset, info);
-
- off += sh->len;
-
- /*
- * record the mins in sk so we can make sure the
- * next search doesn''t repeat this root
- */
- sk->min_offset = sh->offset;
- }
- sk->nr_items = 4096;
- /*
- * this iteration is done, step forward one qgroup for the next
- * ioctl
- */
- if (sk->min_offset < (u64)-1)
- sk->min_offset++;
- else
- break;
- }
-
-done:
- return ret;
-}
-
static int parse_limit(const char *p, unsigned long long *s)
{
char *endptr;
@@ -313,7 +224,7 @@ static int cmd_qgroup_show(int argc, char **argv)
return 1;
}
- ret = list_qgroups(fd);
+ ret = btrfs_show_qgroups(fd);
e = errno;
close_file_or_dir(fd, dirstream);
if (ret < 0)
diff --git a/ctree.h b/ctree.h
index 5b4c859..c90581a 100644
--- a/ctree.h
+++ b/ctree.h
@@ -2059,6 +2059,17 @@ BTRFS_SETGET_FUNCS(qgroup_limit_rsv_referenced, struct
btrfs_qgroup_limit_item,
BTRFS_SETGET_FUNCS(qgroup_limit_rsv_exclusive, struct btrfs_qgroup_limit_item,
rsv_exclusive, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_flags,
+ struct btrfs_qgroup_limit_item, flags, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_max_referenced,
+ struct btrfs_qgroup_limit_item, max_referenced, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_max_exclusive,
+ struct btrfs_qgroup_limit_item, max_exclusive, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_referenced,
+ struct btrfs_qgroup_limit_item, rsv_referenced, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_limit_rsv_exclusive,
+ struct btrfs_qgroup_limit_item, rsv_exclusive, 64);
+
/* this returns the number of file bytes represented by the inline item.
* If an item is compressed, this is the uncompressed size
*/
diff --git a/qgroup.c b/qgroup.c
index 86fe2b2..bd9658e 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -17,7 +17,516 @@
*/
#include "qgroup.h"
+#include <sys/ioctl.h>
#include "ctree.h"
+#include "ioctl.h"
+
+struct qgroup_lookup {
+ struct rb_root root;
+};
+
+struct btrfs_qgroup {
+ struct rb_node rb_node;
+ u64 qgroupid;
+
+ /*
+ * info_item
+ */
+ u64 generation;
+ u64 rfer; /*referenced*/
+ u64 rfer_cmpr; /*referenced compressed*/
+ u64 excl; /*exclusive*/
+ u64 excl_cmpr; /*exclusive compressed*/
+
+ /*
+ *limit_item
+ */
+ u64 flags; /*which limits are set*/
+ u64 max_rfer;
+ u64 max_excl;
+ u64 rsv_rfer;
+ u64 rsv_excl;
+
+ /*qgroups this group is member of*/
+ struct list_head qgroups;
+ /*qgroups that are members of this group*/
+ struct list_head members;
+};
+
+/*
+ * glue structure to represent the relations
+ * between qgroups
+ */
+struct btrfs_qgroup_list {
+ struct list_head next_qgroup;
+ struct list_head next_member;
+ struct btrfs_qgroup *qgroup;
+ struct btrfs_qgroup *member;
+};
+
+/*
+ * qgroupid,rfer,excl default to set
+ */
+struct {
+ char *name;
+ char *column_name;
+ int need_print;
+} btrfs_qgroup_columns[] = {
+ {
+ .name = "qgroupid",
+ .column_name = "Qgroupid",
+ .need_print = 1,
+ },
+ {
+ .name = "rfer",
+ .column_name = "Rfer",
+ .need_print = 1,
+ },
+ {
+ .name = "excl",
+ .column_name = "Excl",
+ .need_print = 1,
+ },
+ {
+ .name = NULL,
+ .column_name = NULL,
+ .need_print = 0,
+ },
+};
+
+void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column)
+{
+ int i;
+
+ BUG_ON(column < 0 || column > BTRFS_QGROUP_ALL);
+
+ if (column < BTRFS_QGROUP_ALL) {
+ btrfs_qgroup_columns[column].need_print = 1;
+ return;
+ }
+ for (i = 0; i < BTRFS_QGROUP_ALL; i++)
+ btrfs_qgroup_columns[i].need_print = 1;
+}
+
+static void print_qgroup_column(struct btrfs_qgroup *qgroup,
+ enum btrfs_qgroup_column_enum column)
+{
+ BUG_ON(column >= BTRFS_QGROUP_ALL || column < 0);
+
+ switch (column) {
+
+ case BTRFS_QGROUP_QGROUPID:
+ printf("%llu/%llu", qgroup->qgroupid >> 48,
+ ((1ll << 48) - 1) & qgroup->qgroupid);
+ break;
+ case BTRFS_QGROUP_RFER:
+ printf("%lld", qgroup->rfer);
+ break;
+ case BTRFS_QGROUP_EXCL:
+ printf("%lld", qgroup->excl);
+ break;
+ default:
+ break;
+ }
+}
+
+static void print_single_qgroup_default(struct btrfs_qgroup *qgroup)
+{
+ int i;
+
+ for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
+ if (!btrfs_qgroup_columns[i].need_print)
+ continue;
+ print_qgroup_column(qgroup, i);
+
+ if (i != BTRFS_QGROUP_ALL - 1)
+ printf(" ");
+ }
+ printf("\n");
+}
+
+static void qgroup_lookup_init(struct qgroup_lookup *tree)
+{
+ tree->root.rb_node = NULL;
+}
+
+static int comp_entry_with_qgroupid(struct btrfs_qgroup *entry1,
+ struct btrfs_qgroup *entry2,
+ int is_descending)
+{
+
+ int ret;
+
+ if (entry1->qgroupid > entry2->qgroupid)
+ ret = 1;
+ else if (entry1->qgroupid < entry2->qgroupid)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
+/*
+ * insert a new root into the tree. returns the existing root entry
+ * if one is already there. qgroupid is used
+ * as the key
+ */
+static int qgroup_tree_insert(struct qgroup_lookup *root_tree,
+ struct btrfs_qgroup *ins)
+{
+
+ struct rb_node **p = &root_tree->root.rb_node;
+ struct rb_node *parent = NULL;
+ struct btrfs_qgroup *curr;
+ int ret;
+
+ while (*p) {
+ parent = *p;
+ curr = rb_entry(parent, struct btrfs_qgroup, rb_node);
+
+ ret = comp_entry_with_qgroupid(ins, curr, 0);
+ if (ret < 0)
+ p = &(*p)->rb_left;
+ else if (ret > 0)
+ p = &(*p)->rb_right;
+ else
+ return -EEXIST;
+ }
+ rb_link_node(&ins->rb_node, parent, p);
+ rb_insert_color(&ins->rb_node, &root_tree->root);
+ return 0;
+}
+
+/*
+ *find a given qgroupid in the tree. We return the smallest one,
+ *rb_next can be used to move forward looking for more if required
+ */
+static struct btrfs_qgroup *qgroup_tree_search(struct qgroup_lookup *root_tree,
+ u64 qgroupid)
+{
+ struct rb_node *n = root_tree->root.rb_node;
+ struct btrfs_qgroup *entry;
+ struct btrfs_qgroup tmp;
+ int ret;
+
+ tmp.qgroupid = qgroupid;
+
+ while (n) {
+ entry = rb_entry(n, struct btrfs_qgroup, rb_node);
+
+ ret = comp_entry_with_qgroupid(&tmp, entry, 0);
+ if (ret < 0)
+ n = n->rb_left;
+ else if (ret > 0)
+ n = n->rb_right;
+ else
+ return entry;
+
+ }
+ return NULL;
+}
+
+static int update_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
+ u64 generation, u64 rfer, u64 rfer_cmpr, u64 excl,
+ u64 excl_cmpr, u64 flags, u64 max_rfer, u64 max_excl,
+ u64 rsv_rfer, u64 rsv_excl, struct btrfs_qgroup *pa,
+ struct btrfs_qgroup *child)
+{
+ struct btrfs_qgroup *bq;
+ struct btrfs_qgroup_list *list;
+
+ bq = qgroup_tree_search(qgroup_lookup, qgroupid);
+ if (!bq || bq->qgroupid != qgroupid)
+ return -ENOENT;
+
+ if (generation)
+ bq->generation = generation;
+ if (rfer)
+ bq->rfer = rfer;
+ if (rfer_cmpr)
+ bq->rfer_cmpr = rfer_cmpr;
+ if (excl)
+ bq->excl = excl;
+ if (excl_cmpr)
+ bq->excl_cmpr = excl_cmpr;
+ if (flags)
+ bq->flags = flags;
+ if (max_rfer)
+ bq->max_rfer = max_rfer;
+ if (max_excl)
+ bq->max_excl = max_excl;
+ if (rsv_rfer)
+ bq->rsv_rfer = rsv_rfer;
+ if (pa && child) {
+ list = malloc(sizeof(*list));
+ if (!list) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+ list->qgroup = pa;
+ list->member = child;
+ list_add_tail(&list->next_qgroup, &child->qgroups);
+ list_add_tail(&list->next_member, &pa->members);
+ }
+ return 0;
+}
+
+static int add_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
+ u64 generation, u64 rfer, u64 rfer_cmpr, u64 excl,
+ u64 excl_cmpr, u64 flags, u64 max_rfer, u64 max_excl,
+ u64 rsv_rfer, u64 rsv_excl, struct btrfs_qgroup *parent,
+ struct btrfs_qgroup *child)
+{
+ struct btrfs_qgroup *bq;
+ struct btrfs_qgroup_list *list;
+ int ret;
+
+ ret = update_qgroup(qgroup_lookup, qgroupid, generation, rfer,
+ rfer_cmpr, excl, excl_cmpr, flags, max_rfer,
+ max_excl, rsv_rfer, rsv_excl, parent, child);
+ if (!ret)
+ return 0;
+
+ bq = malloc(sizeof(*bq));
+ if (!bq) {
+ printf("memory allocation failed\n");
+ exit(1);
+ }
+ memset(bq, 0, sizeof(*bq));
+ if (qgroupid) {
+ bq->qgroupid = qgroupid;
+ INIT_LIST_HEAD(&bq->qgroups);
+ INIT_LIST_HEAD(&bq->members);
+ }
+ if (generation)
+ bq->generation = generation;
+ if (rfer)
+ bq->rfer = rfer;
+ if (rfer_cmpr)
+ bq->rfer_cmpr = rfer_cmpr;
+ if (excl)
+ bq->excl = excl;
+ if (excl_cmpr)
+ bq->excl_cmpr = excl_cmpr;
+ if (flags)
+ bq->flags = flags;
+ if (max_rfer)
+ bq->max_rfer = max_rfer;
+ if (max_excl)
+ bq->max_excl = max_excl;
+ if (rsv_rfer)
+ bq->rsv_rfer = rsv_rfer;
+ if (parent && child) {
+ list = malloc(sizeof(*list));
+ if (!list) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+ list->qgroup = parent;
+ list->member = child;
+ list_add_tail(&list->next_qgroup, &child->qgroups);
+ list_add_tail(&list->next_member, &parent->members);
+ }
+ ret = qgroup_tree_insert(qgroup_lookup, bq);
+ if (ret) {
+ printf("failed to insert tree %llu\n",
+ bq->qgroupid);
+ exit(1);
+ }
+ return ret;
+}
+
+void __free_btrfs_qgroup(struct btrfs_qgroup *bq)
+{
+ struct btrfs_qgroup_list *list;
+ while (!list_empty(&bq->qgroups)) {
+ list = list_entry((&bq->qgroups)->next,
+ struct btrfs_qgroup_list,
+ next_qgroup);
+ list_del(&list->next_qgroup);
+ list_del(&list->next_member);
+ free(list);
+ }
+ while (!list_empty(&bq->members)) {
+ list = list_entry((&bq->members)->next,
+ struct btrfs_qgroup_list,
+ next_member);
+ list_del(&list->next_qgroup);
+ list_del(&list->next_member);
+ free(list);
+ }
+ free(bq);
+}
+
+void __free_all_qgroups(struct qgroup_lookup *root_tree)
+{
+ struct btrfs_qgroup *entry;
+ struct rb_node *n;
+
+ n = rb_first(&root_tree->root);
+ while (n) {
+ entry = rb_entry(n, struct btrfs_qgroup, rb_node);
+ rb_erase(n, &root_tree->root);
+ __free_btrfs_qgroup(entry);
+
+ n = rb_first(&root_tree->root);
+ }
+}
+
+static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
+{
+ int ret;
+ struct btrfs_ioctl_search_args args;
+ struct btrfs_ioctl_search_key *sk = &args.key;
+ struct btrfs_ioctl_search_header *sh;
+ unsigned long off = 0;
+ unsigned int i;
+ int e;
+ struct btrfs_qgroup_info_item *info;
+ struct btrfs_qgroup_limit_item *limit;
+ struct btrfs_qgroup *bq;
+ struct btrfs_qgroup *bq1;
+ u64 a1;
+ u64 a2;
+ u64 a3;
+ u64 a4;
+ u64 a5;
+
+ memset(&args, 0, sizeof(args));
+
+ sk->tree_id = BTRFS_QUOTA_TREE_OBJECTID;
+ sk->max_type = BTRFS_QGROUP_RELATION_KEY;
+ sk->min_type = BTRFS_QGROUP_INFO_KEY;
+ sk->max_objectid = (u64)-1;
+ sk->max_offset = (u64)-1;
+ sk->max_transid = (u64)-1;
+ sk->nr_items = 4096;
+
+ qgroup_lookup_init(qgroup_lookup);
+
+ while (1) {
+ ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
+ e = errno;
+ if (ret < 0) {
+ fprintf(stderr,
+ "ERROR: can''t perform the search - %s\n",
+ strerror(e));
+ return ret;
+ }
+ /* the ioctl returns the number of item it found in nr_items */
+ if (sk->nr_items == 0)
+ break;
+
+ off = 0;
+ /*
+ * for each item, pull the key out of the header and then
+ * read the root_ref item it contains
+ */
+ for (i = 0; i < sk->nr_items; i++) {
+ sh = (struct btrfs_ioctl_search_header *)(args.buf +
+ off);
+ off += sizeof(*sh);
+
+ if (sh->type == BTRFS_QGROUP_INFO_KEY) {
+ info = (struct btrfs_qgroup_info_item *)
+ (args.buf + off);
+ a1 = btrfs_stack_qgroup_info_generation(info);
+ a2 = btrfs_stack_qgroup_info_referenced(info);
+ a3 + btrfs_stack_qgroup_info_referenced_compressed
+ (info);
+ a4 = btrfs_stack_qgroup_info_exclusive(info);
+ a5 + btrfs_stack_qgroup_info_exclusive_compressed
+ (info);
+ add_qgroup(qgroup_lookup, sh->offset, a1, a2,
+ a3, a4, a5, 0, 0, 0, 0, 0, 0, 0);
+ } else if (sh->type == BTRFS_QGROUP_LIMIT_KEY) {
+ limit = (struct btrfs_qgroup_limit_item *)
+ (args.buf + off);
+
+ a1 = btrfs_stack_qgroup_limit_flags(limit);
+ a2 = btrfs_stack_qgroup_limit_max_referenced
+ (limit);
+ a3 = btrfs_stack_qgroup_limit_max_exclusive
+ (limit);
+ a4 = btrfs_stack_qgroup_limit_rsv_referenced
+ (limit);
+ a5 = btrfs_stack_qgroup_limit_rsv_exclusive
+ (limit);
+ add_qgroup(qgroup_lookup, sh->offset, 0, 0,
+ 0, 0, 0, a1, a2, a3, a4, a5, 0, 0);
+ } else if (sh->type == BTRFS_QGROUP_RELATION_KEY) {
+ if (sh->offset < sh->objectid)
+ goto skip;
+ bq = qgroup_tree_search(qgroup_lookup,
+ sh->offset);
+ if (!bq)
+ goto skip;
+ bq1 = qgroup_tree_search(qgroup_lookup,
+ sh->objectid);
+ if (!bq1)
+ goto skip;
+ add_qgroup(qgroup_lookup, sh->offset, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, bq, bq1);
+ } else
+ goto done;
+skip:
+ off += sh->len;
+
+ /*
+ * record the mins in sk so we can make sure the
+ * next search doesn''t repeat this root
+ */
+ sk->min_type = sh->type;
+ sk->min_offset = sh->offset;
+ sk->min_objectid = sh->objectid;
+ }
+ sk->nr_items = 4096;
+ /*
+ * this iteration is done, step forward one qgroup for the next
+ * ioctl
+ */
+ if (sk->min_offset < (u64)-1)
+ sk->min_offset++;
+ else
+ break;
+ }
+
+done:
+ return ret;
+}
+
+static void print_all_qgroups(struct qgroup_lookup *qgroup_lookup)
+{
+
+ struct rb_node *n;
+ struct btrfs_qgroup *entry;
+
+ n = rb_first(&qgroup_lookup->root);
+ while (n) {
+ entry = rb_entry(n, struct btrfs_qgroup, rb_node);
+ print_single_qgroup_default(entry);
+ n = rb_next(n);
+ }
+}
+
+int btrfs_show_qgroups(int fd)
+{
+
+ struct qgroup_lookup qgroup_lookup;
+ int ret;
+
+ ret = __qgroups_search(fd, &qgroup_lookup);
+ if (ret)
+ return ret;
+
+ print_all_qgroups(&qgroup_lookup);
+ __free_all_qgroups(&qgroup_lookup);
+
+ return ret;
+}
u64 parse_qgroupid(char *p)
{
diff --git a/qgroup.h b/qgroup.h
index da6d113..8b34cd7 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -22,6 +22,16 @@
#include "ioctl.h"
#include "kerncompat.h"
+enum btrfs_qgroup_column_enum {
+ BTRFS_QGROUP_QGROUPID,
+ BTRFS_QGROUP_RFER,
+ BTRFS_QGROUP_EXCL,
+ BTRFS_QGROUP_ALL,
+};
+
+int btrfs_show_qgroups(int fd);
+void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column);
+
u64 parse_qgroupid(char *p);
int qgroup_inherit_size(struct btrfs_qgroup_inherit *p);
int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 02/12] Btrfs-progs: introduces ''-p'' option to print the ID of the parent qgroups
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduces ''-p'' option to print the ID of the
parent qgroups.
You may use it like:
btrfs qgroup show -p <path>
For Example:
qgroupid(2/0)
/ \
/ \
/ \
qgroupid(1/0) qgroupid(1/1)
\ /
\ /
qgroupid(0/1)
If we use the command:
btrfs qgroup show -p <path>
The result will output
0/1 -- -- 1/0,1/1
1/0 -- -- 2/0
1/1 -- -- 2/0
2/0 -- -- --
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 23 ++++++++++++++++++++---
qgroup.c | 22 ++++++++++++++++++++++
qgroup.h | 1 +
3 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index d3c699f..96098c1 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,22 +202,39 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show <path>",
+ "btrfs qgroup show -p <path>",
"Show all subvolume quota groups.",
+ "-p print parent qgroup id",
NULL
};
static int cmd_qgroup_show(int argc, char **argv)
{
+ char *path;
int ret = 0;
int fd;
int e;
- char *path = argv[1];
DIR *dirstream = NULL;
+ int c;
- if (check_argc_exact(argc, 2))
+ optind = 1;
+ while (1) {
+ c = getopt(argc, argv, "p");
+ if (c < 0)
+ break;
+ switch (c) {
+ case ''p'':
+ btrfs_qgroup_setup_print_column(
+ BTRFS_QGROUP_PARENT);
+ break;
+ default:
+ usage(cmd_qgroup_show_usage);
+ }
+ }
+ if (check_argc_exact(argc - optind, 1))
usage(cmd_qgroup_show_usage);
+ path = argv[optind];
fd = open_file_or_dir(path, &dirstream);
if (fd < 0) {
fprintf(stderr, "ERROR: can''t access
''%s''\n", path);
diff --git a/qgroup.c b/qgroup.c
index bd9658e..0dbf28c 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -88,6 +88,11 @@ struct {
.need_print = 1,
},
{
+ .name = "parent",
+ .column_name = "Parent",
+ .need_print = 0,
+ },
+ {
.name = NULL,
.column_name = NULL,
.need_print = 0,
@@ -108,6 +113,20 @@ void btrfs_qgroup_setup_print_column(enum
btrfs_qgroup_column_enum column)
btrfs_qgroup_columns[i].need_print = 1;
}
+static void print_parent_column(struct btrfs_qgroup *qgroup)
+{
+ struct btrfs_qgroup_list *list = NULL;
+
+ list_for_each_entry(list, &qgroup->qgroups, next_qgroup) {
+ printf("%llu/%llu", (list->qgroup)->qgroupid >> 48,
+ ((1ll << 48) - 1) & (list->qgroup)->qgroupid);
+ if (!list_is_last(&list->next_qgroup, &qgroup->qgroups))
+ printf(",");
+ }
+ if (list_empty(&qgroup->qgroups))
+ printf("---");
+}
+
static void print_qgroup_column(struct btrfs_qgroup *qgroup,
enum btrfs_qgroup_column_enum column)
{
@@ -125,6 +144,9 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup,
case BTRFS_QGROUP_EXCL:
printf("%lld", qgroup->excl);
break;
+ case BTRFS_QGROUP_PARENT:
+ print_parent_column(qgroup);
+ break;
default:
break;
}
diff --git a/qgroup.h b/qgroup.h
index 8b34cd7..cefdfe1 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -26,6 +26,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_QGROUPID,
BTRFS_QGROUP_RFER,
BTRFS_QGROUP_EXCL,
+ BTRFS_QGROUP_PARENT,
BTRFS_QGROUP_ALL,
};
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 03/12] Btrfs-progs: introduces ''-c'' option to print the ID of the child qgroups
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduces ''-c'' option to print the ID of the child
qgroups.
You may use it like:
btrfs qgroup show -c <path>
For Example:
qgroupid(2/0)
/ \
/ \
/ \
qgroupid(1/0) qgroupid(1/1)
\ /
\ /
qgroupid(0/1)
If we use the command:
btrfs qgroup show -c <path>
The result will output
0/1 -- -- --
1/0 -- -- 0/1
1/1 -- -- 0/1
2/0 -- -- 1/0,1/1
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 9 +++++++--
qgroup.c | 22 ++++++++++++++++++++++
qgroup.h | 1 +
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 96098c1..147bedc 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,9 +202,10 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -p <path>",
+ "btrfs qgroup show -pc <path>",
"Show all subvolume quota groups.",
"-p print parent qgroup id",
+ "-c print child qgroup id",
NULL
};
@@ -219,7 +220,7 @@ static int cmd_qgroup_show(int argc, char **argv)
optind = 1;
while (1) {
- c = getopt(argc, argv, "p");
+ c = getopt(argc, argv, "pc");
if (c < 0)
break;
switch (c) {
@@ -227,6 +228,10 @@ static int cmd_qgroup_show(int argc, char **argv)
btrfs_qgroup_setup_print_column(
BTRFS_QGROUP_PARENT);
break;
+ case ''c'':
+ btrfs_qgroup_setup_print_column(
+ BTRFS_QGROUP_CHILD);
+ break;
default:
usage(cmd_qgroup_show_usage);
}
diff --git a/qgroup.c b/qgroup.c
index 0dbf28c..1592dd4 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -93,6 +93,11 @@ struct {
.need_print = 0,
},
{
+ .name = "child",
+ .column_name = "Child",
+ .need_print = 0,
+ },
+ {
.name = NULL,
.column_name = NULL,
.need_print = 0,
@@ -127,6 +132,20 @@ static void print_parent_column(struct btrfs_qgroup
*qgroup)
printf("---");
}
+static void print_child_column(struct btrfs_qgroup *qgroup)
+{
+ struct btrfs_qgroup_list *list = NULL;
+
+ list_for_each_entry(list, &qgroup->members, next_member) {
+ printf("%llu/%llu", (list->member)->qgroupid >> 48,
+ ((1ll << 48) - 1) & (list->member)->qgroupid);
+ if (!list_is_last(&list->next_member, &qgroup->members))
+ printf(",");
+ }
+ if (list_empty(&qgroup->members))
+ printf("---");
+}
+
static void print_qgroup_column(struct btrfs_qgroup *qgroup,
enum btrfs_qgroup_column_enum column)
{
@@ -147,6 +166,9 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup,
case BTRFS_QGROUP_PARENT:
print_parent_column(qgroup);
break;
+ case BTRFS_QGROUP_CHILD:
+ print_child_column(qgroup);
+ break;
default:
break;
}
diff --git a/qgroup.h b/qgroup.h
index cefdfe1..33682ae 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -27,6 +27,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_RFER,
BTRFS_QGROUP_EXCL,
BTRFS_QGROUP_PARENT,
+ BTRFS_QGROUP_CHILD,
BTRFS_QGROUP_ALL,
};
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 04/12] Btrfs-progs: introduce ''-r'' option to print max referenced size of qgroups
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduces ''-r'' option to print max referenced size
of qgroups.
You may use it like:
btrfs qgroup show -r <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 9 +++++++--
qgroup.c | 7 +++++++
qgroup.h | 1 +
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 147bedc..213cbde 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,10 +202,11 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pc <path>",
+ "btrfs qgroup show -pcr <path>",
"Show all subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
+ "-r print max referenced size of qgroup",
NULL
};
@@ -220,7 +221,7 @@ static int cmd_qgroup_show(int argc, char **argv)
optind = 1;
while (1) {
- c = getopt(argc, argv, "pc");
+ c = getopt(argc, argv, "pcr");
if (c < 0)
break;
switch (c) {
@@ -232,6 +233,10 @@ static int cmd_qgroup_show(int argc, char **argv)
btrfs_qgroup_setup_print_column(
BTRFS_QGROUP_CHILD);
break;
+ case ''r'':
+ btrfs_qgroup_setup_print_column(
+ BTRFS_QGROUP_MAX_RFER);
+ break;
default:
usage(cmd_qgroup_show_usage);
}
diff --git a/qgroup.c b/qgroup.c
index 1592dd4..f9eb52d 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -87,6 +87,10 @@ struct {
.column_name = "Excl",
.need_print = 1,
},
+ { .name = "max_rfer",
+ .column_name = "Max_rfer",
+ .need_print = 0,
+ },
{
.name = "parent",
.column_name = "Parent",
@@ -166,6 +170,9 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup,
case BTRFS_QGROUP_PARENT:
print_parent_column(qgroup);
break;
+ case BTRFS_QGROUP_MAX_RFER:
+ printf("%llu", qgroup->max_rfer);
+ break;
case BTRFS_QGROUP_CHILD:
print_child_column(qgroup);
break;
diff --git a/qgroup.h b/qgroup.h
index 33682ae..168fac0 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -26,6 +26,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_QGROUPID,
BTRFS_QGROUP_RFER,
BTRFS_QGROUP_EXCL,
+ BTRFS_QGROUP_MAX_RFER,
BTRFS_QGROUP_PARENT,
BTRFS_QGROUP_CHILD,
BTRFS_QGROUP_ALL,
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 05/12] Btrfs-progs: introduce ''-e'' option to print max exclusive size of qgroups
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduce ''-e'' option to print max exclusive size
of qgroups.
You may use it like this:
btrfs qgroup -e <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 9 +++++++--
qgroup.c | 8 ++++++++
qgroup.h | 1 +
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 213cbde..fc9ad2f 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,11 +202,12 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pcr <path>",
+ "btrfs qgroup show -pcre <path>",
"Show all subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
"-r print max referenced size of qgroup",
+ "-e print max exclusive size of qgroup",
NULL
};
@@ -221,7 +222,7 @@ static int cmd_qgroup_show(int argc, char **argv)
optind = 1;
while (1) {
- c = getopt(argc, argv, "pcr");
+ c = getopt(argc, argv, "pcre");
if (c < 0)
break;
switch (c) {
@@ -237,6 +238,10 @@ static int cmd_qgroup_show(int argc, char **argv)
btrfs_qgroup_setup_print_column(
BTRFS_QGROUP_MAX_RFER);
break;
+ case ''e'':
+ btrfs_qgroup_setup_print_column(
+ BTRFS_QGROUP_MAX_EXCL);
+ break;
default:
usage(cmd_qgroup_show_usage);
}
diff --git a/qgroup.c b/qgroup.c
index f9eb52d..2cd37b1 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -92,6 +92,11 @@ struct {
.need_print = 0,
},
{
+ .name = "max_excl",
+ .column_name = "Max_excl",
+ .need_print = 0,
+ },
+ {
.name = "parent",
.column_name = "Parent",
.need_print = 0,
@@ -173,6 +178,9 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup,
case BTRFS_QGROUP_MAX_RFER:
printf("%llu", qgroup->max_rfer);
break;
+ case BTRFS_QGROUP_MAX_EXCL:
+ printf("%llu", qgroup->max_excl);
+ break;
case BTRFS_QGROUP_CHILD:
print_child_column(qgroup);
break;
diff --git a/qgroup.h b/qgroup.h
index 168fac0..e7a65ba 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -27,6 +27,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_RFER,
BTRFS_QGROUP_EXCL,
BTRFS_QGROUP_MAX_RFER,
+ BTRFS_QGROUP_MAX_EXCL,
BTRFS_QGROUP_PARENT,
BTRFS_QGROUP_CHILD,
BTRFS_QGROUP_ALL,
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 06/12] Btrfs-progs: list all qgroups impact given path(include ancestral qgroups)
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduces ''-F'' option which can help you filter
the qgroups
by the path name, you may use it like:
btrfs qgroup show -F <path>
For example:
qgroupid(2/0)
/ \
/ \
qgroupid(1/0)
/ \
/ \
/ \
qgroupid(0/1) qgroupid(0/2)
sub1 sub2
/ \
/ \
dir1 file1
If we use the command:
btrfs qgroup show -F sub1/dir1
The result will output
0/1 -- --
1/0 -- --
2/0 -- --
''-F'' option help you list all qgroups impact given path.
(include ancestral qgroups).
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 24 +++++-
qgroup.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
qgroup.h | 28 ++++++-
3 files changed, 281 insertions(+), 10 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index fc9ad2f..7c6c917 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,12 +202,14 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pcre <path>",
- "Show all subvolume quota groups.",
+ "btrfs qgroup show -pcreF <path>",
+ "Show subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
"-r print max referenced size of qgroup",
"-e print max exclusive size of qgroup",
+ "-F list all qgroups which impact the given path"
+ "(include ancestral qgroups)",
NULL
};
@@ -219,10 +221,15 @@ static int cmd_qgroup_show(int argc, char **argv)
int e;
DIR *dirstream = NULL;
int c;
+ u64 qgroupid;
+ int filter_flag = 0;
+
+ struct btrfs_qgroup_filter_set *filter_set;
+ filter_set = btrfs_qgroup_alloc_filter_set();
optind = 1;
while (1) {
- c = getopt(argc, argv, "pcre");
+ c = getopt(argc, argv, "pcreF");
if (c < 0)
break;
switch (c) {
@@ -242,6 +249,9 @@ static int cmd_qgroup_show(int argc, char **argv)
btrfs_qgroup_setup_print_column(
BTRFS_QGROUP_MAX_EXCL);
break;
+ case ''F'':
+ filter_flag |= 0x1;
+ break;
default:
usage(cmd_qgroup_show_usage);
}
@@ -256,7 +266,13 @@ static int cmd_qgroup_show(int argc, char **argv)
return 1;
}
- ret = btrfs_show_qgroups(fd);
+ if (filter_flag) {
+ qgroupid = btrfs_get_path_rootid(fd);
+ btrfs_qgroup_setup_filter(&filter_set,
+ BTRFS_QGROUP_FILTER_ALL_PARENT,
+ qgroupid);
+ }
+ ret = btrfs_show_qgroups(fd, filter_set);
e = errno;
close_file_or_dir(fd, dirstream);
if (ret < 0)
diff --git a/qgroup.c b/qgroup.c
index 2cd37b1..306b638 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -21,12 +21,20 @@
#include "ctree.h"
#include "ioctl.h"
+#define BTRFS_QGROUP_NFILTERS_INCREASE (2 * BTRFS_QGROUP_FILTER_MAX)
+
struct qgroup_lookup {
struct rb_root root;
};
struct btrfs_qgroup {
struct rb_node rb_node;
+ struct rb_node sort_node;
+ /*
+ *all_parent_node is used to
+ *filter a qgroup''s all parent
+ */
+ struct rb_node all_parent_node;
u64 qgroupid;
/*
@@ -113,6 +121,8 @@ struct {
},
};
+static btrfs_qgroup_filter_func all_filter_funcs[];
+
void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column)
{
int i;
@@ -433,6 +443,205 @@ void __free_all_qgroups(struct qgroup_lookup *root_tree)
}
}
+static int filter_all_parent_insert(struct qgroup_lookup *sort_tree,
+ struct btrfs_qgroup *bq)
+{
+ struct rb_node **p = &sort_tree->root.rb_node;
+ struct rb_node *parent = NULL;
+ struct btrfs_qgroup *curr;
+ int ret;
+
+ while (*p) {
+ parent = *p;
+ curr = rb_entry(parent, struct btrfs_qgroup, all_parent_node);
+
+ ret = comp_entry_with_qgroupid(bq, curr, 0);
+ if (ret < 0)
+ p = &(*p)->rb_left;
+ else if (ret > 0)
+ p = &(*p)->rb_right;
+ else
+ return -EEXIST;
+ }
+ rb_link_node(&bq->all_parent_node, parent, p);
+ rb_insert_color(&bq->all_parent_node, &sort_tree->root);
+ return 0;
+}
+
+static int filter_by_all_parent(struct btrfs_qgroup *bq, u64 data)
+{
+ struct qgroup_lookup lookup;
+ struct qgroup_lookup *ql = &lookup;
+ struct btrfs_qgroup_list *list;
+ struct rb_node *n;
+ struct btrfs_qgroup *qgroup + (struct btrfs_qgroup *)(unsigned long)data;
+
+ if (data == 0)
+ return 0;
+ if (bq->qgroupid == qgroup->qgroupid)
+ return 1;
+
+ qgroup_lookup_init(ql);
+ filter_all_parent_insert(ql, qgroup);
+ n = rb_first(&ql->root);
+ while (n) {
+ qgroup = rb_entry(n, struct btrfs_qgroup, all_parent_node);
+ if (!list_empty(&qgroup->qgroups)) {
+ list_for_each_entry(list, &qgroup->qgroups,
+ next_qgroup) {
+ if ((list->qgroup)->qgroupid == bq->qgroupid)
+ return 1;
+ filter_all_parent_insert(ql, list->qgroup);
+ }
+ }
+ rb_erase(n, &ql->root);
+ n = rb_first(&ql->root);
+ }
+ return 0;
+}
+
+static btrfs_qgroup_filter_func all_filter_funcs[] = {
+ [BTRFS_QGROUP_FILTER_ALL_PARENT] = filter_by_all_parent,
+};
+
+struct btrfs_qgroup_filter_set *btrfs_qgroup_alloc_filter_set(void)
+{
+ struct btrfs_qgroup_filter_set *set;
+ int size;
+
+ size = sizeof(struct btrfs_qgroup_filter_set) +
+ BTRFS_QGROUP_NFILTERS_INCREASE *
+ sizeof(struct btrfs_qgroup_filter);
+ set = malloc(size);
+ if (!set) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+ memset(set, 0, size);
+ set->total = BTRFS_QGROUP_NFILTERS_INCREASE;
+
+ return set;
+}
+
+void btrfs_qgroup_free_filter_set(struct btrfs_qgroup_filter_set *filter_set)
+{
+ free(filter_set);
+}
+
+int btrfs_qgroup_setup_filter(struct btrfs_qgroup_filter_set **filter_set,
+ enum btrfs_qgroup_filter_enum filter, u64 data)
+{
+ struct btrfs_qgroup_filter_set *set = *filter_set;
+ int size;
+
+ BUG_ON(!set);
+ BUG_ON(filter >= BTRFS_QGROUP_FILTER_MAX);
+ BUG_ON(set->nfilters > set->total);
+
+ if (set->nfilters == set->total) {
+ size = set->total + BTRFS_QGROUP_NFILTERS_INCREASE;
+ size = sizeof(*set) + size * sizeof(struct btrfs_qgroup_filter);
+
+ set = realloc(set, size);
+ if (!set) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+ memset(&set->filters[set->total], 0,
+ BTRFS_QGROUP_NFILTERS_INCREASE *
+ sizeof(struct btrfs_qgroup_filter));
+ set->total += BTRFS_QGROUP_NFILTERS_INCREASE;
+ *filter_set = set;
+ }
+ BUG_ON(set->filters[set->nfilters].filter_func);
+ set->filters[set->nfilters].filter_func = all_filter_funcs[filter];
+ set->filters[set->nfilters].data = data;
+ set->nfilters++;
+ return 0;
+}
+
+static int filter_qgroup(struct btrfs_qgroup *bq,
+ struct btrfs_qgroup_filter_set *set)
+{
+ int i, ret;
+
+ if (!set || !set->nfilters)
+ return 1;
+ for (i = 0; i < set->nfilters; i++) {
+ if (!set->filters[i].filter_func)
+ break;
+ ret = set->filters[i].filter_func(bq, set->filters[i].data);
+ if (!ret)
+ return 0;
+ }
+ return 1;
+}
+
+static void pre_process_filter_set(struct qgroup_lookup *lookup,
+ struct btrfs_qgroup_filter_set *set)
+{
+ int i;
+ struct btrfs_qgroup *qgroup_for_filter = NULL;
+
+ for (i = 0; i < set->nfilters; i++) {
+
+ if (set->filters[i].filter_func == filter_by_all_parent) {
+ qgroup_for_filter = qgroup_tree_search(lookup,
+ set->filters[i].data);
+ set->filters[i].data + (u64)(unsigned long)qgroup_for_filter;
+ }
+ }
+}
+
+static int sort_tree_insert(struct qgroup_lookup *sort_tree,
+ struct btrfs_qgroup *bq)
+{
+ struct rb_node **p = &sort_tree->root.rb_node;
+ struct rb_node *parent = NULL;
+ struct btrfs_qgroup *curr;
+ int ret;
+
+ while (*p) {
+ parent = *p;
+ curr = rb_entry(parent, struct btrfs_qgroup, sort_node);
+
+ ret = comp_entry_with_qgroupid(bq, curr, 0);
+ if (ret < 0)
+ p = &(*p)->rb_left;
+ else if (ret > 0)
+ p = &(*p)->rb_right;
+ else
+ return -EEXIST;
+ }
+ rb_link_node(&bq->sort_node, parent, p);
+ rb_insert_color(&bq->sort_node, &sort_tree->root);
+ return 0;
+}
+
+static void __filter_all_qgroups(struct qgroup_lookup *all_qgroups,
+ struct qgroup_lookup *sort_tree,
+ struct btrfs_qgroup_filter_set *filter_set)
+{
+ struct rb_node *n;
+ struct btrfs_qgroup *entry;
+ int ret;
+
+ qgroup_lookup_init(sort_tree);
+ pre_process_filter_set(all_qgroups, filter_set);
+
+ n = rb_last(&all_qgroups->root);
+ while (n) {
+ entry = rb_entry(n, struct btrfs_qgroup, rb_node);
+
+ ret = filter_qgroup(entry, filter_set);
+ if (ret)
+ sort_tree_insert(sort_tree, entry);
+
+ n = rb_prev(n);
+ }
+}
static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
{
int ret;
@@ -565,28 +774,50 @@ static void print_all_qgroups(struct qgroup_lookup
*qgroup_lookup)
n = rb_first(&qgroup_lookup->root);
while (n) {
- entry = rb_entry(n, struct btrfs_qgroup, rb_node);
+ entry = rb_entry(n, struct btrfs_qgroup, sort_node);
print_single_qgroup_default(entry);
n = rb_next(n);
}
}
-int btrfs_show_qgroups(int fd)
+int btrfs_show_qgroups(int fd,
+ struct btrfs_qgroup_filter_set *filter_set)
{
struct qgroup_lookup qgroup_lookup;
+ struct qgroup_lookup sort_tree;
int ret;
ret = __qgroups_search(fd, &qgroup_lookup);
if (ret)
return ret;
+ __filter_all_qgroups(&qgroup_lookup, &sort_tree,
+ filter_set);
+ print_all_qgroups(&sort_tree);
- print_all_qgroups(&qgroup_lookup);
__free_all_qgroups(&qgroup_lookup);
-
+ btrfs_qgroup_free_filter_set(filter_set);
return ret;
}
+u64 btrfs_get_path_rootid(int fd)
+{
+ int ret;
+ struct btrfs_ioctl_ino_lookup_args args;
+
+ memset(&args, 0, sizeof(args));
+ args.objectid = BTRFS_FIRST_FREE_OBJECTID;
+
+ ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
+ if (ret < 0) {
+ fprintf(stderr,
+ "ERROR: can''t perform the search -%s\n",
+ strerror(errno));
+ return ret;
+ }
+ return args.treeid;
+}
+
u64 parse_qgroupid(char *p)
{
char *s = strchr(p, ''/'');
diff --git a/qgroup.h b/qgroup.h
index e7a65ba..bcc2b4b 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -22,6 +22,21 @@
#include "ioctl.h"
#include "kerncompat.h"
+struct btrfs_qgroup;
+
+typedef int (*btrfs_qgroup_filter_func)(struct btrfs_qgroup *, u64);
+
+struct btrfs_qgroup_filter {
+ btrfs_qgroup_filter_func filter_func;
+ u64 data;
+};
+
+struct btrfs_qgroup_filter_set {
+ int total;
+ int nfilters;
+ struct btrfs_qgroup_filter filters[0];
+};
+
enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_QGROUPID,
BTRFS_QGROUP_RFER,
@@ -33,9 +48,18 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_ALL,
};
-int btrfs_show_qgroups(int fd);
-void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column);
+enum btrfs_qgroup_filter_enum {
+ BTRFS_QGROUP_FILTER_ALL_PARENT,
+ BTRFS_QGROUP_FILTER_MAX,
+};
+u64 btrfs_get_path_rootid(int fd);
+int btrfs_show_qgroups(int fd, struct btrfs_qgroup_filter_set *);
+void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column);
+struct btrfs_qgroup_filter_set *btrfs_qgroup_alloc_filter_set(void);
+void btrfs_qgroup_free_filter_set(struct btrfs_qgroup_filter_set *filter_set);
+int btrfs_qgroup_setup_filter(struct btrfs_qgroup_filter_set **filter_set,
+ enum btrfs_qgroup_filter_enum, u64 data);
u64 parse_qgroupid(char *p);
int qgroup_inherit_size(struct btrfs_qgroup_inherit *p);
int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 07/12] Btrfs-progs: list all qgroups impact given path(exclude ancestral qgroups)
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch introduces ''-f'' option which can help you filter
the qgroups
by the path name, you may use it like:
btrfs qgroup show -f <path>
For example:
qgroupid(2/0)
/ \
/ \
qgroupid(1/0)
/ \
/ \
/ \
qgroupid(0/1) qgroupid(0/2)
sub1 sub2
/ \
/ \
dir1 file1
If we use the command:
btrfs qgroup show -f sub1/dir1
The result will output
0/1 -- --
''-f'' option helps you list all qgroups impact given path.
(exclude ancestral qgroups)
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 20 +++++++++++++++-----
qgroup.c | 16 +++++++++++++++-
qgroup.h | 1 +
3 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 7c6c917..5f1550a 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,7 +202,7 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pcreF <path>",
+ "btrfs qgroup show -pcreFf <path>",
"Show subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
@@ -210,6 +210,8 @@ static const char * const cmd_qgroup_show_usage[] = {
"-e print max exclusive size of qgroup",
"-F list all qgroups which impact the given path"
"(include ancestral qgroups)",
+ "-f list all qgroups which impact the given path"
+ "(exclude ancestral qgroups)",
NULL
};
@@ -229,7 +231,7 @@ static int cmd_qgroup_show(int argc, char **argv)
optind = 1;
while (1) {
- c = getopt(argc, argv, "pcreF");
+ c = getopt(argc, argv, "pcreFf");
if (c < 0)
break;
switch (c) {
@@ -252,6 +254,9 @@ static int cmd_qgroup_show(int argc, char **argv)
case ''F'':
filter_flag |= 0x1;
break;
+ case ''f'':
+ filter_flag |= 0x2;
+ break;
default:
usage(cmd_qgroup_show_usage);
}
@@ -268,9 +273,14 @@ static int cmd_qgroup_show(int argc, char **argv)
if (filter_flag) {
qgroupid = btrfs_get_path_rootid(fd);
- btrfs_qgroup_setup_filter(&filter_set,
- BTRFS_QGROUP_FILTER_ALL_PARENT,
- qgroupid);
+ if (filter_flag & 0x1)
+ btrfs_qgroup_setup_filter(&filter_set,
+ BTRFS_QGROUP_FILTER_ALL_PARENT,
+ qgroupid);
+ if (filter_flag & 0x2)
+ btrfs_qgroup_setup_filter(&filter_set,
+ BTRFS_QGROUP_FILTER_PARENT,
+ qgroupid);
}
ret = btrfs_show_qgroups(fd, filter_set);
e = errno;
diff --git a/qgroup.c b/qgroup.c
index 306b638..28772d6 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -468,6 +468,18 @@ static int filter_all_parent_insert(struct qgroup_lookup
*sort_tree,
return 0;
}
+static int filter_by_parent(struct btrfs_qgroup *bq, u64 data)
+{
+ struct btrfs_qgroup *qgroup + (struct btrfs_qgroup *)(unsigned long)data;
+
+ if (data == 0)
+ return 0;
+ if (qgroup->qgroupid == bq->qgroupid)
+ return 1;
+ return 0;
+}
+
static int filter_by_all_parent(struct btrfs_qgroup *bq, u64 data)
{
struct qgroup_lookup lookup;
@@ -502,6 +514,7 @@ static int filter_by_all_parent(struct btrfs_qgroup *bq, u64
data)
}
static btrfs_qgroup_filter_func all_filter_funcs[] = {
+ [BTRFS_QGROUP_FILTER_PARENT] = filter_by_parent,
[BTRFS_QGROUP_FILTER_ALL_PARENT] = filter_by_all_parent,
};
@@ -586,7 +599,8 @@ static void pre_process_filter_set(struct qgroup_lookup
*lookup,
for (i = 0; i < set->nfilters; i++) {
- if (set->filters[i].filter_func == filter_by_all_parent) {
+ if (set->filters[i].filter_func == filter_by_all_parent
+ || set->filters[i].filter_func == filter_by_parent) {
qgroup_for_filter = qgroup_tree_search(lookup,
set->filters[i].data);
set->filters[i].data diff --git a/qgroup.h b/qgroup.h
index bcc2b4b..5fcdd8a 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -49,6 +49,7 @@ enum btrfs_qgroup_column_enum {
};
enum btrfs_qgroup_filter_enum {
+ BTRFS_QGROUP_FILTER_PARENT,
BTRFS_QGROUP_FILTER_ALL_PARENT,
BTRFS_QGROUP_FILTER_MAX,
};
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 08/12] Btrfs-progs: enhance btrfs qgroup show to sort qgroups
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
You might want to list qgroups in order of some items, such as
''qgroupid'', ''rfer''
and so on, you can use ''--sort''. Now you can sort the qgroups
by ''qgroupid'',
''rfer'',''excl'',''max_rfer''
and ''max_excl''.
For example:
If you want to list qgroups in order of ''qgroupid''.
You can use the option like that:
btrfs qgroup show --sort=+/-qgroupid <path>
Here, ''+'' means the result is sorted by ascending order.
''-'' is by descending
order. If you don''t specify either ''+'' nor
''-'', the result is sorted by
default - ascending order.
If you want to combine sort items, you do it like that:
btrfs qgroup show --sort=-qgroupid,+rfer,max_rfer,excl <path>
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
cmds-qgroup.c | 25 +++++-
qgroup.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
qgroup.h | 33 +++++++-
3 files changed, 302 insertions(+), 12 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 5f1550a..4fe776c 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,7 +202,8 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pcreFf <path>",
+ "btrfs qgroup show -pcreFf "
+ "[--sort=qgroupid,rfer,excl,max_rfer,max_excl] <path>",
"Show subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
@@ -212,6 +213,11 @@ static const char * const cmd_qgroup_show_usage[] = {
"(include ancestral qgroups)",
"-f list all qgroups which impact the given path"
"(exclude ancestral qgroups)",
+ "--sort=qgroupid,rfer,excl,max_rfer,max_excl",
+ " list qgroups in order of qgroupid,"
+ "rfer,max_rfer or max_excl",
+ " you can use ''+'' or ''-'' in front of
each item.",
+ " (+:ascending, -:descending, ascending default)",
NULL
};
@@ -226,12 +232,19 @@ static int cmd_qgroup_show(int argc, char **argv)
u64 qgroupid;
int filter_flag = 0;
+ struct btrfs_qgroup_comparer_set *comparer_set;
struct btrfs_qgroup_filter_set *filter_set;
filter_set = btrfs_qgroup_alloc_filter_set();
+ comparer_set = btrfs_qgroup_alloc_comparer_set();
+ struct option long_options[] = {
+ {"sort", 1, NULL, ''S''},
+ {0, 0, 0, 0}
+ };
optind = 1;
while (1) {
- c = getopt(argc, argv, "pcreFf");
+ c = getopt_long(argc, argv, "pcreFf",
+ long_options, NULL);
if (c < 0)
break;
switch (c) {
@@ -257,6 +270,12 @@ static int cmd_qgroup_show(int argc, char **argv)
case ''f'':
filter_flag |= 0x2;
break;
+ case ''S'':
+ ret = btrfs_qgroup_parse_sort_string(optarg,
+ &comparer_set);
+ if (ret)
+ usage(cmd_qgroup_show_usage);
+ break;
default:
usage(cmd_qgroup_show_usage);
}
@@ -282,7 +301,7 @@ static int cmd_qgroup_show(int argc, char **argv)
BTRFS_QGROUP_FILTER_PARENT,
qgroupid);
}
- ret = btrfs_show_qgroups(fd, filter_set);
+ ret = btrfs_show_qgroups(fd, filter_set, comparer_set);
e = errno;
close_file_or_dir(fd, dirstream);
if (ret < 0)
diff --git a/qgroup.c b/qgroup.c
index 28772d6..84f5fc1 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -22,6 +22,7 @@
#include "ioctl.h"
#define BTRFS_QGROUP_NFILTERS_INCREASE (2 * BTRFS_QGROUP_FILTER_MAX)
+#define BTRFS_QGROUP_NCOMPS_INCREASE (2 * BTRFS_QGROUP_COMP_MAX)
struct qgroup_lookup {
struct rb_root root;
@@ -122,6 +123,7 @@ struct {
};
static btrfs_qgroup_filter_func all_filter_funcs[];
+static btrfs_qgroup_comp_func all_comp_funcs[];
void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column)
{
@@ -236,6 +238,188 @@ static int comp_entry_with_qgroupid(struct btrfs_qgroup
*entry1,
return is_descending ? -ret : ret;
}
+static int comp_entry_with_rfer(struct btrfs_qgroup *entry1,
+ struct btrfs_qgroup *entry2,
+ int is_descending)
+{
+ int ret;
+
+ if (entry1->rfer > entry2->rfer)
+ ret = 1;
+ else if (entry1->rfer < entry2->rfer)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
+static int comp_entry_with_excl(struct btrfs_qgroup *entry1,
+ struct btrfs_qgroup *entry2,
+ int is_descending)
+{
+ int ret;
+
+ if (entry1->excl > entry2->excl)
+ ret = 1;
+ else if (entry1->excl < entry2->excl)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
+static int comp_entry_with_max_rfer(struct btrfs_qgroup *entry1,
+ struct btrfs_qgroup *entry2,
+ int is_descending)
+{
+ int ret;
+
+ if (entry1->max_rfer > entry2->max_rfer)
+ ret = 1;
+ else if (entry1->max_rfer < entry2->max_rfer)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
+static int comp_entry_with_max_excl(struct btrfs_qgroup *entry1,
+ struct btrfs_qgroup *entry2,
+ int is_descending)
+{
+ int ret;
+
+ if (entry1->max_excl > entry2->max_excl)
+ ret = 1;
+ else if (entry1->max_excl < entry2->max_excl)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
+static btrfs_qgroup_comp_func all_comp_funcs[] = {
+ [BTRFS_QGROUP_COMP_QGROUPID] = comp_entry_with_qgroupid,
+ [BTRFS_QGROUP_COMP_RFER] = comp_entry_with_rfer,
+ [BTRFS_QGROUP_COMP_EXCL] = comp_entry_with_excl,
+ [BTRFS_QGROUP_COMP_MAX_RFER] = comp_entry_with_max_rfer,
+ [BTRFS_QGROUP_COMP_MAX_EXCL] = comp_entry_with_max_excl
+};
+
+static char *all_sort_items[] = {
+ [BTRFS_QGROUP_COMP_QGROUPID] = "qgroupid",
+ [BTRFS_QGROUP_COMP_RFER] = "rfer",
+ [BTRFS_QGROUP_COMP_EXCL] = "excl",
+ [BTRFS_QGROUP_COMP_MAX_RFER] = "max_rfer",
+ [BTRFS_QGROUP_COMP_MAX_EXCL] = "max_excl",
+ [BTRFS_QGROUP_COMP_MAX] = NULL,
+};
+
+static int btrfs_qgroup_get_sort_item(char *sort_name)
+{
+ int i;
+
+ for (i = 0; i < BTRFS_QGROUP_COMP_MAX; i++) {
+ if (strcmp(sort_name, all_sort_items[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+
+struct btrfs_qgroup_comparer_set *btrfs_qgroup_alloc_comparer_set(void)
+{
+ struct btrfs_qgroup_comparer_set *set;
+ int size;
+ size = sizeof(struct btrfs_qgroup_comparer_set) +
+ BTRFS_QGROUP_NCOMPS_INCREASE *
+ sizeof(struct btrfs_qgroup_comparer);
+ set = malloc(size);
+ if (!set) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+
+ memset(set, 0, size);
+ set->total = BTRFS_QGROUP_NCOMPS_INCREASE;
+
+ return set;
+}
+
+void btrfs_qgroup_free_comparer_set(struct btrfs_qgroup_comparer_set *comp_set)
+{
+ free(comp_set);
+}
+
+int btrfs_qgroup_setup_comparer(struct btrfs_qgroup_comparer_set **comp_set,
+ enum btrfs_qgroup_comp_enum comparer,
+ int is_descending)
+{
+ struct btrfs_qgroup_comparer_set *set = *comp_set;
+ int size;
+
+ BUG_ON(!set);
+ BUG_ON(comparer >= BTRFS_QGROUP_COMP_MAX);
+ BUG_ON(set->ncomps > set->total);
+
+ if (set->ncomps == set->total) {
+ size = set->total + BTRFS_QGROUP_NCOMPS_INCREASE;
+ size = sizeof(*set) +
+ size * sizeof(struct btrfs_qgroup_comparer);
+ set = realloc(set, size);
+ if (!set) {
+ fprintf(stderr, "memory allocation failed\n");
+ exit(1);
+ }
+
+ memset(&set->comps[set->total], 0,
+ BTRFS_QGROUP_NCOMPS_INCREASE *
+ sizeof(struct btrfs_qgroup_comparer));
+ set->total += BTRFS_QGROUP_NCOMPS_INCREASE;
+ *comp_set = set;
+ }
+
+ BUG_ON(set->comps[set->ncomps].comp_func);
+
+ set->comps[set->ncomps].comp_func = all_comp_funcs[comparer];
+ set->comps[set->ncomps].is_descending = is_descending;
+ set->ncomps++;
+ return 0;
+}
+
+static int sort_comp(struct btrfs_qgroup *entry1, struct btrfs_qgroup *entry2,
+ struct btrfs_qgroup_comparer_set *set)
+{
+ int qgroupid_compared = 0;
+ int i, ret = 0;
+
+ if (!set || !set->ncomps)
+ goto comp_qgroupid;
+
+ for (i = 0; i < set->ncomps; i++) {
+ if (!set->comps[i].comp_func)
+ break;
+
+ ret = set->comps[i].comp_func(entry1, entry2,
+ set->comps[i].is_descending);
+ if (ret)
+ return ret;
+
+ if (set->comps[i].comp_func == comp_entry_with_qgroupid)
+ qgroupid_compared = 1;
+ }
+
+ if (!qgroupid_compared) {
+comp_qgroupid:
+ ret = comp_entry_with_qgroupid(entry1, entry2, 0);
+ }
+
+ return ret;
+}
+
/*
* insert a new root into the tree. returns the existing root entry
* if one is already there. qgroupid is used
@@ -610,7 +794,8 @@ static void pre_process_filter_set(struct qgroup_lookup
*lookup,
}
static int sort_tree_insert(struct qgroup_lookup *sort_tree,
- struct btrfs_qgroup *bq)
+ struct btrfs_qgroup *bq,
+ struct btrfs_qgroup_comparer_set *comp_set)
{
struct rb_node **p = &sort_tree->root.rb_node;
struct rb_node *parent = NULL;
@@ -621,7 +806,7 @@ static int sort_tree_insert(struct qgroup_lookup *sort_tree,
parent = *p;
curr = rb_entry(parent, struct btrfs_qgroup, sort_node);
- ret = comp_entry_with_qgroupid(bq, curr, 0);
+ ret = sort_comp(bq, curr, comp_set);
if (ret < 0)
p = &(*p)->rb_left;
else if (ret > 0)
@@ -634,9 +819,10 @@ static int sort_tree_insert(struct qgroup_lookup
*sort_tree,
return 0;
}
-static void __filter_all_qgroups(struct qgroup_lookup *all_qgroups,
+static void __filter_and_sort_qgroups(struct qgroup_lookup *all_qgroups,
struct qgroup_lookup *sort_tree,
- struct btrfs_qgroup_filter_set *filter_set)
+ struct btrfs_qgroup_filter_set *filter_set,
+ struct btrfs_qgroup_comparer_set *comp_set)
{
struct rb_node *n;
struct btrfs_qgroup *entry;
@@ -651,7 +837,7 @@ static void __filter_all_qgroups(struct qgroup_lookup
*all_qgroups,
ret = filter_qgroup(entry, filter_set);
if (ret)
- sort_tree_insert(sort_tree, entry);
+ sort_tree_insert(sort_tree, entry, comp_set);
n = rb_prev(n);
}
@@ -795,7 +981,8 @@ static void print_all_qgroups(struct qgroup_lookup
*qgroup_lookup)
}
int btrfs_show_qgroups(int fd,
- struct btrfs_qgroup_filter_set *filter_set)
+ struct btrfs_qgroup_filter_set *filter_set,
+ struct btrfs_qgroup_comparer_set *comp_set)
{
struct qgroup_lookup qgroup_lookup;
@@ -805,8 +992,8 @@ int btrfs_show_qgroups(int fd,
ret = __qgroups_search(fd, &qgroup_lookup);
if (ret)
return ret;
- __filter_all_qgroups(&qgroup_lookup, &sort_tree,
- filter_set);
+ __filter_and_sort_qgroups(&qgroup_lookup, &sort_tree,
+ filter_set, comp_set);
print_all_qgroups(&sort_tree);
__free_all_qgroups(&qgroup_lookup);
@@ -832,6 +1019,59 @@ u64 btrfs_get_path_rootid(int fd)
return args.treeid;
}
+int btrfs_qgroup_parse_sort_string(char *opt_arg,
+ struct btrfs_qgroup_comparer_set **comps)
+{
+ int order;
+ int flag;
+ char *p;
+ char **ptr_argv;
+ int what_to_sort;
+
+ while ((p = strtok(opt_arg, ",")) != NULL) {
+ flag = 0;
+ ptr_argv = all_sort_items;
+
+ while (*ptr_argv) {
+ if (strcmp(*ptr_argv, p) == 0) {
+ flag = 1;
+ break;
+ } else {
+ p++;
+ if (strcmp(*ptr_argv, p) == 0) {
+ flag = 1;
+ p--;
+ break;
+ }
+ p--;
+ }
+ ptr_argv++;
+ }
+
+ if (flag == 0)
+ return -1;
+
+ else {
+ if (*p == ''+'') {
+ order = 0;
+ p++;
+ } else if (*p == ''-'') {
+ order = 1;
+ p++;
+ } else
+ order = 0;
+
+ what_to_sort = btrfs_qgroup_get_sort_item(p);
+ if (what_to_sort < 0)
+ return -1;
+ btrfs_qgroup_setup_comparer(comps, what_to_sort, order);
+ }
+ opt_arg = NULL;
+ }
+
+ return 0;
+}
+
u64 parse_qgroupid(char *p)
{
char *s = strchr(p, ''/'');
diff --git a/qgroup.h b/qgroup.h
index 5fcdd8a..653cf1c 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -25,18 +25,32 @@
struct btrfs_qgroup;
typedef int (*btrfs_qgroup_filter_func)(struct btrfs_qgroup *, u64);
+typedef int (*btrfs_qgroup_comp_func)(struct btrfs_qgroup *,
+ struct btrfs_qgroup *, int);
+
struct btrfs_qgroup_filter {
btrfs_qgroup_filter_func filter_func;
u64 data;
};
+struct btrfs_qgroup_comparer {
+ btrfs_qgroup_comp_func comp_func;
+ int is_descending;
+};
+
struct btrfs_qgroup_filter_set {
int total;
int nfilters;
struct btrfs_qgroup_filter filters[0];
};
+struct btrfs_qgroup_comparer_set {
+ int total;
+ int ncomps;
+ struct btrfs_qgroup_comparer comps[0];
+};
+
enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_QGROUPID,
BTRFS_QGROUP_RFER,
@@ -48,19 +62,36 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_ALL,
};
+enum btrfs_qgroup_comp_enum {
+ BTRFS_QGROUP_COMP_QGROUPID,
+ BTRFS_QGROUP_COMP_RFER,
+ BTRFS_QGROUP_COMP_EXCL,
+ BTRFS_QGROUP_COMP_MAX_RFER,
+ BTRFS_QGROUP_COMP_MAX_EXCL,
+ BTRFS_QGROUP_COMP_MAX
+};
+
enum btrfs_qgroup_filter_enum {
BTRFS_QGROUP_FILTER_PARENT,
BTRFS_QGROUP_FILTER_ALL_PARENT,
BTRFS_QGROUP_FILTER_MAX,
};
+int btrfs_qgroup_parse_sort_string(char *opt_arg,
+ struct btrfs_qgroup_comparer_set **comps);
u64 btrfs_get_path_rootid(int fd);
-int btrfs_show_qgroups(int fd, struct btrfs_qgroup_filter_set *);
+int btrfs_show_qgroups(int fd, struct btrfs_qgroup_filter_set *,
+ struct btrfs_qgroup_comparer_set *);
void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column);
struct btrfs_qgroup_filter_set *btrfs_qgroup_alloc_filter_set(void);
void btrfs_qgroup_free_filter_set(struct btrfs_qgroup_filter_set *filter_set);
int btrfs_qgroup_setup_filter(struct btrfs_qgroup_filter_set **filter_set,
enum btrfs_qgroup_filter_enum, u64 data);
+struct btrfs_qgroup_comparer_set *btrfs_qgroup_alloc_comparer_set(void);
+void btrfs_qgroup_free_comparer_set(struct btrfs_qgroup_comparer_set
*comp_set);
+int btrfs_qgroup_setup_comparer(struct btrfs_qgroup_comparer_set **comp_set,
+ enum btrfs_qgroup_comp_enum comparer,
+ int is_descending);
u64 parse_qgroupid(char *p);
int qgroup_inherit_size(struct btrfs_qgroup_inherit *p);
int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 09/12] Btrfs-progs: enhance btrfs qgroup to print the result as a table
From: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
This patch enhance to print the result as a table.
You can use it like:
btrfs qgroup show <path>
However, to table the result better, we make ''-p'' and
''-c'' not present
at the same time.
For example:
btrfs qgroup show -pr <path>
The result will output as the follow format:
qgroupid rfer excl max_excl parent
-------- ---- ---- -------- ------
0/265 1289752576 1289752576 0 ---
1/0 0 0 10999511627776 2/0,3/0
2/0 0 0 0 ---
3/0 0 0 0 ---
Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
---
qgroup.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 189 insertions(+), 22 deletions(-)
diff --git a/qgroup.c b/qgroup.c
index 84f5fc1..fa905fa 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -80,40 +80,48 @@ struct {
char *name;
char *column_name;
int need_print;
+ int max_len;
} btrfs_qgroup_columns[] = {
{
.name = "qgroupid",
.column_name = "Qgroupid",
.need_print = 1,
+ .max_len = 8,
},
{
.name = "rfer",
.column_name = "Rfer",
.need_print = 1,
+ .max_len = 4,
},
{
.name = "excl",
.column_name = "Excl",
.need_print = 1,
+ .max_len = 4,
},
{ .name = "max_rfer",
.column_name = "Max_rfer",
.need_print = 0,
+ .max_len = 8,
},
{
.name = "max_excl",
.column_name = "Max_excl",
.need_print = 0,
+ .max_len = 8,
},
{
.name = "parent",
.column_name = "Parent",
.need_print = 0,
+ .max_len = 7,
},
{
.name = "child",
.column_name = "Child",
.need_print = 0,
+ .max_len = 5,
},
{
.name = NULL,
@@ -139,69 +147,91 @@ void btrfs_qgroup_setup_print_column(enum
btrfs_qgroup_column_enum column)
btrfs_qgroup_columns[i].need_print = 1;
}
-static void print_parent_column(struct btrfs_qgroup *qgroup)
+static int print_parent_column(struct btrfs_qgroup *qgroup)
{
struct btrfs_qgroup_list *list = NULL;
+ int len = 0;
list_for_each_entry(list, &qgroup->qgroups, next_qgroup) {
- printf("%llu/%llu", (list->qgroup)->qgroupid >> 48,
- ((1ll << 48) - 1) & (list->qgroup)->qgroupid);
+ len += printf("%llu/%llu", (list->qgroup)->qgroupid >>
48,
+ ((1ll << 48) - 1) & (list->qgroup)->qgroupid);
if (!list_is_last(&list->next_qgroup, &qgroup->qgroups))
- printf(",");
+ len += printf(",");
}
if (list_empty(&qgroup->qgroups))
- printf("---");
+ len += printf("---");
+
+ return len;
}
-static void print_child_column(struct btrfs_qgroup *qgroup)
+static int print_child_column(struct btrfs_qgroup *qgroup)
{
struct btrfs_qgroup_list *list = NULL;
+ int len = 0;
list_for_each_entry(list, &qgroup->members, next_member) {
- printf("%llu/%llu", (list->member)->qgroupid >> 48,
- ((1ll << 48) - 1) & (list->member)->qgroupid);
+ len += printf("%llu/%llu", (list->member)->qgroupid >>
48,
+ ((1ll << 48) - 1) & (list->member)->qgroupid);
if (!list_is_last(&list->next_member, &qgroup->members))
- printf(",");
+ len += printf(",");
}
if (list_empty(&qgroup->members))
- printf("---");
+ len += printf("---");
+
+ return len;
+}
+
+static void print_qgroup_column_add_blank(enum btrfs_qgroup_column_enum column,
+ int len)
+{
+ len = btrfs_qgroup_columns[column].max_len - len;
+ while (len--)
+ printf(" ");
}
static void print_qgroup_column(struct btrfs_qgroup *qgroup,
enum btrfs_qgroup_column_enum column)
{
BUG_ON(column >= BTRFS_QGROUP_ALL || column < 0);
+ int len;
switch (column) {
case BTRFS_QGROUP_QGROUPID:
- printf("%llu/%llu", qgroup->qgroupid >> 48,
- ((1ll << 48) - 1) & qgroup->qgroupid);
+ len = printf("%llu/%llu", qgroup->qgroupid >> 48,
+ ((1ll << 48) - 1) & qgroup->qgroupid);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_QGROUPID, len);
break;
case BTRFS_QGROUP_RFER:
- printf("%lld", qgroup->rfer);
+ len = printf("%lld", qgroup->rfer);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_RFER, len);
break;
case BTRFS_QGROUP_EXCL:
- printf("%lld", qgroup->excl);
+ len = printf("%lld", qgroup->excl);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_EXCL, len);
break;
case BTRFS_QGROUP_PARENT:
- print_parent_column(qgroup);
+ len = print_parent_column(qgroup);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_PARENT, len);
break;
case BTRFS_QGROUP_MAX_RFER:
- printf("%llu", qgroup->max_rfer);
+ len = printf("%llu", qgroup->max_rfer);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_MAX_RFER, len);
break;
case BTRFS_QGROUP_MAX_EXCL:
- printf("%llu", qgroup->max_excl);
+ len = printf("%llu", qgroup->max_excl);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_MAX_EXCL, len);
break;
case BTRFS_QGROUP_CHILD:
- print_child_column(qgroup);
+ len = print_child_column(qgroup);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_CHILD, len);
break;
default:
break;
}
}
-static void print_single_qgroup_default(struct btrfs_qgroup *qgroup)
+static void print_single_qgroup_table(struct btrfs_qgroup *qgroup)
{
int i;
@@ -210,7 +240,39 @@ static void print_single_qgroup_default(struct btrfs_qgroup
*qgroup)
continue;
print_qgroup_column(qgroup, i);
- if (i != BTRFS_QGROUP_ALL - 1)
+ if (i != BTRFS_QGROUP_CHILD)
+ printf(" ");
+ }
+ printf("\n");
+}
+
+static void print_table_head()
+{
+ int i;
+ int len;
+
+ for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
+ if (!btrfs_qgroup_columns[i].need_print)
+ continue;
+ printf("%s", btrfs_qgroup_columns[i].name);
+ len = btrfs_qgroup_columns[i].max_len -
+ strlen(btrfs_qgroup_columns[i].name);
+ while (len--)
+ printf(" ");
+ printf(" ");
+ }
+ printf("\n");
+ for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
+ if (!btrfs_qgroup_columns[i].need_print)
+ continue;
+
+ len = strlen(btrfs_qgroup_columns[i].name);
+ while (len--)
+ printf("-");
+ len = btrfs_qgroup_columns[i].max_len -
+ strlen(btrfs_qgroup_columns[i].name);
+ printf(" ");
+ while (len--)
printf(" ");
}
printf("\n");
@@ -819,6 +881,107 @@ static int sort_tree_insert(struct qgroup_lookup
*sort_tree,
return 0;
}
+static void __update_columns_max_len(struct btrfs_qgroup *bq,
+ enum btrfs_qgroup_column_enum column)
+{
+ BUG_ON(column >= BTRFS_QGROUP_ALL || column < 0);
+ struct btrfs_qgroup_list *list = NULL;
+ char tmp[100];
+ char *tmp1;
+ int len;
+
+ switch (column) {
+
+ case BTRFS_QGROUP_QGROUPID:
+ sprintf(tmp, "%llu/%llu", (bq->qgroupid >> 48),
+ bq->qgroupid & ((1ll << 48) - 1));
+ len = strlen(tmp);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
+ case BTRFS_QGROUP_RFER:
+ sprintf(tmp, "%llu", bq->rfer);
+ len = strlen(tmp);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
+ case BTRFS_QGROUP_EXCL:
+ sprintf(tmp, "%llu", bq->excl);
+ len = strlen(tmp);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
+ case BTRFS_QGROUP_MAX_RFER:
+ sprintf(tmp, "%llu", bq->max_rfer);
+ len = strlen(tmp);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
+ case BTRFS_QGROUP_MAX_EXCL:
+ sprintf(tmp, "%llu", bq->max_excl);
+ len = strlen(tmp);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
+ case BTRFS_QGROUP_PARENT:
+ len = 0;
+ list_for_each_entry(list, &bq->qgroups, next_qgroup)
+ len++;
+ tmp1 = calloc(1, 22 * len + 1);
+ if (!tmp1) {
+ perror("malloc fails");
+ exit(1);
+ }
+ list_for_each_entry(list, &bq->qgroups, next_qgroup) {
+ sprintf(tmp, "%llu/%llu", (list->qgroup)->qgroupid >>
48,
+ ((1ll << 48) - 1) & (list->qgroup)->qgroupid);
+ strcat(tmp1, tmp);
+ if (!list_is_last(&list->next_qgroup, &bq->qgroups))
+ strcat(tmp1, ",");
+ }
+ len = strlen(tmp1);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ free(tmp1);
+ break;
+ case BTRFS_QGROUP_CHILD:
+ len = 0;
+ list_for_each_entry(list, &bq->members, next_member)
+ len++;
+ tmp1 = calloc(1, 22 * len + 1);
+ if (!tmp1) {
+ perror("malloc fails");
+ exit(1);
+ }
+ list_for_each_entry(list, &bq->members, next_member) {
+ sprintf(tmp, "%llu/%llu", (list->qgroup)->qgroupid >>
48,
+ ((1ll << 48) - 1) & (list->qgroup)->qgroupid);
+ strcat(tmp1, tmp);
+ if (!list_is_last(&list->next_member, &bq->members))
+ strcat(tmp1, ",");
+ }
+ len = strlen(tmp1);
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ free(tmp1);
+ break;
+ default:
+ break;
+ }
+
+}
+
+static void update_columns_max_len(struct btrfs_qgroup *bq)
+{
+ int i;
+
+ for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
+ if (!btrfs_qgroup_columns[i].need_print)
+ continue;
+ __update_columns_max_len(bq, i);
+ }
+}
+
static void __filter_and_sort_qgroups(struct qgroup_lookup *all_qgroups,
struct qgroup_lookup *sort_tree,
struct btrfs_qgroup_filter_set *filter_set,
@@ -836,9 +999,11 @@ static void __filter_and_sort_qgroups(struct qgroup_lookup
*all_qgroups,
entry = rb_entry(n, struct btrfs_qgroup, rb_node);
ret = filter_qgroup(entry, filter_set);
- if (ret)
+ if (ret) {
sort_tree_insert(sort_tree, entry, comp_set);
+ update_columns_max_len(entry);
+ }
n = rb_prev(n);
}
}
@@ -972,10 +1137,12 @@ static void print_all_qgroups(struct qgroup_lookup
*qgroup_lookup)
struct rb_node *n;
struct btrfs_qgroup *entry;
+ print_table_head();
+
n = rb_first(&qgroup_lookup->root);
while (n) {
entry = rb_entry(n, struct btrfs_qgroup, sort_node);
- print_single_qgroup_default(entry);
+ print_single_qgroup_table(entry);
n = rb_next(n);
}
}
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
You can use it like:
btrfs qgroup show --block-size=m <mnt>
Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E.
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
---
cmds-qgroup.c | 16 +++++++++---
qgroup.c | 78 ++++++++++++++++++++++++++++++++++++++++-------------------
qgroup.h | 3 ++-
utils.c | 50 ++++++++++++++++++++++++++++++++++++++
utils.h | 2 ++
5 files changed, 120 insertions(+), 29 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 4fe776c..912cc42 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -202,8 +202,7 @@ static int cmd_qgroup_destroy(int argc, char **argv)
}
static const char * const cmd_qgroup_show_usage[] = {
- "btrfs qgroup show -pcreFf "
- "[--sort=qgroupid,rfer,excl,max_rfer,max_excl] <path>",
+ "btrfs qgroup show [options] <path>",
"Show subvolume quota groups.",
"-p print parent qgroup id",
"-c print child qgroup id",
@@ -218,6 +217,8 @@ static const char * const cmd_qgroup_show_usage[] = {
"rfer,max_rfer or max_excl",
" you can use ''+'' or ''-'' in front of
each item.",
" (+:ascending, -:descending, ascending default)",
+ "--block-size=BLOCK_SIZE",
+ " Here BLOCK_SIZE can be k,K,m,M,g,G,t,T,p,P,e,E",
NULL
};
@@ -231,6 +232,7 @@ static int cmd_qgroup_show(int argc, char **argv)
int c;
u64 qgroupid;
int filter_flag = 0;
+ int block_size = 0;
struct btrfs_qgroup_comparer_set *comparer_set;
struct btrfs_qgroup_filter_set *filter_set;
@@ -238,6 +240,7 @@ static int cmd_qgroup_show(int argc, char **argv)
comparer_set = btrfs_qgroup_alloc_comparer_set();
struct option long_options[] = {
{"sort", 1, NULL, ''S''},
+ {"block-size", 1, NULL, ''B''},
{0, 0, 0, 0}
};
@@ -276,6 +279,13 @@ static int cmd_qgroup_show(int argc, char **argv)
if (ret)
usage(cmd_qgroup_show_usage);
break;
+ case ''B'':
+ block_size = parse_block_size(optarg);
+ if (block_size < 0) {
+ fprintf(stderr, "Invalid block size\n");
+ usage(cmd_qgroup_show_usage);
+ }
+ break;
default:
usage(cmd_qgroup_show_usage);
}
@@ -301,7 +311,7 @@ static int cmd_qgroup_show(int argc, char **argv)
BTRFS_QGROUP_FILTER_PARENT,
qgroupid);
}
- ret = btrfs_show_qgroups(fd, filter_set, comparer_set);
+ ret = btrfs_show_qgroups(fd, filter_set, comparer_set, block_size);
e = errno;
close_file_or_dir(fd, dirstream);
if (ret < 0)
diff --git a/qgroup.c b/qgroup.c
index fa905fa..0de6c7d 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -20,6 +20,7 @@
#include <sys/ioctl.h>
#include "ctree.h"
#include "ioctl.h"
+#include "utils.h"
#define BTRFS_QGROUP_NFILTERS_INCREASE (2 * BTRFS_QGROUP_FILTER_MAX)
#define BTRFS_QGROUP_NCOMPS_INCREASE (2 * BTRFS_QGROUP_COMP_MAX)
@@ -190,10 +191,12 @@ static void print_qgroup_column_add_blank(enum
btrfs_qgroup_column_enum column,
}
static void print_qgroup_column(struct btrfs_qgroup *qgroup,
- enum btrfs_qgroup_column_enum column)
+ enum btrfs_qgroup_column_enum column,
+ int block_size)
{
BUG_ON(column >= BTRFS_QGROUP_ALL || column < 0);
int len;
+ char tmp[100];
switch (column) {
@@ -203,11 +206,17 @@ static void print_qgroup_column(struct btrfs_qgroup
*qgroup,
print_qgroup_column_add_blank(BTRFS_QGROUP_QGROUPID, len);
break;
case BTRFS_QGROUP_RFER:
- len = printf("%lld", qgroup->rfer);
+ len = block_size_snprintf((signed long long)qgroup->rfer, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
+ printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_RFER, len);
break;
case BTRFS_QGROUP_EXCL:
- len = printf("%lld", qgroup->excl);
+ len = block_size_snprintf((signed long long)qgroup->excl, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
+ printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_EXCL, len);
break;
case BTRFS_QGROUP_PARENT:
@@ -215,11 +224,17 @@ static void print_qgroup_column(struct btrfs_qgroup
*qgroup,
print_qgroup_column_add_blank(BTRFS_QGROUP_PARENT, len);
break;
case BTRFS_QGROUP_MAX_RFER:
- len = printf("%llu", qgroup->max_rfer);
+ len = block_size_snprintf(qgroup->max_rfer, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
+ printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_MAX_RFER, len);
break;
case BTRFS_QGROUP_MAX_EXCL:
- len = printf("%llu", qgroup->max_excl);
+ len = block_size_snprintf(qgroup->max_excl, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
+ printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_MAX_EXCL, len);
break;
case BTRFS_QGROUP_CHILD:
@@ -231,14 +246,15 @@ static void print_qgroup_column(struct btrfs_qgroup
*qgroup,
}
}
-static void print_single_qgroup_table(struct btrfs_qgroup *qgroup)
+static void print_single_qgroup_table(struct btrfs_qgroup *qgroup,
+ int block_size)
{
int i;
for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
if (!btrfs_qgroup_columns[i].need_print)
continue;
- print_qgroup_column(qgroup, i);
+ print_qgroup_column(qgroup, i, block_size);
if (i != BTRFS_QGROUP_CHILD)
printf(" ");
@@ -882,7 +898,8 @@ static int sort_tree_insert(struct qgroup_lookup *sort_tree,
}
static void __update_columns_max_len(struct btrfs_qgroup *bq,
- enum btrfs_qgroup_column_enum column)
+ enum btrfs_qgroup_column_enum column,
+ int block_size)
{
BUG_ON(column >= BTRFS_QGROUP_ALL || column < 0);
struct btrfs_qgroup_list *list = NULL;
@@ -900,26 +917,30 @@ static void __update_columns_max_len(struct btrfs_qgroup
*bq,
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_RFER:
- sprintf(tmp, "%llu", bq->rfer);
- len = strlen(tmp);
+ len = block_size_snprintf((signed long long)bq->rfer, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_EXCL:
- sprintf(tmp, "%llu", bq->excl);
- len = strlen(tmp);
+ len = block_size_snprintf((signed long long)bq->excl, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_MAX_RFER:
- sprintf(tmp, "%llu", bq->max_rfer);
- len = strlen(tmp);
+ len = block_size_snprintf(bq->max_rfer, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_MAX_EXCL:
- sprintf(tmp, "%llu", bq->max_excl);
- len = strlen(tmp);
+ len = block_size_snprintf(bq->max_excl, tmp,
+ sizeof(tmp), block_size);
+ BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
@@ -971,21 +992,22 @@ static void __update_columns_max_len(struct btrfs_qgroup
*bq,
}
-static void update_columns_max_len(struct btrfs_qgroup *bq)
+static void update_columns_max_len(struct btrfs_qgroup *bq, int block_size)
{
int i;
for (i = 0; i < BTRFS_QGROUP_ALL; i++) {
if (!btrfs_qgroup_columns[i].need_print)
continue;
- __update_columns_max_len(bq, i);
+ __update_columns_max_len(bq, i, block_size);
}
}
static void __filter_and_sort_qgroups(struct qgroup_lookup *all_qgroups,
struct qgroup_lookup *sort_tree,
struct btrfs_qgroup_filter_set *filter_set,
- struct btrfs_qgroup_comparer_set *comp_set)
+ struct btrfs_qgroup_comparer_set *comp_set,
+ int block_size)
{
struct rb_node *n;
struct btrfs_qgroup *entry;
@@ -1002,7 +1024,7 @@ static void __filter_and_sort_qgroups(struct qgroup_lookup
*all_qgroups,
if (ret) {
sort_tree_insert(sort_tree, entry, comp_set);
- update_columns_max_len(entry);
+ update_columns_max_len(entry, block_size);
}
n = rb_prev(n);
}
@@ -1131,7 +1153,8 @@ done:
return ret;
}
-static void print_all_qgroups(struct qgroup_lookup *qgroup_lookup)
+static void print_all_qgroups(struct qgroup_lookup *qgroup_lookup,
+ int block_size)
{
struct rb_node *n;
@@ -1142,14 +1165,15 @@ static void print_all_qgroups(struct qgroup_lookup
*qgroup_lookup)
n = rb_first(&qgroup_lookup->root);
while (n) {
entry = rb_entry(n, struct btrfs_qgroup, sort_node);
- print_single_qgroup_table(entry);
+ print_single_qgroup_table(entry, block_size);
n = rb_next(n);
}
}
int btrfs_show_qgroups(int fd,
struct btrfs_qgroup_filter_set *filter_set,
- struct btrfs_qgroup_comparer_set *comp_set)
+ struct btrfs_qgroup_comparer_set *comp_set,
+ int block_size)
{
struct qgroup_lookup qgroup_lookup;
@@ -1159,9 +1183,13 @@ int btrfs_show_qgroups(int fd,
ret = __qgroups_search(fd, &qgroup_lookup);
if (ret)
return ret;
+ /*
+ * we pass block_size here because we need it to
+ * update max columns.
+ */
__filter_and_sort_qgroups(&qgroup_lookup, &sort_tree,
- filter_set, comp_set);
- print_all_qgroups(&sort_tree);
+ filter_set, comp_set, block_size);
+ print_all_qgroups(&sort_tree, block_size);
__free_all_qgroups(&qgroup_lookup);
btrfs_qgroup_free_filter_set(filter_set);
diff --git a/qgroup.h b/qgroup.h
index 653cf1c..1113a24 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -81,7 +81,8 @@ int btrfs_qgroup_parse_sort_string(char *opt_arg,
struct btrfs_qgroup_comparer_set **comps);
u64 btrfs_get_path_rootid(int fd);
int btrfs_show_qgroups(int fd, struct btrfs_qgroup_filter_set *,
- struct btrfs_qgroup_comparer_set *);
+ struct btrfs_qgroup_comparer_set *,
+ int block_size);
void btrfs_qgroup_setup_print_column(enum btrfs_qgroup_column_enum column);
struct btrfs_qgroup_filter_set *btrfs_qgroup_alloc_filter_set(void);
void btrfs_qgroup_free_filter_set(struct btrfs_qgroup_filter_set *filter_set);
diff --git a/utils.c b/utils.c
index c6022fc..4ed7405 100644
--- a/utils.c
+++ b/utils.c
@@ -1219,6 +1219,56 @@ void pretty_size_snprintf(u64 size, char *str, size_t
str_bytes)
snprintf(str, str_bytes, "%.2f%s", fraction, size_strs[num_divs]);
}
+int parse_block_size(const char *ch)
+{
+ int len = strlen(ch);
+ if (len != 1)
+ return -1;
+
+ switch (ch[0]) {
+ case ''k'':
+ case ''K'':
+ return 1;
+ case ''m'':
+ case ''M'':
+ return 2;
+ case ''g'':
+ case ''G'':
+ return 3;
+ case ''t'':
+ case ''T'':
+ return 4;
+ case ''p'':
+ case ''P'':
+ return 5;
+ case ''e'':
+ case ''E'':
+ return 6;
+ default:
+ return -1;
+ }
+
+ return -1;
+}
+
+int block_size_snprintf(double size, char *str, size_t str_bytes, int format)
+{
+ double fraction = size;
+ int cnt = format;
+
+ if (str_bytes == 0)
+ return 0;
+ if (format < 0 || format >= ARRAY_SIZE(size_strs))
+ return -1;
+ if (format == 0)
+ return snprintf(str, str_bytes, "%.f", size);
+
+ while (format--)
+ fraction /= 1024;
+
+ return snprintf(str, str_bytes, "%.2f%s", fraction, size_strs[cnt]);
+}
+
/*
* __strncpy__null - strncpy with null termination
* @dest: the target array
diff --git a/utils.h b/utils.h
index 19f028f..40b662d 100644
--- a/utils.h
+++ b/utils.h
@@ -56,6 +56,8 @@ void pretty_size_snprintf(u64 size, char *str, size_t
str_bytes);
_str; \
})
+int parse_block_size(const char *ch);
+int block_size_snprintf(double size, char *str, size_t str_bytes, int format);
int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
u64 parse_size(char *s);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 11/12] Btrfs-progs: make pretty_size_snprintf() return len
Sometimes, we need to catch length of snprintf() in pretty_size_snprintf().
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
---
utils.c | 9 +++++----
utils.h | 4 ++--
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/utils.c b/utils.c
index 4ed7405..7b42022 100644
--- a/utils.c
+++ b/utils.c
@@ -1190,13 +1190,13 @@ out:
}
static char *size_strs[] = { "", "KiB", "MiB",
"GiB", "TiB", "PiB", "EiB"};
-void pretty_size_snprintf(u64 size, char *str, size_t str_bytes)
+int pretty_size_snprintf(double size, char *str, size_t str_bytes)
{
int num_divs = 0;
float fraction;
if (str_bytes == 0)
- return;
+ return 0;
if( size < 1024 ){
fraction = size;
@@ -1212,11 +1212,12 @@ void pretty_size_snprintf(u64 size, char *str, size_t
str_bytes)
if (num_divs >= ARRAY_SIZE(size_strs)) {
str[0] = ''\0'';
- return;
+ return -1;
}
fraction = (float)last_size / 1024;
}
- snprintf(str, str_bytes, "%.2f%s", fraction, size_strs[num_divs]);
+ return snprintf(str, str_bytes, "%.2f%s", fraction,
+ size_strs[num_divs]);
}
int parse_block_size(const char *ch)
diff --git a/utils.h b/utils.h
index 40b662d..240b590 100644
--- a/utils.h
+++ b/utils.h
@@ -48,11 +48,11 @@ int check_mounted_where(int fd, const char *file, char
*where, int size,
int btrfs_device_already_in_root(struct btrfs_root *root, int fd,
int super_offset);
-void pretty_size_snprintf(u64 size, char *str, size_t str_bytes);
+int pretty_size_snprintf(double size, char *str, size_t str_bytes);
#define pretty_size(size) \
({ \
static __thread char _str[24]; \
- pretty_size_snprintf((size), _str, sizeof(_str)); \
+ (void)pretty_size_snprintf((size), _str, sizeof(_str)); \
_str; \
})
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Wang Shilong
2013-Oct-07 07:21 UTC
[PATCH v3 12/12] Btrfs-progs: add ''-h'' options to print sizes in human readable format
This is a short cut for people who don''t want to use
''--block-size'',it
will print sizes in human readable format.
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
---
cmds-qgroup.c | 17 +++++++++++++---
qgroup.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++------------
qgroup.h | 2 ++
3 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 912cc42..7ea752b 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -204,6 +204,7 @@ static int cmd_qgroup_destroy(int argc, char **argv)
static const char * const cmd_qgroup_show_usage[] = {
"btrfs qgroup show [options] <path>",
"Show subvolume quota groups.",
+ "-h print size in human readable format",
"-p print parent qgroup id",
"-c print child qgroup id",
"-r print max referenced size of qgroup",
@@ -246,7 +247,7 @@ static int cmd_qgroup_show(int argc, char **argv)
optind = 1;
while (1) {
- c = getopt_long(argc, argv, "pcreFf",
+ c = getopt_long(argc, argv, "pcreFfh",
long_options, NULL);
if (c < 0)
break;
@@ -280,11 +281,21 @@ static int cmd_qgroup_show(int argc, char **argv)
usage(cmd_qgroup_show_usage);
break;
case ''B'':
- block_size = parse_block_size(optarg);
- if (block_size < 0) {
+ ret = parse_block_size(optarg);
+ if (ret < 0) {
fprintf(stderr, "Invalid block size\n");
usage(cmd_qgroup_show_usage);
}
+ /* force to print in human readable format
+ * if -h is given
+ */
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ break;
+ else
+ block_size = ret;
+ break;
+ case ''h'':
+ block_size = BTRFS_QGROUP_PRINT_HUMAN_READABLE;
break;
default:
usage(cmd_qgroup_show_usage);
diff --git a/qgroup.c b/qgroup.c
index 0de6c7d..b1b7cef 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -206,15 +206,27 @@ static void print_qgroup_column(struct btrfs_qgroup
*qgroup,
print_qgroup_column_add_blank(BTRFS_QGROUP_QGROUPID, len);
break;
case BTRFS_QGROUP_RFER:
- len = block_size_snprintf((signed long long)qgroup->rfer, tmp,
- sizeof(tmp), block_size);
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(
+ (signed long long)qgroup->rfer,
+ tmp, sizeof(tmp));
+ else
+ len = block_size_snprintf(
+ (signed long long)qgroup->rfer,
+ tmp, sizeof(tmp), block_size);
BUG_ON(len < 0);
printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_RFER, len);
break;
case BTRFS_QGROUP_EXCL:
- len = block_size_snprintf((signed long long)qgroup->excl, tmp,
- sizeof(tmp), block_size);
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(
+ (signed long long)qgroup->excl,
+ tmp, sizeof(tmp));
+ else
+ len = block_size_snprintf(
+ (signed long long)qgroup->excl,
+ tmp, sizeof(tmp), block_size);
BUG_ON(len < 0);
printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_EXCL, len);
@@ -224,14 +236,22 @@ static void print_qgroup_column(struct btrfs_qgroup
*qgroup,
print_qgroup_column_add_blank(BTRFS_QGROUP_PARENT, len);
break;
case BTRFS_QGROUP_MAX_RFER:
- len = block_size_snprintf(qgroup->max_rfer, tmp,
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(qgroup->max_rfer, tmp,
+ sizeof(tmp));
+ else
+ len = block_size_snprintf(qgroup->max_rfer, tmp,
sizeof(tmp), block_size);
BUG_ON(len < 0);
printf("%s", tmp);
print_qgroup_column_add_blank(BTRFS_QGROUP_MAX_RFER, len);
break;
case BTRFS_QGROUP_MAX_EXCL:
- len = block_size_snprintf(qgroup->max_excl, tmp,
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(qgroup->max_excl, tmp,
+ sizeof(tmp));
+ else
+ len = block_size_snprintf(qgroup->max_excl, tmp,
sizeof(tmp), block_size);
BUG_ON(len < 0);
printf("%s", tmp);
@@ -917,28 +937,46 @@ static void __update_columns_max_len(struct btrfs_qgroup
*bq,
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_RFER:
- len = block_size_snprintf((signed long long)bq->rfer, tmp,
- sizeof(tmp), block_size);
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(
+ (signed long long)bq->rfer,
+ tmp, sizeof(tmp));
+ else
+ len = block_size_snprintf((signed long long)bq->rfer,
+ tmp, sizeof(tmp), block_size);
BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_EXCL:
- len = block_size_snprintf((signed long long)bq->excl, tmp,
- sizeof(tmp), block_size);
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(
+ (signed long long)bq->excl,
+ tmp, sizeof(tmp));
+ else
+ len = block_size_snprintf((signed long long)bq->excl,
+ tmp, sizeof(tmp), block_size);
BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_MAX_RFER:
- len = block_size_snprintf(bq->max_rfer, tmp,
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(bq->max_rfer, tmp,
+ sizeof(tmp));
+ else
+ len = block_size_snprintf(bq->max_rfer, tmp,
sizeof(tmp), block_size);
BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
case BTRFS_QGROUP_MAX_EXCL:
- len = block_size_snprintf(bq->max_excl, tmp,
+ if (block_size == BTRFS_QGROUP_PRINT_HUMAN_READABLE)
+ len = pretty_size_snprintf(bq->max_excl, tmp,
+ sizeof(tmp));
+ else
+ len = block_size_snprintf(bq->max_excl, tmp,
sizeof(tmp), block_size);
BUG_ON(len < 0);
if (btrfs_qgroup_columns[column].max_len < len)
diff --git a/qgroup.h b/qgroup.h
index 1113a24..aa05de5 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -22,6 +22,8 @@
#include "ioctl.h"
#include "kerncompat.h"
+#define BTRFS_QGROUP_PRINT_HUMAN_READABLE (-1)
+
struct btrfs_qgroup;
typedef int (*btrfs_qgroup_filter_func)(struct btrfs_qgroup *, u64);
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-08 15:06 UTC
Re: [PATCH v3 02/12] Btrfs-progs: introduces ''-p'' option to print the ID of the parent qgroups
On Mon, Oct 07, 2013 at 03:21:38PM +0800, Wang Shilong wrote:> +static void print_parent_column(struct btrfs_qgroup *qgroup) > +{ > + struct btrfs_qgroup_list *list = NULL; > + > + list_for_each_entry(list, &qgroup->qgroups, next_qgroup) { > + printf("%llu/%llu", (list->qgroup)->qgroupid >> 48, > + ((1ll << 48) - 1) & (list->qgroup)->qgroupid);Please use a wrapper for the >> 48 calculations everywhere (another patch). thanks, david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-08 15:08 UTC
Re: [PATCH v3 03/12] Btrfs-progs: introduces ''-c'' option to print the ID of the child qgroups
On Mon, Oct 07, 2013 at 03:21:39PM +0800, Wang Shilong wrote:> From: Wang Shilong <wangsl-fnst@cn.fujitsu.com> > > This patch introduces ''-c'' option to print the ID of the child qgroups. > You may use it like: > btrfs qgroup show -c <path>I haven''t looked closely, but using -c leads probably to a infinite loop somewhere. The screen scrolls away quickly filled with spaces after it prints the table: qgroupid rfer excl child -------- ---- ---- ----- 0/5 921600 921600 --- 0/267 704512 12288 --- 0/268 700416 8192 --- 0/269 7206805504 4096 --- 0/277 7206805504 4096 --- 0/278 36884398080 36884398080 --- 1/1 7206809600 7206809600 0/269,0/277 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-08 15:34 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote:> You can use it like: > btrfs qgroup show --block-size=m <mnt> > > Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E.There is no distinction between the 1000 and 1024 based prefixes, also no way to get the raw values in bytes. I don''t have a suggestion how to do that, merely letting you know that this could go separately (this and the "-h" patch, the rest shall be integrated). Also, the numbers in the table should be aligned to the right: $ btrfs qgroup show -h -p /mnt/ qgroupid rfer excl parent -------- ---- ---- ------ 0/5 900.00KiB 900.00KiB --- 0/267 688.00KiB 12.00KiB 1/5 0/268 684.00KiB 8.00KiB 1/5 0/269 6.71GiB 4.00KiB 1/1 0/277 6.71GiB 4.00KiB 1/1 0/278 39.74GiB 39.74GiB 1/2 1/1 6.71GiB 6.71GiB --- 1/2 39.74GiB 39.74GiB --- 1/5 696.00KiB 696.00KiB --- david -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Shilong Wang
2013-Oct-08 16:27 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
Thanks for finding this, the problem comes to patch [v3 9/12]. When updating max columns len of child_qgroup, i miswrite qgroup->member to qgroup->parent, i have updated this patch and send a v4, it can be appiled without conflicts with later. Thanks, Wang 2013/10/8 David Sterba <dsterba@suse.cz>:> On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote: >> You can use it like: >> btrfs qgroup show --block-size=m <mnt> >> >> Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E. > > There is no distinction between the 1000 and 1024 based prefixes, also > no way to get the raw values in bytes. I don''t have a suggestion how to > do that, merely letting you know that this could go separately (this and > the "-h" patch, the rest shall be integrated). > > Also, the numbers in the table should be aligned to the right: > > $ btrfs qgroup show -h -p /mnt/ > qgroupid rfer excl parent > -------- ---- ---- ------ > 0/5 900.00KiB 900.00KiB --- > 0/267 688.00KiB 12.00KiB 1/5 > 0/268 684.00KiB 8.00KiB 1/5 > 0/269 6.71GiB 4.00KiB 1/1 > 0/277 6.71GiB 4.00KiB 1/1 > 0/278 39.74GiB 39.74GiB 1/2 > 1/1 6.71GiB 6.71GiB --- > 1/2 39.74GiB 39.74GiB --- > 1/5 696.00KiB 696.00KiB --- > > > david > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Shilong Wang
2013-Oct-08 16:34 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
Sorry, This should to reply to the bug that you find, not this thread. Anyway, you are smart enough to get this ..... 2013/10/9 Shilong Wang <wangshilong1991@gmail.com>:> Thanks for finding this, the problem comes to patch [v3 9/12]. > When updating max columns len of child_qgroup, i miswrite qgroup->member to > qgroup->parent, i have updated this patch and send a v4, it can be > appiled without conflicts with later. > > Thanks, > Wang > 2013/10/8 David Sterba <dsterba@suse.cz>: >> On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote: >>> You can use it like: >>> btrfs qgroup show --block-size=m <mnt> >>> >>> Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E. >> >> There is no distinction between the 1000 and 1024 based prefixes, also >> no way to get the raw values in bytes. I don''t have a suggestion how to >> do that, merely letting you know that this could go separately (this and >> the "-h" patch, the rest shall be integrated). >> >> Also, the numbers in the table should be aligned to the right: >> >> $ btrfs qgroup show -h -p /mnt/ >> qgroupid rfer excl parent >> -------- ---- ---- ------ >> 0/5 900.00KiB 900.00KiB --- >> 0/267 688.00KiB 12.00KiB 1/5 >> 0/268 684.00KiB 8.00KiB 1/5 >> 0/269 6.71GiB 4.00KiB 1/1 >> 0/277 6.71GiB 4.00KiB 1/1 >> 0/278 39.74GiB 39.74GiB 1/2 >> 1/1 6.71GiB 6.71GiB --- >> 1/2 39.74GiB 39.74GiB --- >> 1/5 696.00KiB 696.00KiB --- >> >> >> david >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
David Sterba
2013-Oct-08 16:34 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
On Wed, Oct 09, 2013 at 12:27:23AM +0800, Shilong Wang wrote:> Thanks for finding this, the problem comes to patch [v3 9/12]. > When updating max columns len of child_qgroup, i miswrite qgroup->member to > qgroup->parent, i have updated this patch and send a v4, it can be > appiled without conflicts with later.Works for me, thanks, replaced. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Shilong Wang
2013-Oct-08 16:54 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
Hi David, 2013/10/8 David Sterba <dsterba@suse.cz>:> On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote: >> You can use it like: >> btrfs qgroup show --block-size=m <mnt> >> >> Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E. > > There is no distinction between the 1000 and 1024 based prefixes, also > no way to get the raw values in bytes. I don''t have a suggestion how to > do that, merely letting you know that this could go separately (this and > the "-h" patch, the rest shall be integrated).I implement this like the command ''du''. In default, we print result in bytes. And block size don''t give a byte unit implicitly.Aslo i don''t know why we need to distinct 1000 and 1024, i don''t have any ideas about this.> > Also, the numbers in the table should be aligned to the right:Yes, this should be fixed. Thanks, Wang> > $ btrfs qgroup show -h -p /mnt/ > qgroupid rfer excl parent > -------- ---- ---- ------ > 0/5 900.00KiB 900.00KiB --- > 0/267 688.00KiB 12.00KiB 1/5 > 0/268 684.00KiB 8.00KiB 1/5 > 0/269 6.71GiB 4.00KiB 1/1 > 0/277 6.71GiB 4.00KiB 1/1 > 0/278 39.74GiB 39.74GiB 1/2 > 1/1 6.71GiB 6.71GiB --- > 1/2 39.74GiB 39.74GiB --- > 1/5 696.00KiB 696.00KiB --- > > > david > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html-- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hugo Mills
2013-Oct-08 17:01 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
On Wed, Oct 09, 2013 at 12:54:03AM +0800, Shilong Wang wrote:> Hi David, > > 2013/10/8 David Sterba <dsterba@suse.cz>: > > On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote: > >> You can use it like: > >> btrfs qgroup show --block-size=m <mnt> > >> > >> Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E.k = SI prefix, kilo K = ? (IEEE prefix kibi?) m = SI prefix, milli M = SI prefix, mega g = SI unit, grams G = SI prefix, giga t = ? T = SI prefix, tera p = SI prefix, pico P = SI prefix, peta e = ? E = SI prefix, exa Some confusion here, I think. :)> > There is no distinction between the 1000 and 1024 based prefixes, also > > no way to get the raw values in bytes. I don''t have a suggestion how to > > do that, merely letting you know that this could go separately (this and > > the "-h" patch, the rest shall be integrated). > > I implement this like the command ''du''. > > In default, we print result in bytes. And block size don''t give a byte > unit implicitly.> Aslo i don''t know why we need to distinct 1000 and 1024, i don''t > have any ideas about this.Because when you have a terabyte of data, the difference between the two is 10%. If you''re putting in this kind of infrastructure, it''s not much of an addition to report in either SI decimal or IEEE binary scales.> > Also, the numbers in the table should be aligned to the right: > > Yes, this should be fixed. > > Thanks, > Wang > > > > $ btrfs qgroup show -h -p /mnt/ > > qgroupid rfer excl parent > > -------- ---- ---- ------ > > 0/5 900.00KiB 900.00KiB --- > > 0/267 688.00KiB 12.00KiB 1/5 > > 0/268 684.00KiB 8.00KiB 1/5 > > 0/269 6.71GiB 4.00KiB 1/1 > > 0/277 6.71GiB 4.00KiB 1/1 > > 0/278 39.74GiB 39.74GiB 1/2 > > 1/1 6.71GiB 6.71GiB --- > > 1/2 39.74GiB 39.74GiB --- > > 1/5 696.00KiB 696.00KiB ---Note that the SI mandate a space between the value and the unit. Note also, for future reference, that SI use k for 10^3, whereas IEEE use Ki for 2^10. Hugo. -- === Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk == PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk --- I''ll take your bet, but make it ten thousand francs. I''m only --- a _poor_ corrupt official.
Hugo Mills
2013-Oct-08 17:10 UTC
Re: [PATCH v3 10/12] Btrfs-progs: add ''--block-size'' option to control print result
On Tue, Oct 08, 2013 at 06:01:57PM +0100, Hugo Mills wrote:> On Wed, Oct 09, 2013 at 12:54:03AM +0800, Shilong Wang wrote: > > Hi David, > > > > 2013/10/8 David Sterba <dsterba@suse.cz>: > > > On Mon, Oct 07, 2013 at 03:21:46PM +0800, Wang Shilong wrote: > > >> You can use it like: > > >> btrfs qgroup show --block-size=m <mnt> > > >> > > >> Here, block size supports k/K/m/M/g/G/t/T/p/P/e/E. > > k = SI prefix, kilo > K = ? (IEEE prefix kibi?)... or SI unit, kelvin> t = ?SI-accepted unit, tonne> e = ?SI-accepted unit, charge on the electron Hugo. :) -- === Hugo Mills: hugo@... carfax.org.uk | darksatanic.net | lug.org.uk == PGP key: 65E74AC0 from wwwkeys.eu.pgp.net or http://www.carfax.org.uk --- I spent most of my money on drink, women and fast cars. The --- rest I wasted. -- James Hunt