mirror of
https://github.com/kdave/btrfs-progs
synced 2025-05-15 14:28:42 +00:00
btrfs-progs: add filter for deleted but uncleanded subvolumes
New option to subvolume list that acts as a global filter and applies the other filters to either live subvolumes or the uncleaned ones. The path to the deleted subvolumes is lost at the deletion time, sample output looks like: ID 259 gen 7 top level 0 path <FS_TREE>/DELETED Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
b91d84abc0
commit
4fc17596aa
24
btrfs-list.c
24
btrfs-list.c
@ -1173,6 +1173,11 @@ static int filter_by_parent(struct root_info *ri, u64 data)
|
||||
return !uuid_compare(ri->puuid, (u8 *)(unsigned long)data);
|
||||
}
|
||||
|
||||
static int filter_deleted(struct root_info *ri, u64 data)
|
||||
{
|
||||
return ri->deleted;
|
||||
}
|
||||
|
||||
static btrfs_list_filter_func all_filter_funcs[] = {
|
||||
[BTRFS_LIST_FILTER_ROOTID] = filter_by_rootid,
|
||||
[BTRFS_LIST_FILTER_SNAPSHOT_ONLY] = filter_snapshot,
|
||||
@ -1186,6 +1191,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
|
||||
[BTRFS_LIST_FILTER_TOPID_EQUAL] = filter_topid_equal,
|
||||
[BTRFS_LIST_FILTER_FULL_PATH] = filter_full_path,
|
||||
[BTRFS_LIST_FILTER_BY_PARENT] = filter_by_parent,
|
||||
[BTRFS_LIST_FILTER_DELETED] = filter_deleted,
|
||||
};
|
||||
|
||||
struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
|
||||
@ -1222,6 +1228,11 @@ int btrfs_list_setup_filter(struct btrfs_list_filter_set **filter_set,
|
||||
BUG_ON(filter >= BTRFS_LIST_FILTER_MAX);
|
||||
BUG_ON(set->nfilters > set->total);
|
||||
|
||||
if (filter == BTRFS_LIST_FILTER_DELETED) {
|
||||
set->only_deleted = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (set->nfilters == set->total) {
|
||||
size = set->total + BTRFS_LIST_NFILTERS_INCREASE;
|
||||
size = sizeof(*set) + size * sizeof(struct btrfs_list_filter);
|
||||
@ -1254,6 +1265,12 @@ static int filter_root(struct root_info *ri,
|
||||
if (!set || !set->nfilters)
|
||||
return 1;
|
||||
|
||||
if (set->only_deleted && !ri->deleted)
|
||||
return 0;
|
||||
|
||||
if (!set->only_deleted && ri->deleted)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < set->nfilters; i++) {
|
||||
if (!set->filters[i].filter_func)
|
||||
break;
|
||||
@ -1281,12 +1298,13 @@ static void __filter_and_sort_subvol(struct root_lookup *all_subvols,
|
||||
entry = rb_entry(n, struct root_info, rb_node);
|
||||
|
||||
ret = resolve_root(all_subvols, entry, top_id);
|
||||
if (ret == -ENOENT)
|
||||
goto skip;
|
||||
if (ret == -ENOENT) {
|
||||
entry->full_path = strdup("DELETED");
|
||||
entry->deleted = 1;
|
||||
}
|
||||
ret = filter_root(entry, filter_set);
|
||||
if (ret)
|
||||
sort_tree_insert(sort_tree, entry, comp_set);
|
||||
skip:
|
||||
n = rb_prev(n);
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,8 @@ struct root_info {
|
||||
char *name;
|
||||
|
||||
char *full_path;
|
||||
|
||||
int deleted;
|
||||
};
|
||||
|
||||
typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
|
||||
@ -90,6 +92,7 @@ struct btrfs_list_comparer {
|
||||
struct btrfs_list_filter_set {
|
||||
int total;
|
||||
int nfilters;
|
||||
int only_deleted;
|
||||
struct btrfs_list_filter filters[0];
|
||||
};
|
||||
|
||||
@ -127,6 +130,7 @@ enum btrfs_list_filter_enum {
|
||||
BTRFS_LIST_FILTER_TOPID_EQUAL,
|
||||
BTRFS_LIST_FILTER_FULL_PATH,
|
||||
BTRFS_LIST_FILTER_BY_PARENT,
|
||||
BTRFS_LIST_FILTER_DELETED,
|
||||
BTRFS_LIST_FILTER_MAX,
|
||||
};
|
||||
|
||||
|
@ -317,6 +317,7 @@ static const char * const cmd_subvol_list_usage[] = {
|
||||
"-t print the result as a table",
|
||||
"-s list snapshots only in the filesystem",
|
||||
"-r list readonly subvolumes (including snapshots)",
|
||||
"-d list deleted subvolumes that are not yet cleaned",
|
||||
"-G [+|-]value",
|
||||
" filter the subvolumes by generation",
|
||||
" (+value: >= value; -value: <= value; value: = value)",
|
||||
@ -355,7 +356,7 @@ static int cmd_subvol_list(int argc, char **argv)
|
||||
optind = 1;
|
||||
while(1) {
|
||||
c = getopt_long(argc, argv,
|
||||
"acgopqsurG:C:t", long_options, NULL);
|
||||
"acdgopqsurG:C:t", long_options, NULL);
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
@ -369,6 +370,11 @@ static int cmd_subvol_list(int argc, char **argv)
|
||||
case 'c':
|
||||
btrfs_list_setup_print_column(BTRFS_LIST_OGENERATION);
|
||||
break;
|
||||
case 'd':
|
||||
btrfs_list_setup_filter(&filter_set,
|
||||
BTRFS_LIST_FILTER_DELETED,
|
||||
0);
|
||||
break;
|
||||
case 'g':
|
||||
btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user