From 7c02893e12e207ac543a15da15bdf5fa9597df9b Mon Sep 17 00:00:00 2001 From: Frederick Dilger Date: Mon, 2 Sep 2024 15:31:20 -0600 Subject: [PATCH] LU-18079 utils: argument parse opts for lfs quota Adding new options to only get certain arguments from 'lfs quota'. This works much like 'lfs getstripe'. Each option will show their respected argument and can be combined together to show multiple arguments. They will be shown in the same order that they appear in the full table for 'lfs quota'. Added: --filesystem|--mount-point --blocks|--space|--busage --block-softlimit|--bsoftlimit --block-hardlimit|--bhardlimit --block-grace|--bgrace|--btime --inodes|--iusage --inode-softlimit|--isoftlimit --inode-hardlimit|--ihardlimit --inode-grace|--igrace|--itime each matching a column of the table. Signed-off-by: Frederick Dilger Change-Id: Iffb9be9a55368a3faad3a8e74ee2f2a6b1ec7301 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55894 Reviewed-by: Andreas Dilger Reviewed-by: Sergey Cheremencev Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- lustre/doc/lfs-quota.1 | 126 ++++++++++--- lustre/include/uapi/linux/lustre/lustre_user.h | 11 ++ lustre/tests/sanity-quota.sh | 2 +- lustre/utils/lfs.c | 244 +++++++++++++++++++------ 4 files changed, 298 insertions(+), 85 deletions(-) diff --git a/lustre/doc/lfs-quota.1 b/lustre/doc/lfs-quota.1 index 8f349f1..5f59a5f 100644 --- a/lustre/doc/lfs-quota.1 +++ b/lustre/doc/lfs-quota.1 @@ -2,31 +2,43 @@ .SH NAME lfs-quota \- display quota limits and status for users, groups, or projects. .SH SYNOPSIS -.BR "lfs quota " [ -q "] [" -v "] [" -h "] [" -o -.IR OBD_UUID | \fB-i -.IR MDT_IDX | \fB-I -.IR OST_IDX "] [" \fB-u -.IR USER | \fB-g -.IR GROUP | \fB-p -.IR PROJID "] [" \fB--pool -.IR OST_POOL_NAME "] [" MOUNT_POINT " ...]" - -.br +.SY "lfs quota" +.RB [ -q ] +.RB [ -v ] +.RB [ -h ] +.RB [ -o +.IR OBD_UUID | OST_IDX +.RB "| " -m +.IR MDT_IDX ] +.RB [ -u +.IR USER " |" +.BI "-g " GROUP +.RB "| " -p +.IR PROJID ] +.RB [ --pool +.IR OST_POOL_NAME ] +.EX +.RB [ --filesystem | --mount-point ] +.RB [ --blocks | --busage | --space ] +.RB [ --block-softlimit | --bsoftlimit ] +.RB [ --block-hardlimit | --bhardlimit ] +.RB [ --block-grace | --bgrace | --btime ] +.RB [ --inodes | --iusage ] +.RB [ --inode-softlimit | --isoftlimit ] +.RB [ --inode-hardlimit | --ihardlimit ] +.RB [ --inode-grace | --igrace | --itime ] +.EE +.RI [ MOUNT_POINT " ...]" +.SY .BR "lfs quota " [ -hq "] {" -U | -G | -P } .RI [ MOUNT_POINT " ...]" -.br - -.br +.SY .BR "lfs quota " -t " {" -u | -g | -p } .RI [ MOUNT_POINT " ...]" -.br - -.br +.SY .BR "lfs quota " -a " {" -u | -g | -p } .RI [ MOUNT_POINT " ...]" -.br - -.TP +.YS .SH DESCRIPTION .PP .TP @@ -54,8 +66,59 @@ which specify units of 2^10, 2^20, 2^30, 2^40, 2^50 and 2^60 bytes, respectively. Time values will use the "XXwXXdXXhXXmXXs" format, which specifies weeks, days, hours, minutes, seconds. .TP -.BR -g | --group " {" \fIGROUP | \fIGID } -Display quota information for group name \fIGROUP\fR or numeric \fIGID\fR. +.BR --blocks | --busage | --space +Print only the +.B kbytes +column representing the block usage space. +If other column options are specified, all specified columns will be printed. +.TP +.BR --block-softlimit | --bsoftlimit +Print only the +.B bquota +column representing the block soft-limit. +If other column options are specified, all specified columns will be printed. +.TP +.BR --block-hardlimit | --bhardlimit +Print only the +.B blimit +column representing the block hard-limit. +If other column options are specified, all specified columns will be printed. +.TP +.BR --blocks-grace | --bgrace | --btime +Print only the +.B bgrace +column representing the block grace time. +If other column options are specified, all specified columns will be printed. +.TP +.BR --filesystem | --mount-point +Print only the +.B filesystem +column representing either the mount point or device name. +If other column options are specified, all specified columns will be printed. +.TP +.BR --inodes | --iusage +Print only the +.B files +column representing the inodes. +If other column options are specified, all specified columns will be printed. +.TP +.BR --inode-softlimit | --isoftlimit +Print only the +.B iquota +column representing the inode soft-limit. +If other column options are specified, all specified columns will be printed. +.TP +.BR --inode-hardlimit | --ihardlimit +Print only the +.B ilimit +column representing the inode hard-limit. +If other column options are specified, all specified columns will be printed. +.TP +.BR --ilocks-grace | --igrace | --itime +Print only the +.B igrace +column representing the inode grace time. +If other column options are specified, all specified columns will be printed. .TP .BR -m | --mdt " " \fIMDT_IDX Display quota information for MDT \fIMDT_IDX\fR. @@ -66,13 +129,13 @@ Display quota information for OST \fIOST_IDX\fR. .BR --pool " " \fIPOOL_NAME Display quota information for OST pool \fIPOOL_NAME\fR. .TP -.BR -p | --projid " " \fIPROJID -Display quota information for project \fIPROJID\fR. -.TP .BR -q | --quiet Display only the line containing the data. The line saying what the data is, and the column headers will not be printed. .TP +.BR -g | --group " {" \fIGROUP | \fIGID } +Display quota information for group name \fIGROUP\fR or numeric \fIGID\fR. +.TP .BR -u | --user " {" \fIUSER \fR| \fIUID \fR} Display quota information for user name .I USER @@ -82,6 +145,9 @@ Can be used without specifying the mount point to get quota information from all filesystems for the specified .IR USER | UID . .TP +.BR -p | --projid " " \fIPROJID +Display quota information for project \fIPROJID\fR. +.TP .BR -v | --verbose Display per-MDT and per-OST statistics in addition to the usual system wide data. An asterisk near the OST or MDT means that @@ -137,7 +203,17 @@ from the OST pool .B $ lfs quota -t -g --pool flash_pool /mnt/lustre Display grace times for group quotas for the OST pool .BR flash_pool . -.TP +.EX +.B $ lfs quota --filesystem --blocks --inodes +Disk quotas for usr root (uid 0): + Filesystem kbytes files + /mnt/lustre 5236 308 + /mnt/lustre2 5236 308 +Disk quotas for grp root (gid 0): + Filesystem kbytes files + /mnt/lustre 5236 308 + /mnt/lustre2 5236 308 +.EE .SH SEE ALSO .BR lfs (1), .BR lfs-setquota(1) diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index d3b52381..097690e 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -1555,6 +1555,17 @@ struct sepol_downcall_data { #endif /* !__KERNEL__ */ +/* these are not defined in the kernel */ +#ifndef QIF_BSOFTLIMIT +#define QIF_BSOFTLIMIT 1024 +#define QIF_BHARDLIMIT QIF_BLIMITS +#define QIF_ISOFTLIMIT 2048 +#define QIF_IHARDLIMIT QIF_ILIMITS +#define QIF_FILESYSTEM 4096 +#define QIF_ALL_DETAIL (QIF_ALL | QIF_BSOFTLIMIT | QIF_ISOFTLIMIT | \ +QIF_FILESYSTEM) +#endif + /* lustre volatile file support * file name header: ".^L^S^T^R:volatile" */ diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 5079252..7042f85 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -5627,7 +5627,7 @@ test_73a() pool_add_targets $qpool 0 $((OSTCOUNT - 1)) || error "pool_add_targets failed" - test_default_quota "-u" "data" "qpool1" + test_default_quota "-u" "data" $qpool } run_test 73a "default limits at OST Pool Quotas" diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index e08a97d..e5b4ccd 100755 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -107,6 +107,8 @@ struct quota_param { unsigned int qp_show_default:1; unsigned int qp_show_pools:1; unsigned int qp_show_qid:1; + unsigned int qp_show_title:1; + __u32 qp_detail; }; static int lfs_setquota(int argc, char **argv); @@ -531,9 +533,19 @@ command_t cmdlist[] = { " [--pool POOL] MOUNT_POINT\n" " setquota {-u|-g|-p ID} {--default|--delete} MOUNT_POINT\n"}, {"quota", lfs_quota, 0, "Display disk usage and limits.\n" - "usage: quota [-q] [-v] [-h] [-o OBD_UUID|-i MDT_IDX|-I OST_IDX]\n" + "usage: quota [-q] [-v] [-h] [-o OBD_UUID|-o OST_IDX|-m MDT_IDX]\n" " [{-u|-g|-p} UNAME|UID|GNAME|GID|PROJID]\n" - " [--pool OST_POOL_NAME] [MOUNT_POINT ...]\n" + " [--pool OST_POOL_NAME]\n" + " [--filesystem|--mount-point]\n" + " [--blocks|--busage|--space]\n" + " [--block-softlimit|--bsoftlimit]\n" + " [--block-hardlimit|--bhardlimit]\n" + " [--block-grace|--bgrace|--btime]\n" + " [--inodes|--iusage]\n" + " [--inode-softlimit|--isoftlimit]\n" + " [--inode-hardlimit|--ihardlimit]\n" + " [--inode-grace|--igrace|--itime]\n" + " [MOUNT_POINT ...]\n" " quota -t {-u|-g|-p} [--pool OST_POOL_NAME] [MOUNT_POINT ...]\n" " quota [-hqv] {-U|-G|-P} [--pool OST_POOL_NAME] [MOUNT_POINT ...]\n" " quota -a {-u|-g|-p} [-s START_QID] [-e END_QID] [MOUNT_POINT ...]\n"}, @@ -3704,6 +3716,13 @@ enum { LFS_ATTRS_OPT, LFS_XATTRS_MATCH_OPT, LFS_MIGRATE_NOFIX, + LFS_QUOTA_FILESYSTEM_OPT, + LFS_QUOTA_SPACE_OPT, + LFS_QUOTA_BGRACE_OPT, + LFS_QUOTA_INODES_OPT, + LFS_QUOTA_ISOFTLIMIT_OPT, + LFS_QUOTA_IHARDLIMIT_OPT, + LFS_QUOTA_IGRACE_OPT, }; #ifndef LCME_USER_MIRROR_FLAGS @@ -9194,26 +9213,37 @@ static void print_quota_title(char *name, struct if_quotactl *qctl, if (param->qp_show_qid) { printf("Disk %s quotas\n", qtype_name(qctl->qc_type)); - printf("%16s %9s %7s %7s %7s %7s %7s %7s %7s %7s\n", - "Filesystem", "quota_id", - param->qp_human_readable ? "used" : "kbytes", - "quota", "limit", "grace", - "files", "quota", "limit", "grace"); } else if (param->qp_show_default) { printf("Disk default %s quota:\n", qtype_name(qctl->qc_type)); - printf("%16s %7s %7s %7s %7s %7s %7s\n", - "Filesystem", "bquota", "blimit", "bgrace", - "iquota", "ilimit", "igrace"); } else { printf("Disk quotas for %s %s (%cid %u):\n", qtype_name(qctl->qc_type), name, *qtype_name(qctl->qc_type), qctl->qc_id); - printf("%16s %7s %7s %7s %7s %7s %7s %7s %7s\n", - "Filesystem", - param->qp_human_readable ? "used" : "kbytes", - "quota", "limit", "grace", - "files", "quota", "limit", "grace"); } + + if (param->qp_detail & QIF_FILESYSTEM) + printf("%16s", "Filesystem"); + + if (param->qp_show_qid) + printf(" %9s", "quota_id"); + + if ((param->qp_detail & QIF_SPACE) && !param->qp_show_default) + printf(" %7s ", param->qp_human_readable ? "used" : "kbytes"); + if (param->qp_detail & QIF_BSOFTLIMIT) + printf(" %7s", "bquota"); + if (param->qp_detail & QIF_BHARDLIMIT) + printf(" %7s", "blimit"); + if (param->qp_detail & QIF_BTIME) + printf(" %7s", "bgrace"); + if ((param->qp_detail & QIF_INODES) && !param->qp_show_default) + printf(" %7s ", "files"); + if (param->qp_detail & QIF_ISOFTLIMIT) + printf(" %7s", "iquota"); + if (param->qp_detail & QIF_IHARDLIMIT) + printf(" %7s", "ilimit"); + if (param->qp_detail & QIF_ITIME) + printf(" %7s", "igrace"); + printf("\n"); } static void kbytes2str(__u64 num, char *buf, int buflen, bool h) @@ -9253,7 +9283,7 @@ static void kbytes2str(__u64 num, char *buf, int buflen, bool h) #define STRBUF_LEN 24 static void print_quota(char *mnt, struct if_quotactl *qctl, int type, - int rc, bool h, bool show_default, bool show_qid) + int rc, struct quota_param *param) { char *name, *tmp; time_t now; @@ -9297,56 +9327,66 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, if (tmp) *tmp = '\0'; - printf("%16s", mnt); /* Filesystem */ - if (show_qid) { + if (param->qp_detail & QIF_FILESYSTEM) + printf((param->qp_detail & ~QIF_FILESYSTEM) ? + "%16s" : "%s", mnt); /* Filesystem */ + + if (param->qp_show_qid) { + name = NULL; + if (qctl->qc_type == USRQUOTA) { - if (uid2name(&name, qctl->qc_id)) - printf(" %9u", qctl->qc_id); - else - printf(" %9s", name); + uid2name(&name, qctl->qc_id); } else if (qctl->qc_type == GRPQUOTA) { - if (gid2name(&name, qctl->qc_id)) - printf(" %9u", qctl->qc_id); - else - printf(" %9s", name); - } else { - printf(" %9u", qctl->qc_id); + gid2name(&name, qctl->qc_id); } + if (name && name[0] != '\0') + printf(" %9s", name); + else + printf(" %9u", qctl->qc_id); } - if (show_default) + if (param->qp_show_default) snprintf(timebuf, sizeof(timebuf), "%llu", (unsigned long long)dqb->dqb_btime); else if (bover) diff2str(dqb->dqb_btime, timebuf, now); kbytes2str(lustre_stoqb(dqb->dqb_curspace), - strbuf, sizeof(strbuf), h); + strbuf, sizeof(strbuf), param->qp_human_readable); if (rc == -EREMOTEIO) sprintf(numbuf[0], "%s*", strbuf); else sprintf(numbuf[0], (dqb->dqb_valid & QIF_SPACE) ? "%s" : "[%s]", strbuf); - kbytes2str(dqb->dqb_bsoftlimit, strbuf, sizeof(strbuf), h); + kbytes2str(dqb->dqb_bsoftlimit, strbuf, sizeof(strbuf), + param->qp_human_readable); if (type == QC_GENERAL) sprintf(numbuf[1], (dqb->dqb_valid & QIF_BLIMITS) ? "%s" : "[%s]", strbuf); else sprintf(numbuf[1], "%s", "-"); - kbytes2str(dqb->dqb_bhardlimit, strbuf, sizeof(strbuf), h); + kbytes2str(dqb->dqb_bhardlimit, strbuf, sizeof(strbuf), + param->qp_human_readable); sprintf(numbuf[2], (dqb->dqb_valid & QIF_BLIMITS) ? "%s" : "[%s]", strbuf); - if (show_default) - printf(" %7s %7s %7s", numbuf[1], numbuf[2], timebuf); - else - printf(" %7s%c %6s %7s %7s", - numbuf[0], bover ? '*' : ' ', numbuf[1], - numbuf[2], bover > 1 ? timebuf : "-"); - - if (show_default) + if ((param->qp_detail & QIF_SPACE) && !param->qp_show_default) + printf((param->qp_detail & ~QIF_SPACE) ? + " %7s%c" : "%s", numbuf[0], bover ? '*' : ' '); + if (param->qp_detail & QIF_BSOFTLIMIT) { + printf(param->qp_detail & ~QIF_BSOFTLIMIT ? + " %7s" : "%s", numbuf[1]); + } + if (param->qp_detail & QIF_BHARDLIMIT) + printf(param->qp_detail & ~QIF_BHARDLIMIT ? + " %7s" : "%s", numbuf[2]); + if (param->qp_detail & QIF_BTIME) + printf(param->qp_detail & ~QIF_BTIME ? + " %7s" : "%s", bover > 1 ? timebuf : "-"); + + if (param->qp_show_default) snprintf(timebuf, sizeof(timebuf), "%llu", (unsigned long long)dqb->dqb_itime); else if (iover) @@ -9366,14 +9406,23 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, sprintf(numbuf[2], (dqb->dqb_valid & QIF_ILIMITS) ? "%ju" : "[%ju]", (uintmax_t)dqb->dqb_ihardlimit); - if (show_default) - printf(" %7s %7s %7s", numbuf[1], numbuf[2], timebuf); - else if (type != QC_OSTIDX) - printf(" %7s%c %6s %7s %7s", - numbuf[0], iover ? '*' : ' ', numbuf[1], - numbuf[2], iover > 1 ? timebuf : "-"); - else - printf(" %7s %7s %7s %7s", "-", "-", "-", "-"); + if ((param->qp_detail & QIF_INODES) && !param->qp_show_default) + printf(param->qp_detail & ~QIF_INODES ? + " %7s%c" : "%s", type != QC_OSTIDX ? + numbuf[0] : "-", bover ? '*' : ' '); + if (param->qp_detail & QIF_ISOFTLIMIT) { + printf(param->qp_detail & ~QIF_ISOFTLIMIT ? + " %7s" : "%s", type != QC_OSTIDX ? + numbuf[1] : "-"); + } + if (param->qp_detail & QIF_IHARDLIMIT) + printf(param->qp_detail & ~QIF_IHARDLIMIT ? + " %7s" : "%s", type != QC_OSTIDX ? + numbuf[2] : "-"); + if (param->qp_detail & QIF_ITIME) + printf(param->qp_detail & ~QIF_ITIME ? " %7s" : "%s", + type != QC_OSTIDX && iover > 1 ? timebuf : "-"); + printf("\n"); } else if (qctl->qc_cmd == LUSTRE_Q_GETINFO || qctl->qc_cmd == LUSTRE_Q_GETINFOPOOL || @@ -9417,7 +9466,7 @@ static int tgt_name2index(const char *tgtname, unsigned int *idx) } static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt, - bool h, __u64 *total) + struct quota_param *param, __u64 *total) { int rc = 0, rc1 = 0, count = 0, i = 0; char **list = NULL, *buffer = NULL; @@ -9493,8 +9542,8 @@ static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt, sizeof(qctl->qc_dqinfo)); memset(&qctl->qc_dqblk, 0, sizeof(qctl->qc_dqblk)); - print_quota(name, qctl, qctl->qc_valid, 0, h, - false, false); + print_quota(name, qctl, qctl->qc_valid, 0, + param); rc = 0; continue; } @@ -9507,7 +9556,7 @@ static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt, } print_quota(obd_uuid2str(&qctl->obd_uuid), qctl, - qctl->qc_valid, 0, h, false, false); + qctl->qc_valid, 0, param); *total += is_mdt ? qctl->qc_dqblk.dqb_ihardlimit : qctl->qc_dqblk.dqb_bhardlimit; } @@ -9556,8 +9605,7 @@ static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl, ((qctl->qc_dqblk.dqb_valid & (QIF_LIMITS|QIF_USAGE)) != (QIF_LIMITS|QIF_USAGE)); - print_quota(mnt, qctl, QC_GENERAL, rc, param->qp_human_readable, - param->qp_show_default, param->qp_show_qid); + print_quota(mnt, qctl, QC_GENERAL, rc, param); if (!param->qp_show_qid && !param->qp_show_default && param->qp_verbose && qctl->qc_valid == QC_GENERAL && @@ -9565,9 +9613,9 @@ static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl, qctl->qc_cmd != LUSTRE_Q_GETINFOPOOL) { char strbuf[STRBUF_LEN]; - rc1 = print_obd_quota(mnt, qctl, 1, param->qp_human_readable, + rc1 = print_obd_quota(mnt, qctl, 1, param, &total_ialloc); - rc2 = print_obd_quota(mnt, qctl, 0, param->qp_human_readable, + rc2 = print_obd_quota(mnt, qctl, 0, param, &total_balloc); kbytes2str(total_balloc, strbuf, sizeof(strbuf), param->qp_human_readable); @@ -9906,7 +9954,8 @@ static int lfs_quota(int argc, char **argv) { .val = 'G', .name = "default-grp", .has_arg = no_argument }, { .val = 'h', .name = "human-readable", .has_arg = no_argument }, /* It is unfortunate that '-i' was used for mdt-index, and '-I' for - * ost-index, because '-i' is used for ost-index everywhere else. + * ost-index, because '-i' is used for ost-index everywhere else. '-i' + * and '-I' are also used for soft/hard inode quotas in lfs_setquota(). * These options have been this way since ancient days, but I suspect * that they are not often used. Prefer --ost and --mdt instead. */ @@ -9923,6 +9972,53 @@ static int lfs_quota(int argc, char **argv) { .val = 'u', .name = "user", .has_arg = required_argument }, { .val = 'U', .name = "default-usr", .has_arg = required_argument }, { .val = 'v', .name = "verbose", .has_arg = no_argument }, + { .val = LFS_QUOTA_FILESYSTEM_OPT, + .name = "filesystem", .has_arg = no_argument }, + { .val = LFS_QUOTA_FILESYSTEM_OPT, + .name = "mount-point", .has_arg = no_argument }, + { .val = LFS_QUOTA_SPACE_OPT, + .name = "blocks", .has_arg = no_argument }, + { .val = LFS_QUOTA_SPACE_OPT, + .name = "busage", .has_arg = no_argument }, + { .val = LFS_QUOTA_SPACE_OPT, + .name = "space", .has_arg = no_argument }, + { .val = 'b', + .name = "block-softlimit", .has_arg = no_argument }, + { .val = 'b', + .name = "bsoftlimit", .has_arg = no_argument }, + { .val = 'b', .name = "bquota", .has_arg = no_argument }, + { .val = 'B', + .name = "block-hardlimit", .has_arg = no_argument }, + { .val = 'B', .name = "bhardlimit", .has_arg = no_argument }, + { .val = 'B', .name = "blimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_BGRACE_OPT, + .name = "block-grace", .has_arg = no_argument }, + { .val = LFS_QUOTA_BGRACE_OPT, + .name = "bgrace", .has_arg = no_argument }, + { .val = LFS_QUOTA_BGRACE_OPT, + .name = "btime", .has_arg = no_argument }, + { .val = LFS_QUOTA_INODES_OPT, + .name = "inodes", .has_arg = no_argument }, + { .val = LFS_QUOTA_INODES_OPT, + .name = "iusage", .has_arg = no_argument }, + { .val = LFS_QUOTA_ISOFTLIMIT_OPT, + .name = "inode-softlimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_ISOFTLIMIT_OPT, + .name = "isoftlimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_ISOFTLIMIT_OPT, + .name = "iquota", .has_arg = no_argument }, + { .val = LFS_QUOTA_IHARDLIMIT_OPT, + .name = "inode-hardlimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_IHARDLIMIT_OPT, + .name = "ihardlimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_IHARDLIMIT_OPT, + .name = "ilimit", .has_arg = no_argument }, + { .val = LFS_QUOTA_IGRACE_OPT, + .name = "inode-grace", .has_arg = no_argument }, + { .val = LFS_QUOTA_IGRACE_OPT, + .name = "igrace", .has_arg = no_argument }, + { .val = LFS_QUOTA_IGRACE_OPT, + .name = "itime", .has_arg = no_argument }, { .name = NULL } }; qctl = calloc(1, sizeof(*qctl) + LOV_MAXPOOLNAME + 1); @@ -9933,13 +10029,19 @@ static int lfs_quota(int argc, char **argv) qctl->qc_type = ALLQUOTA; obd_uuid = (char *)qctl->obd_uuid.uuid; - while ((c = getopt_long(argc, argv, "ae:gGhi:I:m:o:pPqs:tuUv", + while ((c = getopt_long(argc, argv, "abBe:gGhi:I:m:o:pPqs:tuUv", long_opts, NULL)) != -1) { switch (c) { case 'a': param.qp_show_qid = 1; qctl->qc_cmd = LUSTRE_Q_ITERQUOTA; break; + case 'b': + param.qp_detail |= QIF_BSOFTLIMIT; + break; + case 'B': + param.qp_detail |= QIF_BHARDLIMIT; + break; case 'e': if (optarg == NULL || *optarg == '\0') { fprintf(stderr, @@ -10004,7 +10106,7 @@ static int lfs_quota(int argc, char **argv) /* need to also handle a UUID for compatibility */ param.qp_valid = qctl->qc_valid = QC_UUID; - snprintf(obd_uuid, sizeof(*obd_uuid), "%s", optarg); + snprintf(obd_uuid, UUID_MAX, "%s", optarg); break; case 'P': param.qp_show_default = 1; @@ -10072,6 +10174,27 @@ quota_type: case 'v': param.qp_verbose = 1; break; + case LFS_QUOTA_FILESYSTEM_OPT: + param.qp_detail |= QIF_FILESYSTEM; + break; + case LFS_QUOTA_SPACE_OPT: + param.qp_detail |= QIF_SPACE; + break; + case LFS_QUOTA_BGRACE_OPT: + param.qp_detail |= QIF_BTIME; + break; + case LFS_QUOTA_INODES_OPT: + param.qp_detail |= QIF_INODES; + break; + case LFS_QUOTA_ISOFTLIMIT_OPT: + param.qp_detail |= QIF_ISOFTLIMIT; + break; + case LFS_QUOTA_IHARDLIMIT_OPT: + param.qp_detail |= QIF_IHARDLIMIT; + break; + case LFS_QUOTA_IGRACE_OPT: + param.qp_detail |= QIF_ITIME; + break; default: fprintf(stderr, "%s quota: unrecognized option '%s'\n", progname, argv[optind - 1]); @@ -10080,6 +10203,9 @@ quota_type: } } + if (!param.qp_detail) + param.qp_detail = QIF_ALL_DETAIL; + if (qctl->qc_cmd == LUSTRE_Q_ITERQUOTA) { if (qctl->qc_type == ALLQUOTA) { fprintf(stderr, "%s quota: no quota type to iterate\n", -- 1.8.3.1