diff --git a/btrfs-list.c b/btrfs-list.c index f804dfc6..0c3edd11 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -200,9 +200,10 @@ static int add_root(struct root_lookup *root_lookup, * This can't be called until all the root_info->path fields are filled * in by lookup_ino_path */ -static int resolve_root(struct root_lookup *rl, struct root_info *ri) +static int resolve_root(struct root_lookup *rl, struct root_info *ri, int print_parent) { u64 top_id; + u64 parent_id = 0; char *full_path = NULL; int len = 0; struct root_info *found; @@ -233,6 +234,11 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri) } next = found->ref_tree; + /* record the first parent */ + if ( parent_id == 0 ) { + parent_id = next; + } + /* if the ref_tree refers to ourselves, we're at the top */ if (next == found->root_id) { top_id = next; @@ -249,9 +255,15 @@ static int resolve_root(struct root_lookup *rl, struct root_info *ri) break; } } - printf("ID %llu top level %llu path %s\n", - (unsigned long long)ri->root_id, (unsigned long long)top_id, - full_path); + if (print_parent) { + printf("ID %llu parent %llu top level %llu path %s\n", + (unsigned long long)ri->root_id, (unsigned long long)parent_id, (unsigned long long)top_id, + full_path); + } else { + printf("ID %llu top level %llu path %s\n", + (unsigned long long)ri->root_id, (unsigned long long)top_id, + full_path); + } free(full_path); return 0; } @@ -549,7 +561,7 @@ build: return full; } -int list_subvols(int fd) +int list_subvols(int fd, int print_parent) { struct root_lookup root_lookup; struct rb_node *n; @@ -666,7 +678,7 @@ int list_subvols(int fd) while (n) { struct root_info *entry; entry = rb_entry(n, struct root_info, rb_node); - resolve_root(&root_lookup, entry); + resolve_root(&root_lookup, entry, print_parent); n = rb_prev(n); } diff --git a/btrfs.c b/btrfs.c index ff84260c..a8553646 100644 --- a/btrfs.c +++ b/btrfs.c @@ -66,9 +66,11 @@ static struct Command commands[] = { "not passed).", NULL }, - { do_subvol_list, 1, "subvolume list", "\n" + { do_subvol_list, -1, "subvolume list", "[-p] \n" "List the snapshot/subvolume of a filesystem.", - NULL + "[-p] \n" + "List the snapshot/subvolume of a filesystem.\n" + "-p print parent ID" }, { do_set_default_subvol, 2, "subvolume set-default", " \n" diff --git a/btrfs_cmds.c b/btrfs_cmds.c index da5bd918..72129d98 100644 --- a/btrfs_cmds.c +++ b/btrfs_cmds.c @@ -302,9 +302,27 @@ int do_subvol_list(int argc, char **argv) { int fd; int ret; + int print_parent = 0; char *subvol; + int optind = 1; - subvol = argv[1]; + while(1) { + int c = getopt(argc, argv, "p"); + if (c < 0) break; + switch(c) { + case 'p': + print_parent = 1; + optind++; + break; + } + } + + if (argc - optind != 1) { + fprintf(stderr, "ERROR: invalid arguments for subvolume list\n"); + return 1; + } + + subvol = argv[optind]; ret = test_issubvolume(subvol); if (ret < 0) { @@ -321,7 +339,7 @@ int do_subvol_list(int argc, char **argv) fprintf(stderr, "ERROR: can't access '%s'\n", subvol); return 12; } - ret = list_subvols(fd); + ret = list_subvols(fd, print_parent); if (ret) return 19; return 0; diff --git a/btrfs_cmds.h b/btrfs_cmds.h index ab722d4f..12902d8b 100644 --- a/btrfs_cmds.h +++ b/btrfs_cmds.h @@ -28,7 +28,7 @@ int do_scan(int nargs, char **argv); int do_resize(int nargs, char **argv); int do_subvol_list(int nargs, char **argv); int do_set_default_subvol(int nargs, char **argv); -int list_subvols(int fd); +int list_subvols(int fd, int print_parent); int do_df_filesystem(int nargs, char **argv); int find_updated_files(int fd, u64 root_id, u64 oldest_gen); int do_find_newer(int argc, char **argv);