diff options
Diffstat (limited to 'cmds-subvolume.c')
-rw-r--r-- | cmds-subvolume.c | 130 |
1 files changed, 40 insertions, 90 deletions
diff --git a/cmds-subvolume.c b/cmds-subvolume.c index 9d9b0af7..2319684e 100644 --- a/cmds-subvolume.c +++ b/cmds-subvolume.c @@ -224,33 +224,6 @@ out: return retval; } -/* - * Test if path is a subvolume - * Returns: - * 0 - path exists but it is not a subvolume - * 1 - path exists and it is a subvolume - * < 0 - error - */ -int test_issubvolume(const char *path) -{ - struct stat st; - struct statfs stfs; - int res; - - res = stat(path, &st); - if (res < 0) - return -errno; - - if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) - return 0; - - res = statfs(path, &stfs); - if (res < 0) - return -errno; - - return (int)stfs.f_type == BTRFS_SUPER_MAGIC; -} - static int wait_for_commit(int fd) { int ret; @@ -788,7 +761,9 @@ static int cmd_subvol_get_default(int argc, char **argv) u64 default_id; DIR *dirstream = NULL; - if (check_argc_exact(argc, 2)) + clean_args_no_options(argc, argv, cmd_subvol_get_default_usage); + + if (check_argc_exact(argc - optind, 1)) usage(cmd_subvol_get_default_usage); subvol = argv[1]; @@ -850,11 +825,13 @@ static int cmd_subvol_set_default(int argc, char **argv) char *subvolid; DIR *dirstream = NULL; - if (check_argc_exact(argc, 3)) + clean_args_no_options(argc, argv, cmd_subvol_set_default_usage); + + if (check_argc_exact(argc - optind, 2)) usage(cmd_subvol_set_default_usage); - subvolid = argv[1]; - path = argv[2]; + subvolid = argv[optind]; + path = argv[optind + 1]; objectid = arg_strtou64(subvolid); @@ -887,11 +864,13 @@ static int cmd_subvol_find_new(int argc, char **argv) u64 last_gen; DIR *dirstream = NULL; - if (check_argc_exact(argc, 3)) + clean_args_no_options(argc, argv, cmd_subvol_find_new_usage); + + if (check_argc_exact(argc - optind, 2)) usage(cmd_subvol_find_new_usage); - subvol = argv[1]; - last_gen = arg_strtou64(argv[2]); + subvol = argv[optind]; + last_gen = arg_strtou64(argv[optind + 1]); ret = test_issubvolume(subvol); if (ret < 0) { @@ -929,21 +908,21 @@ static const char * const cmd_subvol_show_usage[] = { static int cmd_subvol_show(int argc, char **argv) { struct root_info get_ri; - struct btrfs_list_filter_set *filter_set; + struct btrfs_list_filter_set *filter_set = NULL; char tstr[256]; char uuidparse[BTRFS_UUID_UNPARSED_SIZE]; - char *fullpath = NULL, *svpath = NULL, *mnt = NULL; + char *fullpath = NULL; char raw_prefix[] = "\t\t\t\t"; - u64 sv_id; - int fd = -1, mntfd = -1; + int fd = -1; int ret = 1; - DIR *dirstream1 = NULL, *dirstream2 = NULL; + DIR *dirstream1 = NULL; clean_args_no_options(argc, argv, cmd_subvol_show_usage); if (check_argc_exact(argc - optind, 1)) usage(cmd_subvol_show_usage); + memset(&get_ri, 0, sizeof(get_ri)); fullpath = realpath(argv[optind], NULL); if (!fullpath) { error("cannot find real path for '%s': %s", @@ -951,57 +930,23 @@ static int cmd_subvol_show(int argc, char **argv) goto out; } - ret = test_issubvolume(fullpath); - if (ret < 0) { - error("cannot access subvolume %s: %s", fullpath, - strerror(-ret)); - goto out; - } - if (!ret) { - error("not a subvolume: %s", fullpath); - ret = 1; - goto out; - } - - ret = find_mount_root(fullpath, &mnt); - if (ret < 0) { - error("find_mount_root failed on '%s': %s", - fullpath, strerror(-ret)); - goto out; - } - if (ret > 0) { - error("%s doesn't belong to btrfs mount point", fullpath); - goto out; - } - ret = 1; - svpath = get_subvol_name(mnt, fullpath); - - fd = btrfs_open_dir(fullpath, &dirstream1, 1); - if (fd < 0) - goto out; - - ret = btrfs_list_get_path_rootid(fd, &sv_id); - if (ret) { - error("can't get rootid for '%s'", fullpath); - goto out; - } - - mntfd = btrfs_open_dir(mnt, &dirstream2, 1); - if (mntfd < 0) - goto out; - - if (sv_id == BTRFS_FS_TREE_OBJECTID) { + ret = get_subvol_info(fullpath, &get_ri); + if (ret == 2) { + /* + * Since the top level btrfs was given don't + * take that as error + */ printf("%s is toplevel subvolume\n", fullpath); + ret = 0; goto out; } - - memset(&get_ri, 0, sizeof(get_ri)); - get_ri.root_id = sv_id; - - ret = btrfs_get_subvol(mntfd, &get_ri); if (ret) { - error("can't find '%s'", svpath); - goto out; + ret < 0 ? + error("Failed to get subvol info %s: %s\n", + fullpath, strerror(-ret)): + error("Failed to get subvol info %s: %d\n", + fullpath, ret); + return ret; } /* print the info */ @@ -1052,19 +997,23 @@ static int cmd_subvol_show(int argc, char **argv) btrfs_list_setup_filter(&filter_set, BTRFS_LIST_FILTER_BY_PARENT, (u64)(unsigned long)get_ri.uuid); btrfs_list_setup_print_column(BTRFS_LIST_PATH); + + fd = open_file_or_dir(fullpath, &dirstream1); + if (fd < 0) { + fprintf(stderr, "ERROR: can't access '%s'\n", fullpath); + goto out; + } btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW, 1, raw_prefix); +out: /* clean up */ free(get_ri.path); free(get_ri.name); free(get_ri.full_path); btrfs_list_free_filter_set(filter_set); -out: close_file_or_dir(fd, dirstream1); - close_file_or_dir(mntfd, dirstream2); - free(mnt); free(fullpath); return !!ret; } @@ -1198,7 +1147,8 @@ static int enumerate_dead_subvols(int fd, u64 **ids) u64 *newids; count += SUBVOL_ID_BATCH; - newids = (u64*)realloc(*ids, count); + newids = (u64*)realloc(*ids, + count * sizeof(u64)); if (!newids) return -ENOMEM; *ids = newids; |