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,
[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)
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);
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;
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);
}
}
char *name;
char *full_path;
+
+ int deleted;
};
typedef int (*btrfs_list_filter_func)(struct root_info *, u64);
struct btrfs_list_filter_set {
int total;
int nfilters;
+ int only_deleted;
struct btrfs_list_filter filters[0];
};
BTRFS_LIST_FILTER_TOPID_EQUAL,
BTRFS_LIST_FILTER_FULL_PATH,
BTRFS_LIST_FILTER_BY_PARENT,
+ BTRFS_LIST_FILTER_DELETED,
BTRFS_LIST_FILTER_MAX,
};
"-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)",
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;
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;