X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-qgroup.c;h=d07bb0c0ea5663085c1a13b290f9e6e2ebbca265;hb=90a16b10b328d63ea90b3f4a04fd52a0bc0b689f;hp=0ad99f48296d036521b214b58704b2a97be9c5f3;hpb=bbbe7fd7d0f2f104c4c1c54e38524a6496cc9ab6;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-qgroup.c b/cmds-qgroup.c index 0ad99f4..d07bb0c 100644 --- a/cmds-qgroup.c +++ b/cmds-qgroup.c @@ -26,44 +26,55 @@ #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,7 +87,7 @@ 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 = btrfs_open_dir(path, &dirstream, 1); @@ -84,10 +95,8 @@ static int qgroup_assign(int assign, int argc, char **argv) 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: %s", strerror(errno)); close_file_or_dir(fd, dirstream); return 1; } @@ -102,38 +111,38 @@ 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", + error("quota rescan failed: %s", strerror(errno)); } 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 = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) @@ -143,7 +152,7 @@ static int qgroup_create(int create, int argc, char **argv) e = errno; close_file_or_dir(fd, dirstream); if (ret < 0) { - fprintf(stderr, "ERROR: unable to %s quota group: %s\n", + error("unable to %s quota group: %s", create ? "create":"destroy", strerror(e)); return 1; } @@ -205,16 +214,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[] = { @@ -225,10 +231,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[] = { @@ -239,7 +242,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; @@ -253,15 +261,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", @@ -271,11 +283,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 }; @@ -284,11 +297,11 @@ 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; struct btrfs_qgroup_comparer_set *comparer_set; struct btrfs_qgroup_filter_set *filter_set; @@ -297,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 } }; @@ -331,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); } @@ -348,11 +368,27 @@ static int cmd_qgroup_show(int argc, char **argv) path = argv[optind]; fd = btrfs_open_dir(path, &dirstream, 1); - if (fd < 0) + if (fd < 0) { + free(filter_set); + free(comparer_set); return 1; + } + + if (sync) { + ret = ioctl(fd, BTRFS_IOC_SYNC); + if (ret < 0) + 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, @@ -363,12 +399,9 @@ 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)); +out: return !!ret; } @@ -394,7 +427,6 @@ static int cmd_qgroup_limit(int argc, char **argv) int exclusive = 0; DIR *dirstream = NULL; - optind = 1; while (1) { int c = getopt(argc, argv, "ce"); if (c < 0) @@ -415,7 +447,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; } @@ -436,12 +468,11 @@ static int cmd_qgroup_limit(int argc, char **argv) path = argv[optind + 1]; ret = test_issubvolume(path); if (ret < 0) { - fprintf(stderr, "ERROR: error accessing '%s'\n", path); + error("cannot access '%s': %s", path, strerror(-ret)); return 1; } if (!ret) { - fprintf(stderr, "ERROR: '%s' is not a subvolume\n", - path); + error("'%s' is not a subvolume", path); return 1; } /* @@ -462,8 +493,7 @@ static int cmd_qgroup_limit(int argc, char **argv) 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: %s", strerror(e)); return 1; } return 0;