X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-qgroup.c;h=93206900693de5a43472f6c6c6ff6f63b6d3230c;hb=7cdd58b2e92863f055c70ef7134d3a70760473c7;hp=48c173338d13dd35e41c4db3e778ad24375def8c;hpb=71d856ba3c325151472ae2460a302d65e37bd012;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-qgroup.c b/cmds-qgroup.c index 48c1733..9320690 100644 --- a/cmds-qgroup.c +++ b/cmds-qgroup.c @@ -20,50 +20,63 @@ #include #include +#include + #include "ctree.h" #include "ioctl.h" #include "commands.h" #include "qgroup.h" #include "utils.h" +#include "help.h" static const char * const qgroup_cmd_group_usage[] = { "btrfs qgroup [options] ", NULL }; -static int qgroup_assign(int assign, int argc, char **argv) +static int _cmd_qgroup_assign(int assign, int argc, char **argv, + const char * const *usage_str) { int ret = 0; int fd; - int e; int rescan = 0; char *path; struct btrfs_ioctl_qgroup_assign_args args; DIR *dirstream = NULL; - while (1) { - enum { GETOPT_VAL_RESCAN = 256 }; - static const struct option long_options[] = { - { "rescan", no_argument, NULL, GETOPT_VAL_RESCAN }, - { NULL, 0, NULL, 0 } - }; - int c = getopt_long(argc, argv, "", long_options, NULL); - - if (c < 0) - break; - switch (c) { - case GETOPT_VAL_RESCAN: - rescan = 1; - break; - default: - /* Usage printed by the caller */ - return -1; + if (assign) { + while (1) { + enum { GETOPT_VAL_RESCAN = 256, GETOPT_VAL_NO_RESCAN }; + static const struct option long_options[] = { + { "rescan", no_argument, NULL, + GETOPT_VAL_RESCAN }, + { "no-rescan", no_argument, NULL, + GETOPT_VAL_NO_RESCAN }, + { NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "", long_options, NULL); + + if (c < 0) + break; + switch (c) { + case GETOPT_VAL_RESCAN: + rescan = 1; + break; + case GETOPT_VAL_NO_RESCAN: + rescan = 0; + break; + default: + /* Usage printed by the caller */ + return -1; + } } + } else { + clean_args_no_options(argc, argv, usage_str); } if (check_argc_exact(argc - optind, 3)) - return -1; + usage(usage_str); memset(&args, 0, sizeof(args)); args.assign = assign; @@ -76,20 +89,16 @@ static int qgroup_assign(int assign, int argc, char **argv) * FIXME src should accept subvol path */ if (btrfs_qgroup_level(args.src) >= btrfs_qgroup_level(args.dst)) { - fprintf(stderr, "ERROR: bad relation requested '%s'\n", path); + error("bad relation requested: %s", path); return 1; } - fd = open_file_or_dir(path, &dirstream); - if (fd < 0) { - fprintf(stderr, "ERROR: can't access '%s'\n", path); + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) return 1; - } ret = ioctl(fd, BTRFS_IOC_QGROUP_ASSIGN, &args); - e = errno; if (ret < 0) { - fprintf(stderr, "ERROR: unable to assign quota group: %s\n", - strerror(e)); + error("unable to assign quota group: %m"); close_file_or_dir(fd, dirstream); return 1; } @@ -104,51 +113,46 @@ static int qgroup_assign(int assign, int argc, char **argv) */ if (ret > 0) { if (rescan) { - struct btrfs_ioctl_quota_rescan_args args; + struct btrfs_ioctl_quota_rescan_args qargs; printf("Quota data changed, rescan scheduled\n"); - memset(&args, 0, sizeof(args)); - ret = ioctl(fd, BTRFS_IOC_QUOTA_RESCAN, &args); + memset(&qargs, 0, sizeof(qargs)); + ret = ioctl(fd, BTRFS_IOC_QUOTA_RESCAN, &qargs); if (ret < 0) - fprintf(stderr, - "ERROR: quota rescan failed: %s\n", - strerror(errno)); + error("quota rescan failed: %m"); } else { - printf("WARNING: quotas may be inconsistent, rescan needed\n"); + warning("quotas may be inconsistent, rescan needed"); } } close_file_or_dir(fd, dirstream); return ret; } -static int qgroup_create(int create, int argc, char **argv) +static int _cmd_qgroup_create(int create, int argc, char **argv) { int ret = 0; int fd; - int e; - char *path = argv[2]; + char *path; struct btrfs_ioctl_qgroup_create_args args; DIR *dirstream = NULL; - if (check_argc_exact(argc, 3)) + if (check_argc_exact(argc - optind, 2)) return -1; memset(&args, 0, sizeof(args)); args.create = create; - args.qgroupid = parse_qgroupid(argv[1]); + args.qgroupid = parse_qgroupid(argv[optind]); + path = argv[optind + 1]; - fd = open_file_or_dir(path, &dirstream); - if (fd < 0) { - fprintf(stderr, "ERROR: can't access '%s'\n", path); + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) return 1; - } ret = ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args); - e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { - fprintf(stderr, "ERROR: unable to %s quota group: %s\n", - create ? "create":"destroy", strerror(e)); + error("unable to %s quota group: %m", + create ? "create":"destroy"); return 1; } return 0; @@ -209,16 +213,13 @@ static const char * const cmd_qgroup_assign_usage[] = { "Assign SRC as the child qgroup of DST", "", "--rescan schedule qutoa rescan if needed", - "--no-rescan ", + "--no-rescan don't schedule quota rescan", NULL }; static int cmd_qgroup_assign(int argc, char **argv) { - int ret = qgroup_assign(1, argc, argv); - if (ret < 0) - usage(cmd_qgroup_assign_usage); - return ret; + return _cmd_qgroup_assign(1, argc, argv, cmd_qgroup_assign_usage); } static const char * const cmd_qgroup_remove_usage[] = { @@ -229,10 +230,7 @@ static const char * const cmd_qgroup_remove_usage[] = { static int cmd_qgroup_remove(int argc, char **argv) { - int ret = qgroup_assign(0, argc, argv); - if (ret < 0) - usage(cmd_qgroup_remove_usage); - return ret; + return _cmd_qgroup_assign(0, argc, argv, cmd_qgroup_remove_usage); } static const char * const cmd_qgroup_create_usage[] = { @@ -243,7 +241,12 @@ static const char * const cmd_qgroup_create_usage[] = { static int cmd_qgroup_create(int argc, char **argv) { - int ret = qgroup_create(1, argc, argv); + int ret; + + clean_args_no_options(argc, argv, cmd_qgroup_create_usage); + + ret = _cmd_qgroup_create(1, argc, argv); + if (ret < 0) usage(cmd_qgroup_create_usage); return ret; @@ -257,15 +260,19 @@ static const char * const cmd_qgroup_destroy_usage[] = { static int cmd_qgroup_destroy(int argc, char **argv) { - int ret = qgroup_create(0, argc, argv); + int ret; + + clean_args_no_options(argc, argv, cmd_qgroup_destroy_usage); + + ret = _cmd_qgroup_create(0, argc, argv); + if (ret < 0) usage(cmd_qgroup_destroy_usage); return ret; } static const char * const cmd_qgroup_show_usage[] = { - "btrfs qgroup show -pcreFf " - "[--sort=qgroupid,rfer,excl,max_rfer,max_excl] ", + "btrfs qgroup show [options] ", "Show subvolume quota groups.", "-p print parent qgroup id", "-c print child qgroup id", @@ -275,11 +282,12 @@ static const char * const cmd_qgroup_show_usage[] = { " (including ancestral qgroups)", "-f list all qgroups which impact the given path", " (excluding ancestral qgroups)", - HELPINFO_OUTPUT_UNIT, + HELPINFO_UNITS_LONG, "--sort=qgroupid,rfer,excl,max_rfer,max_excl", " list qgroups sorted by specified items", " you can use '+' or '-' in front of each item.", " (+:ascending, -:descending, ascending default)", + "--sync force sync of the filesystem before getting info", NULL }; @@ -288,11 +296,12 @@ static int cmd_qgroup_show(int argc, char **argv) char *path; int ret = 0; int fd; - int e; DIR *dirstream = NULL; u64 qgroupid; int filter_flag = 0; unsigned unit_mode; + int sync = 0; + enum btrfs_util_error err; struct btrfs_qgroup_comparer_set *comparer_set; struct btrfs_qgroup_filter_set *filter_set; @@ -301,11 +310,15 @@ static int cmd_qgroup_show(int argc, char **argv) unit_mode = get_unit_mode_from_arg(&argc, argv, 0); - optind = 1; while (1) { int c; + enum { + GETOPT_VAL_SORT = 256, + GETOPT_VAL_SYNC + }; static const struct option long_options[] = { - {"sort", required_argument, NULL, 'S'}, + {"sort", required_argument, NULL, GETOPT_VAL_SORT}, + {"sync", no_argument, NULL, GETOPT_VAL_SYNC}, { NULL, 0, NULL, 0 } }; @@ -335,12 +348,15 @@ static int cmd_qgroup_show(int argc, char **argv) case 'f': filter_flag |= 0x2; break; - case 'S': + case GETOPT_VAL_SORT: ret = btrfs_qgroup_parse_sort_string(optarg, &comparer_set); if (ret) usage(cmd_qgroup_show_usage); break; + case GETOPT_VAL_SYNC: + sync = 1; + break; default: usage(cmd_qgroup_show_usage); } @@ -351,14 +367,28 @@ static int cmd_qgroup_show(int argc, char **argv) usage(cmd_qgroup_show_usage); path = argv[optind]; - fd = open_file_or_dir(path, &dirstream); + fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) { - fprintf(stderr, "ERROR: can't access '%s'\n", path); + free(filter_set); + free(comparer_set); return 1; } + if (sync) { + err = btrfs_util_sync_fd(fd); + if (err) + warning("sync ioctl failed on '%s': %s", path, + strerror(errno)); + } + if (filter_flag) { - qgroupid = btrfs_get_path_rootid(fd); + ret = lookup_path_rootid(fd, &qgroupid); + if (ret < 0) { + error("cannot resolve rootid for %s: %s", + path, strerror(-ret)); + close_file_or_dir(fd, dirstream); + goto out; + } if (filter_flag & 0x1) btrfs_qgroup_setup_filter(&filter_set, BTRFS_QGROUP_FILTER_ALL_PARENT, @@ -369,12 +399,11 @@ static int cmd_qgroup_show(int argc, char **argv) qgroupid); } ret = btrfs_show_qgroups(fd, filter_set, comparer_set); - e = errno; close_file_or_dir(fd, dirstream); - if (ret < 0) - fprintf(stderr, "ERROR: can't list qgroups: %s\n", - strerror(e)); + free(filter_set); + free(comparer_set); +out: return !!ret; } @@ -392,15 +421,14 @@ static int cmd_qgroup_limit(int argc, char **argv) { int ret = 0; int fd; - int e; char *path = NULL; struct btrfs_ioctl_qgroup_limit_args args; unsigned long long size; int compressed = 0; int exclusive = 0; DIR *dirstream = NULL; + enum btrfs_util_error err; - optind = 1; while (1) { int c = getopt(argc, argv, "ce"); if (c < 0) @@ -421,7 +449,7 @@ static int cmd_qgroup_limit(int argc, char **argv) usage(cmd_qgroup_limit_usage); if (!parse_limit(argv[optind], &size)) { - fprintf(stderr, "Invalid size argument given\n"); + error("invalid size argument: %s", argv[optind]); return 1; } @@ -440,14 +468,9 @@ static int cmd_qgroup_limit(int argc, char **argv) if (argc - optind == 2) { args.qgroupid = 0; path = argv[optind + 1]; - ret = test_issubvolume(path); - if (ret < 0) { - fprintf(stderr, "ERROR: error accessing '%s'\n", path); - return 1; - } - if (!ret) { - fprintf(stderr, "ERROR: '%s' is not a subvolume\n", - path); + err = btrfs_util_is_subvolume(path); + if (err) { + error_btrfs_util(err); return 1; } /* @@ -460,18 +483,14 @@ static int cmd_qgroup_limit(int argc, char **argv) } else usage(cmd_qgroup_limit_usage); - fd = open_file_or_dir(path, &dirstream); - if (fd < 0) { - fprintf(stderr, "ERROR: can't access '%s'\n", path); + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) return 1; - } ret = ioctl(fd, BTRFS_IOC_QGROUP_LIMIT, &args); - e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { - fprintf(stderr, "ERROR: unable to limit requested quota group: " - "%s\n", strerror(e)); + error("unable to limit requested quota group: %m"); return 1; } return 0;