summaryrefslogtreecommitdiff
path: root/btrfs-list.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2013-10-23 19:00:09 +0200
committerChris Mason <chris.mason@fusionio.com>2013-10-24 05:57:44 -0400
commit4fc17596aaa2b03ee38c467585465923d62b1510 (patch)
tree46453ce5137b7e87370006229d4d46ceb1f3e1fb /btrfs-list.c
parentb91d84abc0df2195aaa06a79b565d8852b3099b2 (diff)
downloadbtrfs-progs-4fc17596aaa2b03ee38c467585465923d62b1510.tar.gz
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>
Diffstat (limited to 'btrfs-list.c')
-rw-r--r--btrfs-list.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/btrfs-list.c b/btrfs-list.c
index 9411e4d..f3618b9 100644
--- a/btrfs-list.c
+++ b/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);
}
}