summaryrefslogtreecommitdiff
path: root/btrfs-list.c
diff options
context:
space:
mode:
authorwangshilong <wangsl-fnst@cn.fujitsu.com>2012-09-19 17:21:51 +0800
committerroot <root@localhost.localdomain>2012-10-04 16:26:33 -0400
commit60d11eca6649700c1e39c19c36c903cad747e775 (patch)
tree57868509696a0977308585d46ee80870ce7ccc38 /btrfs-list.c
parentaf3045cb201b5a89397d90409aafe111aa526e8a (diff)
Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
This patch introduces '-g' '-c' '--sort' options The option '-g' can help you filter the subvolumes by the generation, you may use it just like: btrfs subvol list -g +/-value <path> '+' means the generation of the subvolumes should >= the value you specified. '-' means the generation should <= the value If you don't input either '+' nor '-', this command will list the subvolumes that their generation equals to the value. However if you want to find gengeration between value1 and value2 you may use the above like: btrfs sub list -g -value1 -g +value2 <path> The option '-c' can help you filter the subvolumes by the ogeneration, you may use it just like: btrfs subvol list -c +/-value <path> The usage is the same to '-g' You might want to list subvolumes in order of some items, such as root id, gen and so on, you can use '--sort'. Now you can sort the subvolumes by root id, gen, ogen and path. For example: If you want to list subvolumes in order of rootid, you can use the option like that: btrfs sub list --sort=+/-rooid <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 sub list --sort=-rootid,+path,ogen,gen <path> Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Diffstat (limited to 'btrfs-list.c')
-rw-r--r--btrfs-list.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/btrfs-list.c b/btrfs-list.c
index 201f3784..c6d9a18f 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -215,12 +215,48 @@ static int comp_entry_with_ogen(struct root_info *entry1,
return is_descending ? -ret : ret;
}
+static int comp_entry_with_path(struct root_info *entry1,
+ struct root_info *entry2,
+ int is_descending)
+{
+ int ret;
+
+ if (strcmp(entry1->full_path, entry2->full_path) > 0)
+ ret = 1;
+ else if (strcmp(entry1->full_path, entry2->full_path) < 0)
+ ret = -1;
+ else
+ ret = 0;
+
+ return is_descending ? -ret : ret;
+}
+
static btrfs_list_comp_func all_comp_funcs[] = {
[BTRFS_LIST_COMP_ROOTID] = comp_entry_with_rootid,
[BTRFS_LIST_COMP_OGEN] = comp_entry_with_ogen,
[BTRFS_LIST_COMP_GEN] = comp_entry_with_gen,
+ [BTRFS_LIST_COMP_PATH] = comp_entry_with_path,
};
+static char *all_sort_items[] = {
+ [BTRFS_LIST_COMP_ROOTID] = "rootid",
+ [BTRFS_LIST_COMP_OGEN] = "ogen",
+ [BTRFS_LIST_COMP_GEN] = "gen",
+ [BTRFS_LIST_COMP_PATH] = "path",
+ [BTRFS_LIST_COMP_MAX] = NULL,
+};
+
+static int btrfs_list_get_sort_item(char *sort_name)
+{
+ int i;
+
+ for (i = 0; i < BTRFS_LIST_COMP_MAX; i++) {
+ if (strcmp(sort_name, all_sort_items[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+
struct btrfs_list_comparer_set *btrfs_list_alloc_comparer_set(void)
{
struct btrfs_list_comparer_set *set;
@@ -1091,10 +1127,46 @@ static int filter_flags(struct root_info *ri, u64 flags)
return ri->flags & flags;
}
+static int filter_gen_more(struct root_info *ri, u64 data)
+{
+ return ri->gen >= data;
+}
+
+static int filter_gen_less(struct root_info *ri, u64 data)
+{
+ return ri->gen <= data;
+}
+
+static int filter_gen_equal(struct root_info *ri, u64 data)
+{
+ return ri->gen == data;
+}
+
+static int filter_cgen_more(struct root_info *ri, u64 data)
+{
+ return ri->ogen >= data;
+}
+
+static int filter_cgen_less(struct root_info *ri, u64 data)
+{
+ return ri->ogen <= data;
+}
+
+static int filter_cgen_equal(struct root_info *ri, u64 data)
+{
+ return ri->ogen == data;
+}
+
static btrfs_list_filter_func all_filter_funcs[] = {
[BTRFS_LIST_FILTER_ROOTID] = filter_by_rootid,
[BTRFS_LIST_FILTER_SNAPSHOT_ONLY] = filter_snapshot,
[BTRFS_LIST_FILTER_FLAGS] = filter_flags,
+ [BTRFS_LIST_FILTER_GEN_MORE] = filter_gen_more,
+ [BTRFS_LIST_FILTER_GEN_LESS] = filter_gen_less,
+ [BTRFS_LIST_FILTER_GEN_EQUAL] = filter_gen_equal,
+ [BTRFS_LIST_FILTER_CGEN_MORE] = filter_cgen_more,
+ [BTRFS_LIST_FILTER_CGEN_LESS] = filter_cgen_less,
+ [BTRFS_LIST_FILTER_CGEN_EQUAL] = filter_cgen_equal,
};
struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
@@ -1534,3 +1606,99 @@ char *btrfs_list_path_for_root(int fd, u64 root)
return ret_path;
}
+
+int btrfs_list_parse_sort_string(char *optarg,
+ struct btrfs_list_comparer_set **comps)
+{
+ int order;
+ int flag;
+ char *p;
+ char **ptr_argv;
+ int what_to_sort;
+
+ while ((p = strtok(optarg, ",")) != 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_list_get_sort_item(p);
+ btrfs_list_setup_comparer(comps, what_to_sort, order);
+ }
+ optarg = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * This function is used to parse the argument of filter condition.
+ *
+ * type is the filter object.
+ */
+int btrfs_list_parse_filter_string(char *optarg,
+ struct btrfs_list_filter_set **filters,
+ enum btrfs_list_filter_enum type)
+{
+
+ u64 arg;
+ char *ptr_parse_end = NULL;
+ char *ptr_optarg_end = optarg + strlen(optarg);
+
+ switch (*(optarg++)) {
+ case '+':
+ arg = (u64)strtol(optarg, &ptr_parse_end, 10);
+ type += 2;
+ if (ptr_parse_end != ptr_optarg_end)
+ return -1;
+
+ btrfs_list_setup_filter(filters, type, arg);
+ break;
+ case '-':
+ arg = (u64)strtoll(optarg, &ptr_parse_end, 10);
+ type += 1;
+ if (ptr_parse_end != ptr_optarg_end)
+ return -1;
+
+ btrfs_list_setup_filter(filters, type, arg);
+ break;
+ default:
+ optarg--;
+ arg = (u64)strtoll(optarg, &ptr_parse_end, 10);
+
+ if (ptr_parse_end != ptr_optarg_end)
+ return -1;
+ btrfs_list_setup_filter(filters, type, arg);
+ break;
+ }
+
+ return 0;
+}
+