Hi,

When listing subvolumes it can be useful to filter out any snapshots;
surprisingly enough I couldn't find an option to do this easily, only
the opposite (list only snapshots).

A "root" subvolume is identified by a null parent UUID, so adding a new
subvolume filter and flag -P ("Parent") does the trick. 

The same can of course be accomplished with shell hackery, e.g.:

 btrfs subvol list -q -o <path> | grep -i "parent_uuid -" | cut -d " " -f 11

but a built-in way seems less fragile.

I originally cooked this up for myself, but David Sterba encouraged me to
send this to the list, so here it is. I'm not too proud of the -P but
couldn't find a better option letter; suggestions welcome. :)

cheers,
Holger

Signed-off-by: Holger Hoffstätte <hol...@applied-asynchrony.com>
---
 btrfs-list.c     | 6 ++++++
 btrfs-list.h     | 1 +
 cmds-subvolume.c | 8 +++++++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/btrfs-list.c b/btrfs-list.c
index 4cc2ed49..6aa7a290 100644
--- a/btrfs-list.c
+++ b/btrfs-list.c
@@ -1175,6 +1175,11 @@ static int filter_deleted(struct root_info *ri, u64 data)
        return ri->deleted;
 }
 
+static int filter_parent_subvol_only(struct root_info *ri, u64 data)
+{
+       return uuid_is_null(ri->puuid);
+}
+
 static btrfs_list_filter_func all_filter_funcs[] = {
        [BTRFS_LIST_FILTER_ROOTID]              = filter_by_rootid,
        [BTRFS_LIST_FILTER_SNAPSHOT_ONLY]       = filter_snapshot,
@@ -1189,6 +1194,7 @@ static btrfs_list_filter_func all_filter_funcs[] = {
        [BTRFS_LIST_FILTER_FULL_PATH]           = filter_full_path,
        [BTRFS_LIST_FILTER_BY_PARENT]           = filter_by_parent,
        [BTRFS_LIST_FILTER_DELETED]             = filter_deleted,
+       [BTRFS_LIST_FILTER_PARENT_SUBVOL_ONLY]  = filter_parent_subvol_only,
 };
 
 struct btrfs_list_filter_set *btrfs_list_alloc_filter_set(void)
diff --git a/btrfs-list.h b/btrfs-list.h
index 13f44c3a..54aab123 100644
--- a/btrfs-list.h
+++ b/btrfs-list.h
@@ -142,6 +142,7 @@ enum btrfs_list_filter_enum {
        BTRFS_LIST_FILTER_FULL_PATH,
        BTRFS_LIST_FILTER_BY_PARENT,
        BTRFS_LIST_FILTER_DELETED,
+       BTRFS_LIST_FILTER_PARENT_SUBVOL_ONLY,
        BTRFS_LIST_FILTER_MAX,
 };
 
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index e7ef67d3..2371338e 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -404,6 +404,7 @@ static const char * const cmd_subvol_list_usage[] = {
        "-q           print the parent uuid of the snapshots",
        "-R           print the uuid of the received snapshots",
        "-t           print the result as a table",
+       "-P           list parent subvolumes only",
        "-s           list snapshots only in the filesystem",
        "-r           list readonly subvolumes (including snapshots)",
        "-d           list deleted subvolumes that are not yet cleaned",
@@ -445,7 +446,7 @@ static int cmd_subvol_list(int argc, char **argv)
                };
 
                c = getopt_long(argc, argv,
-                                   "acdgopqsurRG:C:t", long_options, NULL);
+                                   "acdgopPqsurRG:C:t", long_options, NULL);
                if (c < 0)
                        break;
 
@@ -473,6 +474,11 @@ static int cmd_subvol_list(int argc, char **argv)
                case 't':
                        is_tab_result = 1;
                        break;
+               case 'P':
+                       btrfs_list_setup_filter(&filter_set,
+                                               
BTRFS_LIST_FILTER_PARENT_SUBVOL_ONLY,
+                                               0);
+                       break;
                case 's':
                        btrfs_list_setup_filter(&filter_set,
                                                BTRFS_LIST_FILTER_SNAPSHOT_ONLY,
-- 
2.14.2

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to