diff options
author | wangshilong <wangsl-fnst@cn.fujitsu.com> | 2012-09-19 17:21:51 +0800 |
---|---|---|
committer | root <root@localhost.localdomain> | 2012-10-04 16:26:33 -0400 |
commit | 60d11eca6649700c1e39c19c36c903cad747e775 (patch) | |
tree | 57868509696a0977308585d46ee80870ce7ccc38 /btrfs-list.c | |
parent | af3045cb201b5a89397d90409aafe111aa526e8a (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.c | 168 |
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; +} + |