2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public
4 * License v2 as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * General Public License for more details.
11 * You should have received a copy of the GNU General Public
12 * License along with this program; if not, write to the
13 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14 * Boston, MA 021110-1307, USA.
21 #include <sys/ioctl.h>
27 #include <uuid/uuid.h>
29 #include "kerncompat.h"
36 #include "btrfs-list.h"
39 static const char * const subvolume_cmd_group_usage[] = {
40 "btrfs subvolume <command> <args>",
45 * test if path is a directory
46 * this function return
47 * 0-> path exists but it is not a directory
48 * 1-> path exists and it is a directory
49 * -1 -> path is unaccessible
51 static int test_isdir(char *path)
56 res = stat(path, &st);
60 return S_ISDIR(st.st_mode);
63 static const char * const cmd_subvol_create_usage[] = {
64 "btrfs subvolume create [-i <qgroupid>] [<dest>/]<name>",
66 "Create a subvolume <name> in <dest>. If <dest> is not given",
67 "subvolume <name> will be created in the current directory.",
69 "-i <qgroupid> add the newly created subvolume to a qgroup. This",
70 " option can be given multiple times.",
74 static int cmd_subvol_create(int argc, char **argv)
83 struct btrfs_qgroup_inherit *inherit = NULL;
84 DIR *dirstream = NULL;
88 int c = getopt(argc, argv, "c:i:");
94 res = qgroup_inherit_add_copy(&inherit, optarg, 0);
101 res = qgroup_inherit_add_group(&inherit, optarg);
108 usage(cmd_subvol_create_usage);
112 if (check_argc_exact(argc - optind, 1))
113 usage(cmd_subvol_create_usage);
117 retval = 1; /* failure */
118 res = test_isdir(dst);
120 fprintf(stderr, "ERROR: '%s' exists\n", dst);
124 dupname = strdup(dst);
125 newname = basename(dupname);
126 dupdir = strdup(dst);
127 dstdir = dirname(dupdir);
129 if (!test_issubvolname(newname)) {
130 fprintf(stderr, "ERROR: incorrect subvolume name '%s'\n",
135 len = strlen(newname);
136 if (len == 0 || len >= BTRFS_VOL_NAME_MAX) {
137 fprintf(stderr, "ERROR: subvolume name too long '%s'\n",
142 fddst = open_file_or_dir(dstdir, &dirstream);
144 fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
148 printf("Create subvolume '%s/%s'\n", dstdir, newname);
150 struct btrfs_ioctl_vol_args_v2 args;
152 memset(&args, 0, sizeof(args));
153 strncpy_null(args.name, newname);
154 args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
155 args.size = qgroup_inherit_size(inherit);
156 args.qgroup_inherit = inherit;
158 res = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE_V2, &args);
160 struct btrfs_ioctl_vol_args args;
162 memset(&args, 0, sizeof(args));
163 strncpy_null(args.name, newname);
165 res = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE, &args);
169 fprintf(stderr, "ERROR: cannot create subvolume - %s\n",
174 retval = 0; /* success */
176 close_file_or_dir(fddst, dirstream);
185 * test if path is a subvolume:
186 * this function return
187 * 0-> path exists but it is not a subvolume
188 * 1-> path exists and it is a subvolume
189 * -1 -> path is unaccessible
191 int test_issubvolume(char *path)
196 res = stat(path, &st);
200 return (st.st_ino == 256) && S_ISDIR(st.st_mode);
203 static int wait_for_commit(int fd)
207 ret = ioctl(fd, BTRFS_IOC_START_SYNC, NULL);
210 return ioctl(fd, BTRFS_IOC_WAIT_SYNC, NULL);
213 static const char * const cmd_subvol_delete_usage[] = {
214 "btrfs subvolume delete [options] <subvolume> [<subvolume>...]",
215 "Delete subvolume(s)",
216 "Delete subvolumes from the filesystem. The corresponding directory",
217 "is removed instantly but the data blocks are removed later.",
218 "The deletion does not involve full commit by default due to",
219 "performance reasons (as a consequence, the subvolume may appear again",
220 "after a crash). Use one of the --commit options to wait until the",
221 "operation is safely stored on the media.",
223 "-c|--commit-after wait for transaction commit at the end of the operation",
224 "-C|--commit-each wait for transaction commit after deleting each subvolume",
228 static int cmd_subvol_delete(int argc, char **argv)
230 int res, len, e, ret = 0;
233 struct btrfs_ioctl_vol_args args;
234 char *dname, *vname, *cpath;
235 char *dupdname = NULL;
236 char *dupvname = NULL;
238 DIR *dirstream = NULL;
240 struct option long_options[] = {
241 {"commit-after", no_argument, NULL, 'c'}, /* sync mode 1 */
242 {"commit-each", no_argument, NULL, 'C'}, /* sync mode 2 */
250 c = getopt_long(argc, argv, "cC", long_options, NULL);
262 usage(cmd_subvol_delete_usage);
266 if (check_argc_min(argc - optind, 1))
267 usage(cmd_subvol_delete_usage);
269 printf("Transaction commit: %s\n",
270 !sync_mode ? "none (default)" :
271 sync_mode == 1 ? "at the end" : "after each");
278 res = test_issubvolume(path);
280 fprintf(stderr, "ERROR: error accessing '%s'\n", path);
285 fprintf(stderr, "ERROR: '%s' is not a subvolume\n", path);
290 cpath = realpath(path, NULL);
293 fprintf(stderr, "ERROR: finding real path for '%s': %s\n",
294 path, strerror(errno));
297 dupdname = strdup(cpath);
298 dname = dirname(dupdname);
299 dupvname = strdup(cpath);
300 vname = basename(dupvname);
303 if (!test_issubvolname(vname)) {
304 fprintf(stderr, "ERROR: incorrect subvolume name '%s'\n",
311 if (len == 0 || len >= BTRFS_VOL_NAME_MAX) {
312 fprintf(stderr, "ERROR: snapshot name too long '%s'\n",
318 fd = open_file_or_dir(dname, &dirstream);
320 fprintf(stderr, "ERROR: can't access '%s'\n", dname);
325 printf("Delete subvolume '%s/%s'\n", dname, vname);
326 strncpy_null(args.name, vname);
327 res = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);
331 fprintf( stderr, "ERROR: cannot delete '%s/%s' - %s\n",
332 dname, vname, strerror(e));
337 if (sync_mode == 1) {
338 res = wait_for_commit(fd);
341 "ERROR: unable to wait for commit after '%s': %s\n",
342 path, strerror(errno));
354 close_file_or_dir(fd, dirstream);
355 /* avoid double free */
361 if (sync_mode == 2 && fd != -1) {
362 res = wait_for_commit(fd);
365 "ERROR: unable to do final sync: %s\n",
370 close_file_or_dir(fd, dirstream);
377 * - uppercase for filters and sort options
378 * - lowercase for enabling specific items in the output
380 static const char * const cmd_subvol_list_usage[] = {
381 "btrfs subvolume list [options] [-G [+|-]value] [-C [+|-]value] "
382 "[--sort=gen,ogen,rootid,path] <path>",
383 "List subvolumes (and snapshots)",
385 "-p print parent ID",
386 "-a print all the subvolumes in the filesystem and",
387 " distinguish absolute and relative path with respect",
388 " to the given <path>",
389 "-c print the ogeneration of the subvolume",
390 "-g print the generation of the subvolume",
391 "-o print only subvolumes bellow specified path",
392 "-u print the uuid of subvolumes (and snapshots)",
393 "-q print the parent uuid of the snapshots",
394 "-t print the result as a table",
395 "-s list snapshots only in the filesystem",
396 "-r list readonly subvolumes (including snapshots)",
397 "-d list deleted subvolumes that are not yet cleaned",
399 " filter the subvolumes by generation",
400 " (+value: >= value; -value: <= value; value: = value)",
402 " filter the subvolumes by ogeneration",
403 " (+value: >= value; -value: <= value; value: = value)",
404 "--sort=gen,ogen,rootid,path",
405 " list the subvolume in order of gen, ogen, rootid or path",
406 " you also can add '+' or '-' in front of each items.",
407 " (+:ascending, -:descending, ascending default)",
411 static int cmd_subvol_list(int argc, char **argv)
413 struct btrfs_list_filter_set *filter_set;
414 struct btrfs_list_comparer_set *comparer_set;
418 int ret = -1, uerr = 0;
421 int is_tab_result = 0;
423 int is_only_in_path = 0;
424 struct option long_options[] = {
425 {"sort", 1, NULL, 'S'},
428 DIR *dirstream = NULL;
430 filter_set = btrfs_list_alloc_filter_set();
431 comparer_set = btrfs_list_alloc_comparer_set();
435 c = getopt_long(argc, argv,
436 "acdgopqsurG:C:t", long_options, NULL);
442 btrfs_list_setup_print_column(BTRFS_LIST_PARENT);
448 btrfs_list_setup_print_column(BTRFS_LIST_OGENERATION);
451 btrfs_list_setup_filter(&filter_set,
452 BTRFS_LIST_FILTER_DELETED,
456 btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
465 btrfs_list_setup_filter(&filter_set,
466 BTRFS_LIST_FILTER_SNAPSHOT_ONLY,
468 btrfs_list_setup_print_column(BTRFS_LIST_OGENERATION);
469 btrfs_list_setup_print_column(BTRFS_LIST_OTIME);
472 btrfs_list_setup_print_column(BTRFS_LIST_UUID);
475 btrfs_list_setup_print_column(BTRFS_LIST_PUUID);
478 flags |= BTRFS_ROOT_SUBVOL_RDONLY;
481 btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
482 ret = btrfs_list_parse_filter_string(optarg,
484 BTRFS_LIST_FILTER_GEN);
492 btrfs_list_setup_print_column(BTRFS_LIST_OGENERATION);
493 ret = btrfs_list_parse_filter_string(optarg,
495 BTRFS_LIST_FILTER_CGEN);
502 ret = btrfs_list_parse_sort_string(optarg,
517 btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_FLAGS,
520 if (check_argc_exact(argc - optind, 1)) {
525 subvol = argv[optind];
526 fd = open_file_or_dir(subvol, &dirstream);
529 fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
533 ret = btrfs_list_get_path_rootid(fd, &top_id);
535 fprintf(stderr, "ERROR: can't get rootid for '%s'\n", subvol);
540 btrfs_list_setup_filter(&filter_set,
541 BTRFS_LIST_FILTER_FULL_PATH,
543 else if (is_only_in_path)
544 btrfs_list_setup_filter(&filter_set,
545 BTRFS_LIST_FILTER_TOPID_EQUAL,
548 /* by default we shall print the following columns*/
549 btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
550 btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
551 btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
552 btrfs_list_setup_print_column(BTRFS_LIST_PATH);
555 ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
556 BTRFS_LIST_LAYOUT_TABLE,
557 !is_list_all && !is_only_in_path, NULL);
559 ret = btrfs_list_subvols_print(fd, filter_set, comparer_set,
560 BTRFS_LIST_LAYOUT_DEFAULT,
561 !is_list_all && !is_only_in_path, NULL);
564 close_file_or_dir(fd, dirstream);
566 btrfs_list_free_filter_set(filter_set);
568 btrfs_list_free_comparer_set(comparer_set);
570 usage(cmd_subvol_list_usage);
574 static const char * const cmd_snapshot_usage[] = {
575 "btrfs subvolume snapshot [-r] <source> <dest>|[<dest>/]<name>",
576 "btrfs subvolume snapshot [-r] [-i <qgroupid>] <source> <dest>|[<dest>/]<name>",
577 "Create a snapshot of the subvolume",
578 "Create a writable/readonly snapshot of the subvolume <source> with",
579 "the name <name> in the <dest> directory. If only <dest> is given,",
580 "the subvolume will be named the basename of <source>.",
582 "-r create a readonly snapshot",
583 "-i <qgroupid> add the newly created snapshot to a qgroup. This",
584 " option can be given multiple times.",
588 static int cmd_snapshot(int argc, char **argv)
592 int fd = -1, fddst = -1;
593 int len, readonly = 0;
594 char *dupname = NULL;
598 struct btrfs_ioctl_vol_args_v2 args;
599 struct btrfs_qgroup_inherit *inherit = NULL;
600 DIR *dirstream1 = NULL, *dirstream2 = NULL;
603 memset(&args, 0, sizeof(args));
605 int c = getopt(argc, argv, "c:i:r");
611 res = qgroup_inherit_add_copy(&inherit, optarg, 0);
618 res = qgroup_inherit_add_group(&inherit, optarg);
628 res = qgroup_inherit_add_copy(&inherit, optarg, 1);
635 usage(cmd_snapshot_usage);
639 if (check_argc_exact(argc - optind, 2))
640 usage(cmd_snapshot_usage);
642 subvol = argv[optind];
643 dst = argv[optind + 1];
645 retval = 1; /* failure */
646 res = test_issubvolume(subvol);
648 fprintf(stderr, "ERROR: error accessing '%s'\n", subvol);
652 fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol);
656 res = test_isdir(dst);
658 fprintf(stderr, "ERROR: '%s' exists and it is not a directory\n", dst);
663 dupname = strdup(subvol);
664 newname = basename(dupname);
667 dupname = strdup(dst);
668 newname = basename(dupname);
669 dupdir = strdup(dst);
670 dstdir = dirname(dupdir);
673 if (!test_issubvolname(newname)) {
674 fprintf(stderr, "ERROR: incorrect snapshot name '%s'\n",
679 len = strlen(newname);
680 if (len == 0 || len >= BTRFS_VOL_NAME_MAX) {
681 fprintf(stderr, "ERROR: snapshot name too long '%s'\n",
686 fddst = open_file_or_dir(dstdir, &dirstream1);
688 fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
692 fd = open_file_or_dir(subvol, &dirstream2);
694 fprintf(stderr, "ERROR: can't access '%s'\n", dstdir);
699 args.flags |= BTRFS_SUBVOL_RDONLY;
700 printf("Create a readonly snapshot of '%s' in '%s/%s'\n",
701 subvol, dstdir, newname);
703 printf("Create a snapshot of '%s' in '%s/%s'\n",
704 subvol, dstdir, newname);
709 args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
710 args.size = qgroup_inherit_size(inherit);
711 args.qgroup_inherit = inherit;
713 strncpy_null(args.name, newname);
715 res = ioctl(fddst, BTRFS_IOC_SNAP_CREATE_V2, &args);
718 fprintf( stderr, "ERROR: cannot snapshot '%s' - %s\n",
719 subvol, strerror(errno));
723 retval = 0; /* success */
726 close_file_or_dir(fddst, dirstream1);
727 close_file_or_dir(fd, dirstream2);
735 static const char * const cmd_subvol_get_default_usage[] = {
736 "btrfs subvolume get-default <path>",
737 "Get the default subvolume of a filesystem",
741 static int cmd_subvol_get_default(int argc, char **argv)
746 struct btrfs_list_filter_set *filter_set;
748 DIR *dirstream = NULL;
750 if (check_argc_exact(argc, 2))
751 usage(cmd_subvol_get_default_usage);
754 fd = open_file_or_dir(subvol, &dirstream);
756 fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
760 ret = btrfs_list_get_default_subvolume(fd, &default_id);
762 fprintf(stderr, "ERROR: can't perform the search - %s\n",
768 if (default_id == 0) {
769 fprintf(stderr, "ERROR: 'default' dir item not found\n");
773 /* no need to resolve roots if FS_TREE is default */
774 if (default_id == BTRFS_FS_TREE_OBJECTID) {
775 printf("ID 5 (FS_TREE)\n");
780 filter_set = btrfs_list_alloc_filter_set();
781 btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_ROOTID,
784 /* by default we shall print the following columns*/
785 btrfs_list_setup_print_column(BTRFS_LIST_OBJECTID);
786 btrfs_list_setup_print_column(BTRFS_LIST_GENERATION);
787 btrfs_list_setup_print_column(BTRFS_LIST_TOP_LEVEL);
788 btrfs_list_setup_print_column(BTRFS_LIST_PATH);
790 ret = btrfs_list_subvols_print(fd, filter_set, NULL,
791 BTRFS_LIST_LAYOUT_DEFAULT, 1, NULL);
794 btrfs_list_free_filter_set(filter_set);
796 close_file_or_dir(fd, dirstream);
800 static const char * const cmd_subvol_set_default_usage[] = {
801 "btrfs subvolume set-default <subvolid> <path>",
802 "Set the default subvolume of a filesystem",
806 static int cmd_subvol_set_default(int argc, char **argv)
812 DIR *dirstream = NULL;
814 if (check_argc_exact(argc, 3))
815 usage(cmd_subvol_set_default_usage);
820 objectid = arg_strtou64(subvolid);
822 fd = open_file_or_dir(path, &dirstream);
824 fprintf(stderr, "ERROR: can't access '%s'\n", path);
828 ret = ioctl(fd, BTRFS_IOC_DEFAULT_SUBVOL, &objectid);
830 close_file_or_dir(fd, dirstream);
832 fprintf(stderr, "ERROR: unable to set a new default subvolume - %s\n",
839 static const char * const cmd_find_new_usage[] = {
840 "btrfs subvolume find-new <path> <lastgen>",
841 "List the recently modified files in a filesystem",
845 static int cmd_find_new(int argc, char **argv)
851 DIR *dirstream = NULL;
853 if (check_argc_exact(argc, 3))
854 usage(cmd_find_new_usage);
857 last_gen = arg_strtou64(argv[2]);
859 ret = test_issubvolume(subvol);
861 fprintf(stderr, "ERROR: error accessing '%s'\n", subvol);
865 fprintf(stderr, "ERROR: '%s' is not a subvolume\n", subvol);
869 fd = open_file_or_dir(subvol, &dirstream);
871 fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
875 ret = ioctl(fd, BTRFS_IOC_SYNC);
877 fprintf(stderr, "ERROR: unable to fs-syncing '%s' - %s\n",
878 subvol, strerror(errno));
879 close_file_or_dir(fd, dirstream);
883 ret = btrfs_list_find_updated_files(fd, 0, last_gen);
884 close_file_or_dir(fd, dirstream);
888 static const char * const cmd_subvol_show_usage[] = {
889 "btrfs subvolume show <subvol-path>",
890 "Show more information of the subvolume",
894 static int cmd_subvol_show(int argc, char **argv)
896 struct root_info get_ri;
897 struct btrfs_list_filter_set *filter_set;
899 char uuidparse[BTRFS_UUID_UNPARSED_SIZE];
900 char *fullpath = NULL, *svpath = NULL, *mnt = NULL;
901 char raw_prefix[] = "\t\t\t\t";
903 int fd = -1, mntfd = -1;
905 DIR *dirstream1 = NULL, *dirstream2 = NULL;
907 if (check_argc_exact(argc, 2))
908 usage(cmd_subvol_show_usage);
910 fullpath = realpath(argv[1], NULL);
912 fprintf(stderr, "ERROR: finding real path for '%s', %s\n",
913 argv[1], strerror(errno));
917 ret = test_issubvolume(fullpath);
919 fprintf(stderr, "ERROR: error accessing '%s'\n", fullpath);
923 fprintf(stderr, "ERROR: '%s' is not a subvolume\n", fullpath);
927 ret = find_mount_root(fullpath, &mnt);
929 fprintf(stderr, "ERROR: find_mount_root failed on '%s': "
930 "%s\n", fullpath, strerror(-ret));
935 "ERROR: %s doesn't belong to btrfs mount point\n",
941 svpath = get_subvol_name(mnt, fullpath);
943 fd = open_file_or_dir(fullpath, &dirstream1);
945 fprintf(stderr, "ERROR: can't access '%s'\n", fullpath);
949 ret = btrfs_list_get_path_rootid(fd, &sv_id);
951 fprintf(stderr, "ERROR: can't get rootid for '%s'\n",
956 mntfd = open_file_or_dir(mnt, &dirstream2);
958 fprintf(stderr, "ERROR: can't access '%s'\n", mnt);
962 ret = btrfs_list_get_path_rootid(mntfd, &mntid);
964 fprintf(stderr, "ERROR: can't get rootid for '%s'\n", mnt);
968 if (sv_id == BTRFS_FS_TREE_OBJECTID) {
969 printf("%s is btrfs root\n", fullpath);
973 memset(&get_ri, 0, sizeof(get_ri));
974 get_ri.root_id = sv_id;
976 if (btrfs_get_subvol(mntfd, &get_ri)) {
977 fprintf(stderr, "ERROR: can't find '%s'\n",
984 printf("%s\n", fullpath);
985 printf("\tName: \t\t\t%s\n", get_ri.name);
987 if (uuid_is_null(get_ri.uuid))
988 strcpy(uuidparse, "-");
990 uuid_unparse(get_ri.uuid, uuidparse);
991 printf("\tuuid: \t\t\t%s\n", uuidparse);
993 if (uuid_is_null(get_ri.puuid))
994 strcpy(uuidparse, "-");
996 uuid_unparse(get_ri.puuid, uuidparse);
997 printf("\tParent uuid: \t\t%s\n", uuidparse);
1002 localtime_r(&get_ri.otime, &tm);
1003 strftime(tstr, 256, "%Y-%m-%d %X", &tm);
1006 printf("\tCreation time: \t\t%s\n", tstr);
1008 printf("\tObject ID: \t\t%llu\n", get_ri.root_id);
1009 printf("\tGeneration (Gen): \t%llu\n", get_ri.gen);
1010 printf("\tGen at creation: \t%llu\n", get_ri.ogen);
1011 printf("\tParent: \t\t%llu\n", get_ri.ref_tree);
1012 printf("\tTop Level: \t\t%llu\n", get_ri.top_id);
1014 if (get_ri.flags & BTRFS_ROOT_SUBVOL_RDONLY)
1015 printf("\tFlags: \t\t\treadonly\n");
1017 printf("\tFlags: \t\t\t-\n");
1019 /* print the snapshots of the given subvol if any*/
1020 printf("\tSnapshot(s):\n");
1021 filter_set = btrfs_list_alloc_filter_set();
1022 btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT,
1023 (u64)(unsigned long)get_ri.uuid);
1024 btrfs_list_setup_print_column(BTRFS_LIST_PATH);
1025 btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW,
1031 free(get_ri.full_path);
1032 btrfs_list_free_filter_set(filter_set);
1035 close_file_or_dir(fd, dirstream1);
1036 close_file_or_dir(mntfd, dirstream2);
1042 const struct cmd_group subvolume_cmd_group = {
1043 subvolume_cmd_group_usage, NULL, {
1044 { "create", cmd_subvol_create, cmd_subvol_create_usage, NULL, 0 },
1045 { "delete", cmd_subvol_delete, cmd_subvol_delete_usage, NULL, 0 },
1046 { "list", cmd_subvol_list, cmd_subvol_list_usage, NULL, 0 },
1047 { "snapshot", cmd_snapshot, cmd_snapshot_usage, NULL, 0 },
1048 { "get-default", cmd_subvol_get_default,
1049 cmd_subvol_get_default_usage, NULL, 0 },
1050 { "set-default", cmd_subvol_set_default,
1051 cmd_subvol_set_default_usage, NULL, 0 },
1052 { "find-new", cmd_find_new, cmd_find_new_usage, NULL, 0 },
1053 { "show", cmd_subvol_show, cmd_subvol_show_usage, NULL, 0 },
1058 int cmd_subvolume(int argc, char **argv)
1060 return handle_command_group(&subvolume_cmd_group, argc, argv);