Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
PATCH 1/2 Btrfs-progs: introduce -g -c --sort options into btrfs subvol list command
From: Wang Shilong <[email protected]>
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>
---
This patch is based on patchset:
[PATCH V4 0/7 ] Btrfs-progs: enhance btrfs subvol list only to show read-only snapshots
--- btrfs-list.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ btrfs-list.h | 14 +++++ cmds-subvolume.c | 50 +++++++++++++++- man/btrfs.8.in | 29 ++++++++- 4 files changed, 254 insertions(+), 7 deletions(-)
btrfs-list.c +168 -0
@@ -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 ; +} +
btrfs-list.h +14 -0
@@ -62,6 +62,14 @@ enum btrfs_list_filter_enum {BTRFS_LIST_FILTER_ROOTID ,BTRFS_LIST_FILTER_SNAPSHOT_ONLY ,BTRFS_LIST_FILTER_FLAGS , +BTRFS_LIST_FILTER_GEN , +BTRFS_LIST_FILTER_GEN_EQUAL =BTRFS_LIST_FILTER_GEN , +BTRFS_LIST_FILTER_GEN_LESS , +BTRFS_LIST_FILTER_GEN_MORE , +BTRFS_LIST_FILTER_CGEN , +BTRFS_LIST_FILTER_CGEN_EQUAL =BTRFS_LIST_FILTER_CGEN , +BTRFS_LIST_FILTER_CGEN_LESS , +BTRFS_LIST_FILTER_CGEN_MORE , BTRFS_LIST_FILTER_MAX, };
@@ -69,9 +77,15 @@ enum btrfs_list_comp_enum {BTRFS_LIST_COMP_ROOTID ,BTRFS_LIST_COMP_OGEN ,BTRFS_LIST_COMP_GEN , +BTRFS_LIST_COMP_PATH , BTRFS_LIST_COMP_MAX, }; +int btrfs_list_parse_sort_string (char *optarg, +struct btrfs_list_comparer_set **comps); +int btrfs_list_parse_filter_string (char *optarg, +struct btrfs_list_filter_set **filters, +enum btrfs_list_filter_enum type);void btrfs_list_setup_print_column (enum btrfs_list_column_enum column);struct btrfs_list_filter_set *btrfs_list_alloc_filter_set (void );void btrfs_list_free_filter_set (struct btrfs_list_filter_set *filter_set);
cmds-subvolume.c +46 -4
93 lines not on this page · raw message
man/btrfs.8.in +26 -3
@@ -11,7 +11,7 @@ btrfs \- control a btrfs filesystem .PP \fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP .PP -\fBbtrfs\fP \fBsubvolume list\fP\fI [-pr] <path>\fP +\fBbtrfs\fP \fBsubvolume list\fP\fI [-pr] [-s 0|1] [-g [+|-]value] [-c [+|-]value] [--rootid=rootid,gen,ogen,path] <path>\fP .PP \fBbtrfs\fP \fBsubvolume set-default\fP\fI <id> <path>\fP .PP
@@ -108,18 +108,41 @@ Create a subvolume in \fI<dest>\fR (or in the current directory if \fI<dest>\fR is omitted). .TP -\fBsubvolume list\fR\fI [-pr] <path>\fR +\fBsubvolume list\fR\fI [-pr][-s 0|1] [-g [+|-]value] [-c [+|-]value] [--sort=gen,ogen,rootid,path] <path>\fR +.RS List the subvolumes present in the filesystem \fI<path>\fR. For every subvolume the following information is shown by default. ID <ID> top level <ID> path <path> where path is the relative path of the subvolume to the \fItop level\fR subvolume. + The subvolume's ID may be used by the \fBsubvolume set-default\fR command, or at mount time via the \fIsubvol=\fR option. If \fI-p\fR is given, then \fIparent <ID>\fR is added to the output between ID and top level. The parent's ID may be used at mount time via the \fIsubvolrootid=\fR option. -If \fI-r\fR is given, only readonly subvolumes in the filesystem will be listed. + +\fB-r\fP only readonly subvolumes in the filesystem wille be listed. + +\fB-s\fP only snapshot subvolumes in the filesystem will be listed. + +\fB-g [+|-]value\fP +list subvolumes in the filesystem that its generation is +>=, <= or = value. '+' means >= value, '-' means <= value, If there is +neither '+' nor '-', it means = value. + +\fB-c [+|-]value\fP +list subvolumes in the filesystem that its ogeneration is +>=, <= or = value. The usage is the same to '-g' option. + +\fB--sort=gen,ogen,path,rootid\fP +list subvolumes in order by specified items. +you can add '+' or '-' in front of each items, '+' means ascending,'-' +means descending. The default is ascending. + +for \fB--sort\fP you can combine some items together by ',', just like +\f--sort=+ogen,-gen,path,rootid\fR. +.RE .TP \fBsubvolume set-default\fR\fI <id> <path>\fR
Signature · 1 line
1.7.6.5