X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=cmds-quota.c;h=745889d125236e71e9fe096974f8e3ae26794eec;hb=3ccad2a6443fcae0fee2cd94132580d2d06268dd;hp=8481514cb2b9449ad13291ada50106741f45074e;hpb=7b1c567c84a6292c138db3bd1638e19e73e0e593;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/cmds-quota.c b/cmds-quota.c index 8481514..745889d 100644 --- a/cmds-quota.c +++ b/cmds-quota.c @@ -24,19 +24,20 @@ #include "commands.h" #include "utils.h" +#include "help.h" static const char * const quota_cmd_group_usage[] = { "btrfs quota [options] ", NULL }; -int quota_ctl(int cmd, int argc, char **argv) +static int quota_ctl(int cmd, int argc, char **argv) { int ret = 0; int fd; - int e; char *path = argv[1]; struct btrfs_ioctl_quota_ctl_args args; + DIR *dirstream = NULL; if (check_argc_exact(argc, 2)) return -1; @@ -44,19 +45,15 @@ int quota_ctl(int cmd, int argc, char **argv) memset(&args, 0, sizeof(args)); args.cmd = cmd; - fd = open_file_or_dir(path); - if (fd < 0) { - fprintf(stderr, "ERROR: can't access '%s'\n", path); - return 12; - } + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) + return 1; ret = ioctl(fd, BTRFS_IOC_QUOTA_CTL, &args); - e = errno; - close(fd); + close_file_or_dir(fd, dirstream); if (ret < 0) { - fprintf(stderr, "ERROR: quota command failed: %s\n", - strerror(e)); - return 30; + error("quota command failed: %m"); + return 1; } return 0; } @@ -64,12 +61,20 @@ int quota_ctl(int cmd, int argc, char **argv) static const char * const cmd_quota_enable_usage[] = { "btrfs quota enable ", "Enable subvolume quota support for a filesystem.", + "Any data already present on the filesystem will not count towards", + "the space usage numbers. It is recommended to enable quota for a", + "filesystem before writing any data to it.", NULL }; static int cmd_quota_enable(int argc, char **argv) { - int ret = quota_ctl(BTRFS_QUOTA_CTL_ENABLE, argc, argv); + int ret; + + clean_args_no_options(argc, argv, cmd_quota_enable_usage); + + ret = quota_ctl(BTRFS_QUOTA_CTL_ENABLE, argc, argv); + if (ret < 0) usage(cmd_quota_enable_usage); return ret; @@ -83,32 +88,118 @@ static const char * const cmd_quota_disable_usage[] = { static int cmd_quota_disable(int argc, char **argv) { - int ret = quota_ctl(BTRFS_QUOTA_CTL_DISABLE, argc, argv); + int ret; + + clean_args_no_options(argc, argv, cmd_quota_disable_usage); + + ret = quota_ctl(BTRFS_QUOTA_CTL_DISABLE, argc, argv); + if (ret < 0) usage(cmd_quota_disable_usage); return ret; } static const char * const cmd_quota_rescan_usage[] = { - "btrfs quota rescan ", - "Rescan the subvolume for a changed quota setting.", + "btrfs quota rescan [-sw] ", + "Trash all qgroup numbers and scan the metadata again with the current config.", + "", + "-s show status of a running rescan operation", + "-w wait for rescan operation to finish (can be already in progress)", NULL }; static int cmd_quota_rescan(int argc, char **argv) { - int ret = quota_ctl(BTRFS_QUOTA_CTL_RESCAN, argc, argv); - if (ret < 0) + int ret = 0; + int fd; + int e; + char *path = NULL; + struct btrfs_ioctl_quota_rescan_args args; + unsigned long ioctlnum = BTRFS_IOC_QUOTA_RESCAN; + DIR *dirstream = NULL; + int wait_for_completion = 0; + + while (1) { + int c = getopt(argc, argv, "sw"); + if (c < 0) + break; + switch (c) { + case 's': + ioctlnum = BTRFS_IOC_QUOTA_RESCAN_STATUS; + break; + case 'w': + wait_for_completion = 1; + break; + default: + usage(cmd_quota_rescan_usage); + } + } + + if (ioctlnum != BTRFS_IOC_QUOTA_RESCAN && wait_for_completion) { + error("switch -w cannot be used with -s"); + return 1; + } + + if (check_argc_exact(argc - optind, 1)) usage(cmd_quota_rescan_usage); - return ret; + + memset(&args, 0, sizeof(args)); + + path = argv[optind]; + fd = btrfs_open_dir(path, &dirstream, 1); + if (fd < 0) + return 1; + + ret = ioctl(fd, ioctlnum, &args); + e = errno; + + if (ioctlnum == BTRFS_IOC_QUOTA_RESCAN_STATUS) { + close_file_or_dir(fd, dirstream); + if (ret < 0) { + error("could not obtain quota rescan status: %m"); + return 1; + } + if (!args.flags) + printf("no rescan operation in progress\n"); + else + printf("rescan operation running (current key %lld)\n", + args.progress); + return 0; + } + + if (ret == 0) { + printf("quota rescan started\n"); + fflush(stdout); + } else if (ret < 0 && (!wait_for_completion || e != EINPROGRESS)) { + error("quota rescan failed: %m"); + close_file_or_dir(fd, dirstream); + return 1; + } + + if (wait_for_completion) { + ret = ioctl(fd, BTRFS_IOC_QUOTA_RESCAN_WAIT, &args); + e = errno; + if (ret < 0) { + error("quota rescan wait failed: %m"); + close_file_or_dir(fd, dirstream); + return 1; + } + } + + close_file_or_dir(fd, dirstream); + return 0; } +static const char quota_cmd_group_info[] = +"manage filesystem quota settings"; + const struct cmd_group quota_cmd_group = { - quota_cmd_group_usage, NULL, { + quota_cmd_group_usage, quota_cmd_group_info, { { "enable", cmd_quota_enable, cmd_quota_enable_usage, NULL, 0 }, - { "disable", cmd_quota_disable, cmd_quota_disable_usage, 0, 0 }, + { "disable", cmd_quota_disable, cmd_quota_disable_usage, + NULL, 0 }, { "rescan", cmd_quota_rescan, cmd_quota_rescan_usage, NULL, 0 }, - { 0, 0, 0, 0, 0 } + NULL_CMD_STRUCT } };