Whamcloud - gitweb
LU-17702 utils: 'lfs quota' MOUNT_POINT optional 83/55683/22
authorFrederick Dilger <fdilger@whamcloud.com>
Tue, 9 Jul 2024 22:01:36 +0000 (16:01 -0600)
committerOleg Drokin <green@whamcloud.com>
Fri, 16 Aug 2024 23:52:51 +0000 (23:52 +0000)
Specifying the MOUNT_POINT is now optional for 'lfs quota'.
Additionally multiple mount points can now be specified
to print quota information for each one.

If the mount point is not specified, quota information for ALL
mounted filesystems will be printed instead.

Changes were made to fix the quota formatting as some columns were
misaligned. Filesystem is no longer placed on newline if the
name exceeds 16 characters, this should make for better argument
parsing.

Signed-off-by: Frederick Dilger <fdilger@whamcloud.com>
Change-Id: I3985855c5ce67be0fb8107c046bd54b802e1f6f1
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55683
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-quota.1
lustre/doc/lfs-setquota.1
lustre/tests/sanity-quota.sh
lustre/utils/lfs.c

index e08a56f..8f349f1 100644 (file)
@@ -2,28 +2,37 @@
 .SH NAME
 lfs-quota \- display quota limits and status for users, groups, or projects.
 .SH SYNOPSIS
-.BR "lfs quota " [ -hqv "] [" --ost " \fIobd_uuid\fR|" --mdt " \fIMDT_IDX\fR]
-       [\fB-u \fIUSER\fR|\fB-g <\fIGROUP\fR>|\fB-p \fIPROJID\fR]
-[\fB--pool\fR \fIPOOL_NAME\fR] \fIFILESYSTEM
+.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
-.BR "lfs quota " [ -hq "] {" -U | -G | -P } " " \fIFILESYSTEM
+.BR "lfs quota " [ -hq "] {" -U | -G | -P }
+.RI [ MOUNT_POINT " ...]"
 .br
 
 .br
-.BR "lfs quota " -t " {" -u | -g | -p "} " \fIFILESYSTEM
+.BR "lfs quota " -t " {" -u | -g | -p }
+.RI [ MOUNT_POINT " ...]"
 .br
 
 .br
-.B lfs quota -a \fR<\fB-u\fR|\fB-g\fR|\fB-p\fR> <\fIfilesystem\fR>
+.BR "lfs quota " -a " {" -u | -g | -p }
+.RI [ MOUNT_POINT " ...]"
 .br
 
 .TP
 .SH DESCRIPTION
 .PP
 .TP
-.B lfs quota \fIFILESYSTEM
-Display disk usage and limits for individual users, groups, and projects.
+.BR "lfs quota " [ \fIMOUNT_POINT " ...]"
+Display disk usage and limits for individual users, groups, and projects for
+each MOUNT_POINT.
 An asterisk is displayed when the quota is exceeded.
 By default the statistics for the entire filesystem are displayed but
 individual MDTs and OSTs can be specified with the
@@ -33,6 +42,7 @@ or
 options.  A user, group, or project ID can be specified.
 If user, group, and project are omitted, quotas for the
 current uid/gid/projid are shown.
+If no MOUNT_POINT is specified, quotas for all Lustre mountpoints will be shown.
 .TP
 .BR -h | --human-readable
 This will change the formatting of
@@ -63,8 +73,14 @@ Display quota information for project \fIPROJID\fR.
 Display only the line containing the data.
 The line saying what the data is, and the column headers will not be printed.
 .TP
-.BR -u | --user " {" \fIUSER | \fIUID }
-Display quota information for user name \fIUSER\fR or numeric \fIUID\fR.
+.BR -u | --user " {" \fIUSER \fR| \fIUID \fR}
+Display quota information for user name
+.I USER
+or numeric
+.IR UID .
+Can be used without specifying the mount point to get quota information
+from all filesystems for the specified
+.IR USER | UID .
 .TP
 .BR -v | --verbose
 Display per-MDT and per-OST statistics in addition
@@ -73,7 +89,7 @@ the quota is exceeded only for that specific target. The user is over the
 quota only if an asterisk is near the whole filesystem usage.
 Inactive target will also be printed but marked as "inact".
 .TP
-.BR "lfs quota " { -U | -G | -P "} " FILESYSTEM
+.BR "lfs quota " { -U | -G | -P "} " MOUNT_POINT
 Display default quota values for users, groups, or projects.
 This command requires super user permissions.
 .TP
@@ -86,11 +102,15 @@ Display default quota limits for project \fIPROJID\fR.
 .BR -U | --default-usr " {" \fIUSER | UID }
 Display default quota limits for username \fIUSER\fR or numeric \fIUID\fR.
 .TP
-.BR "lfs quota -a" " {" -u | -g | -p "} " \fIFILESYSTEM
+.BR "lfs quota -a" " {" -u | -g | -p "} " \fIMOUNT_POINT
 .TP
 Display all quota setting for all users, groups, or projects.
 .TP
-.BR "lfs quota -t" | --times " {" -u | -g | -p "} [" --pool " \fIPOOL_NAME\fR] " \fIFILESYSTEM
+.B "lfs quota -a -u"
+.TP
+Display all quota settings for all users across all mounted filesystems.
+.TP
+.BR "lfs quota -t" | --times " {" -u | -g | -p "} [" --pool " \fIPOOL_NAME\fR] " \fIMOUNT_POINT
 Display grace times for users, groups, or projects.
 Time values use the "XXwXXdXXhXXmXXs" format, which specifies
 weeks, days, hours, minutes, seconds.
index 92b4f6d..0b0cf6c 100644 (file)
@@ -7,20 +7,20 @@ lfs-setquota \- set quota limits or grace time for users, groups or projects.
        [\fB-b|\fB--block-softlimit\fR \fIBLOCK_SOFTLIMIT\fR[\fBKMGTPE\fR]]
        [\fB-B|\fB--block-hardlimit\fR \fIBLOCK_HARDLIMIT\fR[\fBKMGTPE\fR]]
        [\fB-i|\fB--inode-softlimit\fR \fIINODE_SOFTLIMIT\fR[\fBKMGTPE\fR]]
-       [\fB-I|\fB--inode-hardlimit\fR \fIINODE_HARDLIMIT\fR[\fBKMGTPE\fR]] \fIFILESYSTEM
+       [\fB-I|\fB--inode-hardlimit\fR \fIINODE_HARDLIMIT\fR[\fBKMGTPE\fR]] \fIMOUNT_POINT
 .TP
 .BR "lfs setquota " { -u | --user | -g | --group | -p | --projid "} " \fIID
- {\fB--default\fR|\fB-D\fR|\fB--delete\fR} \fIFILESYSTEM
+ {\fB--default\fR|\fB-D\fR|\fB--delete\fR} \fIMOUNT_POINT
 .TP
 .BR "lfs setquota " { -t | --times "} {" -h | -u | -g | -p "} [" "--pool " \fIPOOLNAME ]
  [\fB-b\fR|\fB--block-grace\fR \fIBLOCK_GRACE_TIME\fR]
- [\fB-i\fR|\fB--inode-grace\fR \fIINODE_GRACE_TIME\fR] \fIFILESYSTEM
+ [\fB-i\fR|\fB--inode-grace\fR \fIINODE_GRACE_TIME\fR] \fIMOUNT_POINT
 .TP
 .BR "lfs setquota " { -U | --default-usr | -G | --default-grp | -P | --default-prj }
        [\fB-b\fR|\fB--block-softlimit\fR \fIBLOCK_SOFTLIMIT\fR[\fBKMGTPE\fR]]
        [\fB-B\fR|\fB--block-hardlimit\fR \fIBLOCK_HARDLIMIT\fR[\fBKMGTPE\fR]]
        [\fB-i\fR|\fB--inode-softlimit\fR \fIINODE_SOFTLIMIT\fR[\fBKMGTPE\fR]]
-       [\fB-I\fR|\fB--inode-hardlimit\fR \fIINODE_HARDLIMIT\fR[\fBKMGTPE\fR]] \fIFILESYSTEM
+       [\fB-I\fR|\fB--inode-hardlimit\fR \fIINODE_HARDLIMIT\fR[\fBKMGTPE\fR]] \fIMOUNT_POINT
 .TP
 .BR "lfs setquota " { -u | --user | -g | --group | -p | --projid "} " \fIUID\fR|\fIGID\fR|\fIPROJID\fR
        [\fB--delete\fR] <\fIfilesystem\fR>
index 654d633..be86060 100755 (executable)
@@ -201,8 +201,9 @@ getquota() {
        [ ! -z "$5" ] && pool_arg="--pool $5 "
        [ "$uuid" = "global" ] && uuid=$DIR
 
+       $LFS quota -v "$1" "$2" $pool_arg $DIR 1>&2
        $LFS quota -v "$1" "$2" $pool_arg $DIR |
-               awk 'BEGIN { num='$spec' } { if ($1 == "'$uuid'") \
+               awk 'BEGIN { num='$spec' } { if ($1 ~ "'$uuid'") \
                { if (NF == 1) { getline } else { num++ } ; print $num;} }' \
                | tr -d "*"
 }
@@ -564,7 +565,7 @@ wait_quota_synced() {
 check_system_is_clean() {
        local used
 
-       lfs quota -uv $TSTUSR $MOUNT
+       lfs quota -v -u $TSTUSR $MOUNT
        for cur in "curspace" "curinodes";
        do
                used=$(getquota -u $TSTUSR global $cur)
@@ -1260,7 +1261,7 @@ test_1i() {
        $LFS setquota -u $TSTUSR -B 0 --pool $qpool1 $DIR ||
                error "set user quota failed"
 
-       $LFS quota -uv $TSTUSR --pool $qpool1 $DIR
+       $LFS quota -v -u $TSTUSR --pool $qpool1 $DIR
        $RUNAS $DD of=$testfile1 count=$((limit1/2)) ||
                quota_error u $TSTUSR "write failure, but expect success"
 
@@ -2146,7 +2147,7 @@ test_7a() {
        resetquota -u $TSTUSR
        set_ost_qtype "none" || error "disable ost quota failed"
 
-       local OSTUUID=$(ostuuid_from_index 0)
+       local OSTUUID=$(ostname_from_index 0)
        USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
        [ $USED -ne 0 ] &&
                error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
@@ -2213,7 +2214,7 @@ test_7b() {
        resetquota -u $TSTUSR
        set_ost_qtype "none" || error "disable ost quota failed"
 
-       local OSTUUID=$(ostuuid_from_index 0)
+       local OSTUUID=$(ostname_from_index 0)
        USED=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
        [ $USED -ne 0 ] &&
                error "limit($USED) on $OSTUUID for user $TSTUSR isn't 0"
@@ -2685,7 +2686,7 @@ test_13(){
        [ $nlock -eq $init_nlock ] || error "per-ID lock isn't cleared"
 
        # spare quota should be released
-       local OSTUUID=$(ostuuid_from_index 0)
+       local OSTUUID=$(ostname_from_index 0)
        local limit=$(getquota -u $TSTUSR $OSTUUID bhardlimit)
        local space=$(getquota -u $TSTUSR $OSTUUID curspace)
        [ $limit -le $space ] ||
@@ -3229,7 +3230,7 @@ test_23_sub() {
 
        cleanup_quota_test
 
-       local OST0_UUID=$(ostuuid_from_index 0)
+       local OST0_UUID=$(ostname_from_index 0)
        local OST0_QUOTA_USED=$(getquota -u $TSTUSR $OST0_UUID curspace)
        [ $OST0_QUOTA_USED -ne 0 ] &&
                ($SHOW_QUOTA_USER; \
@@ -4127,11 +4128,11 @@ test_get_allquota() {
        eval $($LFS quota -a -s $start_qid -e $end_qid -u $MOUNT |
            awk 'NR > 2 {printf("u_blimits[%d]=%d;u_ilimits[%d]=%d; \
                 u_busage[%d]=%d;u_iusage[%d]=%d;", \
-                NR, $4, NR, $8, NR, $2, NR, $6)}')
+                NR, $5, NR, $9, NR, $3, NR, $7)}')
        eval $($LFS quota -a -s $start_qid -e $end_qid -g $MOUNT |
            awk 'NR > 2 {printf("g_blimits[%d]=%d;g_ilimits[%d]=%d; \
                 g_busage[%d]=%d;g_iusage[%d]=%d;", \
-                NR, $4, NR, $8, NR, $2, NR, $6)}')
+                NR, $5, NR, $9, NR, $3, NR, $7)}')
 
        for i in $(seq $qid_cnt); do
                [ $i -le 2 ] && continue
@@ -4176,11 +4177,11 @@ test_get_allquota() {
        eval $($LFS quota -a -s $start_qid -e $end_qid -u $MOUNT |
            awk 'NR > 2 {printf("u_blimits[%d]=%d;u_ilimits[%d]=%d; \
                 u_busage2[%d]=%d;u_iusage2[%d]=%d;", \
-                NR, $4, NR, $8, NR, $2, NR, $6)}')
+                NR, $5, NR, $9, NR, $3, NR, $7)}')
        eval $($LFS quota -a -s $start_qid -e $end_qid  -g $MOUNT |
            awk 'NR > 2 {printf("g_blimits[%d]=%d;g_ilimits[%d]=%d; \
                 g_busage2[%d]=%d;g_iusage2[%d]=%d;", \
-                NR, $4, NR, $8, NR, $2, NR, $6)}')
+                NR, $5, NR, $9, NR, $3, NR, $7)}')
 
        sz=$((sz / 1024))
        for i in $(seq $qid_cnt); do
@@ -4240,7 +4241,7 @@ test_49()
        do_facet mds1 $LCTL set_param fail_loc=0
 
        start=$SECONDS
-       $LFS quota -a -u $MOUNT | tail -n 100
+       $LFS quota -a -u $MOUNT | head -n 100
        echo "get all usr quota: $total_file_cnt / $((SECONDS - start)) seconds"
 
        start=$SECONDS
@@ -5609,7 +5610,7 @@ test_72()
        used=$(getquota -u $TSTUSR global bhardlimit $qpool)
        echo "used $used"
        [ $used -ge $limit ] || error "used($used) is less than limit($limit)"
-       # check that lfs quota -uv --pool prints only OST that
+       # check that lfs quota -v -u --pool prints only OST that
        # was added in a pool
        lfs quota -v -u $TSTUSR --pool $qpool $DIR | grep -v "OST0001" |
                grep "OST\|MDT" && error "$qpool consists wrong targets"
@@ -5719,12 +5720,13 @@ test_74()
        [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit $tmp for $qpool2"
 
        # check limits in pools
+       $LFS quota -u $TSTUSR --pool $DIR
        tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
-             grep -A4 $qpool | awk 'NR == 4{print $4}')
+             grep -A4 $qpool | awk 'NR == 2{print $4}')
        echo "pool limit for $qpool $tmp"
-       [ $tmp -eq $((limit * 1024)) ] || error "wrong limit:tmp for $qpool"
+       [ $tmp -eq $((limit * 1024)) ] || error "wrong limit:$tmp for $qpool"
        tmp=$($LFS quota -u $TSTUSR --pool $DIR | \
-             grep -A4 $qpool2 | awk 'NR == 4{print $4}')
+             grep -A4 $qpool2 | awk 'NR == 2{print $4}')
        echo "pool limit for $qpool2 $tmp"
        [ $tmp -eq $((limit2 * 1024)) ] || error "wrong limit:$tmp for $qpool2"
 }
@@ -6098,7 +6100,7 @@ test_80()
        lfs getstripe $dir2
        sleep 3
 
-       $LFS quota -uv $TSTUSR $DIR
+       $LFS quota -v -u $TSTUSR $DIR
        #define OBD_FAIL_QUOTA_PREACQ            0xA06
        do_facet mds1 $LCTL set_param fail_loc=0xa06
        $RUNAS $DD of=$TESTFILE3 count=3 ||
@@ -6109,16 +6111,16 @@ test_80()
                quota_error u $TSTUSR "write failed"
        sync
        sleep 3
-       $LFS quota -uv --pool $qpool $TSTUSR $DIR
+       $LFS quota -v -u --pool $qpool $TSTUSR $DIR
 
        rm -f $TESTFILE2
        stop ost2
        do_facet mds1 $LCTL set_param fail_loc=0
        start ost2 $(ostdevname 2) $OST_MOUNT_OPTS || error "start ost2 failed"
-       $LFS quota -uv $TSTUSR --pool $qpool $DIR
+       $LFS quota -v -u $TSTUSR --pool $qpool $DIR
        # OST0 needs some time to update quota usage after removing TESTFILE2
        sleep 4
-       $LFS quota -uv $TSTUSR --pool $qpool $DIR
+       $LFS quota -v -u $TSTUSR --pool $qpool $DIR
        $RUNAS $DD of=$TESTFILE0 count=2 oflag=direct ||
                quota_error u $TSTUSR "write failure, but expect success"
 }
@@ -6283,8 +6285,8 @@ test_84()
        # the grant quota should be larger than 0
        waited=0
        while (( $waited < 60 )); do
-               grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit $qp)
-               grant2=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit)
+               grant=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit $qp)
+               grant2=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit)
                (( ${grant} > 0 && ${grant2} > 0 )) && break
 
                do_facet ost1 $LCTL set_param \
@@ -6315,8 +6317,8 @@ test_84()
        # the grant quota should be set as insane value
        waited=0
        while (( $waited < 60 )); do
-               grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit $qp)
-               grant2=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit)
+               grant=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit $qp)
+               grant2=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit)
                (( ${#grant} == 20 && ${#grant2} == 20 )) && break
 
                sleep 1
@@ -6343,9 +6345,9 @@ test_84()
        $LFS quota -gv --pool $qp $TSTUSR $DIR
 
        # the grant quota should be reset
-       grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit)
+       grant=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit)
        (( ${#grant} == 20 )) && error "grant is not cleared"
-       grant=$(getquota -g $TSTUSR lustre-OST0000_UUID bhardlimit $qp)
+       grant=$(getquota -g $TSTUSR lustre-OST0000 bhardlimit $qp)
        (( ${#grant} == 20 )) && error "pool grant is not cleared"
 
        $LFS quota -gv $TSTUSR --pool $qp $DIR
@@ -6452,7 +6454,7 @@ test_86()
 
        local test_dir="$DIR/$tdir/test_dir"
 
-       setup_quota_test || error "setup quota failed with %?"
+       setup_quota_test || error "setup quota failed with $?"
        set_mdt_qtype $QTYPE || error "enable mdt quota failed"
 
        $LFS setdirstripe -c 1 -i 0 $test_dir || error "setdirstripe failed"
@@ -6466,6 +6468,99 @@ test_86()
 }
 run_test 86 "Pre-acquired quota should be released if quota is over limit"
 
+check_quota_no_mount()
+{
+       local opts="$1"
+       local id="$2"
+
+       echo "cmd: $LFS quota $opts $id"
+       local expected=$($LFS quota $opts $id $MOUNT)
+       local actual=$($LFS quota $opts $id)
+
+       [[ "$actual" == "$expected" ]] ||
+               error "quota info not $expected, found: $actual"
+}
+
+check_quota_two_mounts()
+{
+       local opts="$1"
+       local id="$2"
+
+       local cmd="$LFS quota -q $opts $id $MOUNT $MOUNT2"
+       echo "cmd: $cmd"
+#      remove the header for comparison
+       local actual
+       local full=$($cmd)
+       local head=$($LFS quota -q $opts $id $MOUNT)
+       local tail=$($LFS quota -q $opts $id $MOUNT2)
+
+       actual=$(echo "$full" | head -n$(echo "$head" | wc -l))
+       [[ "$actual" == "$head" ]] ||
+               error "quota info from $MOUNT not '$head', found '$actual'"
+
+       actual=$(echo "$full" | tail -n$(echo "$tail" | wc -l))
+       [[ "$actual" == "$tail" ]] ||
+               error "quota info from $MOUNT2 not '$tail', found '$actual'"
+}
+
+test_90a()
+{
+       (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
+               skip "Need MDS version at least 2.15.60"
+
+       setup_quota_test || error "setup quota failed with $?"
+
+       stack_trap cleanup_quota_test
+
+       check_quota_no_mount
+       check_quota_no_mount -u $TSTUSR
+       check_quota_no_mount "-a -u"
+       check_quota_no_mount "-t -u"
+       check_quota_no_mount -U
+       check_quota_no_mount -g $TSTUSR
+       check_quota_no_mount "-a -g"
+       check_quota_no_mount "-t -g"
+       check_quota_no_mount -G
+
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       check_quota_no_mount -p 100
+       check_quota_no_mount "-a -p"
+       check_quota_no_mount "-t -p"
+       check_quota_no_mount -P
+}
+run_test 90a "lfs quota should work without mount point"
+
+test_90b()
+{
+       (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
+               skip "Need MDS version at least 2.15.60"
+
+       setup_quota_test || error "setup quota failed with $?"
+       mount_client $MOUNT2
+
+       stack_trap "umount $MOUNT2"
+       stack_trap cleanup_quota_test
+
+       check_quota_two_mounts -u $TSTUSR
+       check_quota_two_mounts "-a -u"
+       check_quota_two_mounts "-t -u"
+       check_quota_two_mounts -U
+       check_quota_two_mounts -g $TSTUSR
+       check_quota_two_mounts "-a -g"
+       check_quota_two_mounts "-t -g"
+       check_quota_two_mounts -G
+
+       ! is_project_quota_supported &&
+               skip "Project quota is not supported"
+       check_quota_two_mounts -p 1000
+       check_quota_two_mounts "-a -p"
+       check_quota_two_mounts "-t -p"
+       check_quota_two_mounts -P
+}
+run_test 90b "lfs quota should work with multiple mount points"
+
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) \
index a172a94..2d6191c 100755 (executable)
@@ -98,6 +98,16 @@ static int lfs_df(int argc, char **argv);
 static int lfs_getname(int argc, char **argv);
 static int lfs_check(int argc, char **argv);
 #ifdef HAVE_SYS_QUOTA_H
+struct quota_param {
+       __u32            qp_valid;
+       unsigned int     qp_verbose:1;
+       unsigned int     qp_quiet:1;
+       unsigned int     qp_human_readable:1;
+       unsigned int     qp_show_default:1;
+       unsigned int     qp_show_pools:1;
+       unsigned int     qp_show_qid:1;
+};
+
 static int lfs_setquota(int argc, char **argv);
 static int lfs_quota(int argc, char **argv);
 static int lfs_project(int argc, char **argv);
@@ -446,15 +456,16 @@ command_t cmdlist[] = {
         "Usage: getname [--help|-h] [--instance|-i] [--fsname|-n] [path ...]"},
 #ifdef HAVE_SYS_QUOTA_H
        {"setquota", lfs_setquota, 0, "Set filesystem quotas.\n"
-        "usage: setquota [-t] {-u|-U|-g|-G|-p|-P ID} {-b|-B|-i|-I LIMIT} [--pool POOL] FILESYSTEM\n"
-        "       setquota {-u|-g|-p ID} {--default|--delete} FILESYSTEM\n"},
+        "usage: setquota [-t] {-u|-U|-g|-G|-p|-P ID} {-b|-B|-i|-I LIMIT}\n"
+        "                [--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"
-        "             [{-u|-g|-p} UNAME|UID|GNAME|GID|PROJID]\n"
-        "             [--pool OST_POOL_NAME] FILESYSTEM\n"
-        "       quota -t {-u|-g|-p} [--pool OST_POOL_NAME] FILESYSTEM\n"
-        "       quota [-hqv] {-U|-G|-P} [--pool OST_POOL_NAME] FILESYSTEM\n"
-        "       quota -a {-u|-g|-p} [-s START_QID] [-e END_QID] FILESYSTEM"},
+        "             [{-u|-g|-p} UNAME|UID|GNAME|GID|PROJID]\n"
+        "             [--pool OST_POOL_NAME] [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"},
        {"project", lfs_project, 0,
         "Change or list project attribute for specified file or directory.\n"
         "usage: project [-d|-r] <file|directory...>\n"
@@ -8908,20 +8919,34 @@ static void diff2str(time_t seconds, char *buf, time_t now)
 }
 
 static void print_quota_title(char *name, struct if_quotactl *qctl,
-                             bool human_readable, bool show_default)
+                             struct quota_param *param)
 {
-       if (show_default) {
+       if (param->qp_quiet ||
+           qctl->qc_cmd == LUSTRE_Q_GETINFO ||
+           qctl->qc_cmd == LUSTRE_Q_GETINFOPOOL ||
+           qctl->qc_cmd == Q_GETOINFO)
+               return;
+
+       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("%15s %8s%8s%8s %8s%8s%8s\n",
+               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("%15s%8s %7s%8s%8s%8s %7s%8s%8s\n",
-                      "Filesystem", human_readable ? "used" : "kbytes",
-                      "quota", "limit", "grace",
+               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");
        }
 }
@@ -8965,7 +8990,7 @@ static void kbytes2str(__u64 num, char *buf, int buflen, bool h)
 static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                        int rc, bool h, bool show_default, bool show_qid)
 {
-       char *name;
+       char *name, *tmp;
        time_t now;
 
        time(&now);
@@ -9003,25 +9028,25 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                                iover = 3;
                }
 
+               tmp = strstr(mnt, "_UUID");
+               if (tmp)
+                       *tmp = '\0';
+
+               printf("%16s", mnt); /* Filesystem */
                if (show_qid) {
                        if (qctl->qc_type == USRQUOTA) {
                                if (uid2name(&name, qctl->qc_id))
-                                       printf("%10u", qctl->qc_id);
+                                       printf(" %9u", qctl->qc_id);
                                else
-                                       printf("%10s", name);
+                                       printf(" %9s", name);
                        } else if (qctl->qc_type == GRPQUOTA) {
                                if (gid2name(&name, qctl->qc_id))
-                                       printf("%10u", qctl->qc_id);
+                                       printf(" %9u", qctl->qc_id);
                                else
-                                       printf("%10s", name);
+                                       printf(" %9s", name);
                        } else {
-                               printf("%10u", qctl->qc_id);
+                               printf(" %9u", qctl->qc_id);
                        }
-               } else {
-                       if (strlen(mnt) > 15)
-                               printf("%s\n%15s", mnt, "");
-                       else
-                               printf("%15s", mnt);
                }
 
                if (show_default)
@@ -9050,7 +9075,7 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                        "%s" : "[%s]", strbuf);
 
                if (show_default)
-                       printf(" %6s %7s %7s", numbuf[1], numbuf[2], timebuf);
+                       printf(" %7s %7s %7s", numbuf[1], numbuf[2], timebuf);
                else
                        printf(" %7s%c %6s %7s %7s",
                               numbuf[0], bover ? '*' : ' ', numbuf[1],
@@ -9077,7 +9102,7 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type,
                        "%ju" : "[%ju]", (uintmax_t)dqb->dqb_ihardlimit);
 
                if (show_default)
-                       printf(" %6s %7s %7s", numbuf[1], numbuf[2], timebuf);
+                       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],
@@ -9229,8 +9254,7 @@ out:
 }
 
 static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl,
-                          int verbose, int quiet, bool human_readable,
-                          bool show_default, bool show_qid, int rc)
+                          struct quota_param *param, int rc)
 {
        int rc1 = 0, rc2 = 0;
        char *obd_type = (char *)qctl->obd_type;
@@ -9238,7 +9262,7 @@ static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl,
        __u64 total_ialloc = 0, total_balloc = 0;
        int inacc;
 
-       if (!show_default && qctl->qc_id == 0) {
+       if (!param->qp_show_default && qctl->qc_id == 0) {
                qctl->qc_dqblk.dqb_bhardlimit = 0;
                qctl->qc_dqblk.dqb_bsoftlimit = 0;
                qctl->qc_dqblk.dqb_ihardlimit = 0;
@@ -9256,12 +9280,6 @@ static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl,
            LQUOTA_FLAG(qctl->qc_dqblk.dqb_itime) & LQUOTA_FLAG_DEFAULT)
                qctl->qc_dqblk.dqb_itime &= LQUOTA_GRACE_MASK;
 
-       if (!show_qid && (qctl->qc_cmd == LUSTRE_Q_GETQUOTA ||
-            qctl->qc_cmd == LUSTRE_Q_GETQUOTAPOOL ||
-            qctl->qc_cmd == LUSTRE_Q_GETDEFAULT_POOL ||
-            qctl->qc_cmd == LUSTRE_Q_GETDEFAULT) && !quiet)
-               print_quota_title(name, qctl, human_readable, show_default);
-
        if (rc && *obd_type)
                fprintf(stderr, "%s %s ", obd_type, obd_uuid);
 
@@ -9273,25 +9291,26 @@ 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, human_readable, show_default,
-                   show_qid);
+       print_quota(mnt, qctl, QC_GENERAL, rc, param->qp_human_readable,
+                   param->qp_show_default, param->qp_show_qid);
 
-       if (!show_qid && !show_default && verbose &&
-           qctl->qc_valid == QC_GENERAL && qctl->qc_cmd != LUSTRE_Q_GETINFO &&
+       if (!param->qp_show_qid && !param->qp_show_default &&
+           param->qp_verbose && qctl->qc_valid == QC_GENERAL &&
+           qctl->qc_cmd != LUSTRE_Q_GETINFO &&
            qctl->qc_cmd != LUSTRE_Q_GETINFOPOOL) {
                char strbuf[STRBUF_LEN];
 
-               rc1 = print_obd_quota(mnt, qctl, 1, human_readable,
+               rc1 = print_obd_quota(mnt, qctl, 1, param->qp_human_readable,
                                      &total_ialloc);
-               rc2 = print_obd_quota(mnt, qctl, 0, human_readable,
+               rc2 = print_obd_quota(mnt, qctl, 0, param->qp_human_readable,
                                      &total_balloc);
                kbytes2str(total_balloc, strbuf, sizeof(strbuf),
-                          human_readable);
+                          param->qp_human_readable);
                printf("Total allocated inode limit: %ju, total allocated block limit: %s\n",
                       (uintmax_t)total_ialloc, strbuf);
        }
 
-       if (!show_qid && (rc || rc1 || rc2 || inacc))
+       if (!param->qp_show_qid && (rc || rc1 || rc2 || inacc))
                printf("%d Some errors happened when getting quota info. Some devices may be not working or deactivated. The data in \"[]\" is inaccurate.\n", inacc);
 
        if (rc)
@@ -9306,8 +9325,8 @@ static int print_one_quota(char *mnt, char *name, struct if_quotactl *qctl,
        return 0;
 }
 
-static int iter_all_quota(char *mnt, struct if_quotactl *qctl, int quiet,
-                         bool human_readable)
+static int iter_all_quota(char *mnt, struct if_quotactl *qctl,
+                         struct quota_param *param)
 {
        struct if_quotactl qctl_tmp, *qctl_iter;
        void *buffer = NULL;
@@ -9338,12 +9357,6 @@ static int iter_all_quota(char *mnt, struct if_quotactl *qctl, int quiet,
        if (rc)
                goto out;
 
-       printf("Filesystem %s, Disk %s quotas\n", mnt,
-              qtype_name(qctl->qc_type));
-       printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n", "quota_id",
-              human_readable ? "used" : "kbytes", "quota", "limit", "grace",
-              "files", "quota", "limit", "grace");
-
        cur = 0;
        while (cur < buflen) {
                if ((buflen - cur) < sizeof(struct if_quotactl)) {
@@ -9359,8 +9372,7 @@ static int iter_all_quota(char *mnt, struct if_quotactl *qctl, int quiet,
                if ((qctl_iter->qc_dqblk.dqb_valid & QIF_USAGE) != QIF_USAGE)
                        qctl_iter->qc_dqblk.dqb_valid |= QIF_USAGE;
 
-               print_one_quota(mnt, NULL, qctl_iter, 0, quiet,
-                               human_readable, false, true, 0);
+               print_one_quota(mnt, NULL, qctl_iter, param, 0);
        }
 
 out:
@@ -9373,10 +9385,10 @@ out:
        return rc;
 }
 
-static int get_print_quota(char *mnt, char *name, struct if_quotactl *qctl,
-                          int verbose, int quiet, bool human_readable,
-                          bool show_default)
+static int get_print_quota(char *mnt, struct if_quotactl *qctl,
+                          struct quota_param *param)
 {
+       char *name = NULL;
        int rc;
 
        rc = llapi_quotactl(mnt, qctl);
@@ -9400,8 +9412,7 @@ static int get_print_quota(char *mnt, char *name, struct if_quotactl *qctl,
                return rc;
        }
 
-       return print_one_quota(mnt, name, qctl, verbose, quiet, human_readable,
-                              show_default, false, rc);
+       return print_one_quota(mnt, name, qctl, param, rc);
 }
 
 static int lfs_project(int argc, char **argv)
@@ -9564,20 +9575,65 @@ static int lfs_project(int argc, char **argv)
        return ret;
 }
 
+static int do_quota_op(char *mnt, struct if_quotactl *qctl,
+                       struct quota_param *param)
+{
+       struct if_quotactl *qctl_tmp;
+       char **poollist = NULL;
+       char *buf = NULL;
+       int poolcount, i, rc = 0;
+
+       /* avoid modifying the original qctl */
+       qctl_tmp = malloc(sizeof(*qctl_tmp) + LOV_MAXPOOLNAME + 1);
+       memcpy(qctl_tmp, qctl, sizeof(*qctl_tmp) + LOV_MAXPOOLNAME + 1);
+
+       if (qctl_tmp->qc_cmd == LUSTRE_Q_ITERQUOTA) {
+               rc = iter_all_quota(mnt, qctl_tmp, param);
+               goto out;
+       }
+
+       if (param->qp_show_pools) {
+               char *p;
+
+               rc = llapi_get_poolbuf(mnt, &buf, &poollist, &poolcount);
+               if (rc)
+                       goto out;
+
+               for (i = 0; i < poolcount; i++) {
+                       p = memchr(poollist[i], '.', MAXNAMLEN);
+                       if (!p) {
+                               fprintf(stderr, "bad string format %.*s\n",
+                                       MAXNAMLEN, poollist[i]);
+                               rc = -EINVAL;
+                               goto out;
+                       }
+                       p++;
+                       printf("Quotas for pool: %s\n", p);
+                       snprintf(qctl_tmp->qc_poolname, LOV_MAXPOOLNAME + 1,
+                                "%s", p);
+                       rc = get_print_quota(mnt, qctl_tmp, param);
+                       if (rc)
+                               goto out;
+               }
+       }
+       rc = get_print_quota(mnt, qctl_tmp, param);
+       goto out;
+out:
+       free(qctl_tmp);
+       free(buf);
+       return rc;
+}
+
 static int lfs_quota(int argc, char **argv)
 {
-       int c;
-       char *mnt, *name = NULL;
+       struct quota_param param = { .qp_valid = QC_GENERAL };
        struct if_quotactl *qctl;
-       char *obd_uuid, *endp;
-       int rc = 0, rc1 = 0, verbose = 0, quiet = 0;
-       __u32 valid = QC_GENERAL;
-       long idx = 0;
+       char *obd_uuid, *endp, *name = NULL;
        __u32 start_qid = 0, end_qid = 0;
-       bool human_readable = false;
-       bool show_default = false;
-       int qtype;
-       bool show_pools = false;
+       int c, qtype, rc = 0;
+       long idx = 0;
+       bool all = false;
+
        struct option long_opts[] = {
        { .val = 'a',   .name = "all",          .has_arg = required_argument },
        { .val = 'e',   .name = "end-qid",      .has_arg = required_argument },
@@ -9603,9 +9659,6 @@ static int lfs_quota(int argc, char **argv)
        { .val = 'U',   .name = "default-usr",  .has_arg = required_argument },
        { .val = 'v',   .name = "verbose",      .has_arg = no_argument },
        { .name = NULL } };
-       char **poollist = NULL;
-       char *buf = NULL;
-       int poolcount, i;
 
        qctl = calloc(1, sizeof(*qctl) + LOV_MAXPOOLNAME + 1);
        if (!qctl)
@@ -9619,12 +9672,13 @@ static int lfs_quota(int argc, char **argv)
                long_opts, NULL)) != -1) {
                switch (c) {
                case 'a':
+                       param.qp_show_qid = 1;
                        qctl->qc_cmd = LUSTRE_Q_ITERQUOTA;
                        break;
                case 'e':
                        if (optarg == NULL || *optarg == '\0') {
                                fprintf(stderr,
-                                       "%s quota: invalid start quota ID\n",
+                                       "%s quota: invalid end quota ID\n",
                                progname);
                                rc = CMD_HELP;
                                goto out;
@@ -9632,13 +9686,13 @@ static int lfs_quota(int argc, char **argv)
                        end_qid = strtoul(optarg, NULL, 0);
                        break;
                case 'G':
-                       show_default = true;
+                       param.qp_show_default = 1;
                        /* fallthrough */
                case 'g':
                        qtype = GRPQUOTA;
                        goto quota_type;
                case 'h':
-                       human_readable = true;
+                       param.qp_human_readable = 1;
                        break;
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 22, 53, 0)
                case 'i':
@@ -9657,7 +9711,7 @@ static int lfs_quota(int argc, char **argv)
                                rc = CMD_HELP;
                                goto out;
                        }
-                       valid = qctl->qc_valid = QC_MDTIDX;
+                       param.qp_valid = qctl->qc_valid = QC_MDTIDX;
                        qctl->qc_idx = idx;
                        break;
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 22, 53, 0)
@@ -9678,17 +9732,17 @@ static int lfs_quota(int argc, char **argv)
                                        rc = CMD_HELP;
                                        goto out;
                                }
-                               valid = qctl->qc_valid = QC_OSTIDX;
+                               param.qp_valid = qctl->qc_valid = QC_OSTIDX;
                                qctl->qc_idx = idx;
                                break;
                        }
 
                        /* need to also handle a UUID for compatibility */
-                       valid = qctl->qc_valid = QC_UUID;
+                       param.qp_valid = qctl->qc_valid = QC_UUID;
                        snprintf(obd_uuid, sizeof(*obd_uuid), "%s", optarg);
                        break;
                case 'P':
-                       show_default = true;
+                       param.qp_show_default = 1;
                        /* fallthrough */
                case 'p':
                        qtype = PRJQUOTA;
@@ -9712,11 +9766,11 @@ static int lfs_quota(int argc, char **argv)
                        }
 
                        /* optarg is NULL */
-                       show_pools = true;
+                       param.qp_show_pools = 1;
                        qctl->qc_cmd = LUSTRE_Q_GETQUOTAPOOL;
                        break;
                case 'q':
-                       quiet = 1;
+                       param.qp_quiet = 1;
                        break;
                case 's':
                        if (optarg == NULL || *optarg == '\0') {
@@ -9732,11 +9786,15 @@ static int lfs_quota(int argc, char **argv)
                        qctl->qc_cmd = LUSTRE_Q_GETINFO;
                        break;
                case 'U':
-                       show_default = true;
+                       param.qp_show_default = 1;
                        /* fallthrough */
                case 'u':
                        qtype = USRQUOTA;
 quota_type:
+                       /*
+                        * since ID is not required for when -a or -t is used
+                        * it is only set after all options have been processed
+                        */
                        if (qctl->qc_type != ALLQUOTA) {
                                fprintf(stderr,
                                        "%s quota: only one of -u, -g, or -p may be specified\n",
@@ -9747,7 +9805,7 @@ quota_type:
                        qctl->qc_type = qtype;
                        break;
                case 'v':
-                       verbose = 1;
+                       param.qp_verbose = 1;
                        break;
                default:
                        fprintf(stderr, "%s quota: unrecognized option '%s'\n",
@@ -9757,49 +9815,36 @@ quota_type:
                }
        }
 
-       /* current uid/gid info for "lfs quota /path/to/lustre/mount" */
-       if ((qctl->qc_cmd == LUSTRE_Q_GETQUOTA ||
-            qctl->qc_cmd == LUSTRE_Q_GETQUOTAPOOL) &&
-            qctl->qc_type == ALLQUOTA &&
-            optind == argc - 1 && !show_default) {
-               qctl->qc_idx = idx;
-
-               for (qtype = USRQUOTA; qtype <= GRPQUOTA; qtype++) {
-                       qctl->qc_type = qtype;
-                       qctl->qc_valid = valid;
-                       if (qtype == USRQUOTA) {
-                               qctl->qc_id = geteuid();
-                               rc = uid2name(&name, qctl->qc_id);
-                       } else {
-                               qctl->qc_id = getegid();
-                               rc = gid2name(&name, qctl->qc_id);
-                               memset(&qctl->qc_dqblk, 0,
-                                      sizeof(qctl->qc_dqblk));
-                       }
-                       if (rc)
-                               name = "<unknown>";
-                       mnt = argv[optind];
-                       rc1 = get_print_quota(mnt, name, qctl, verbose, quiet,
-                                             human_readable, show_default);
-                       if (rc1 && !rc)
-                               rc = rc1;
+       if (qctl->qc_cmd == LUSTRE_Q_ITERQUOTA) {
+               if (qctl->qc_type == ALLQUOTA) {
+                       fprintf(stderr, "%s quota: no quota type to iterate\n",
+                               progname);
+                       rc = CMD_HELP;
+                       return rc;
                }
-               goto out;
-       /* lfs quota -u username /path/to/lustre/mount */
-       } else if (qctl->qc_cmd == LUSTRE_Q_GETQUOTA ||
-                  qctl->qc_cmd == LUSTRE_Q_GETQUOTAPOOL) {
-               /* options should be followed by u/g-name and mntpoint */
-               if ((!show_default && optind + 2 != argc) ||
-                   (show_default && optind + 1 != argc) ||
-                   qctl->qc_type == ALLQUOTA) {
+
+               if (end_qid != 0 && start_qid > end_qid) {
                        fprintf(stderr,
-                               "%s quota: name and mount point must be specified\n",
+                               "%s quota: end qid is smaller than start qid\n",
                                progname);
                        rc = CMD_HELP;
-                       goto out;
+                       return rc;
                }
 
-               if (!show_default) {
+               qctl->qc_allquota_qid_start = start_qid;
+               qctl->qc_allquota_qid_end = end_qid;
+       } else if (qctl->qc_type != ALLQUOTA &&
+                  (qctl->qc_cmd == LUSTRE_Q_GETQUOTA ||
+                   qctl->qc_cmd == LUSTRE_Q_GETQUOTAPOOL)) {
+               if (!param.qp_show_default) {
+                       if (optind + 1 > argc) {
+                               fprintf(stderr,
+                                       "%s quota: u/g-name is required\n",
+                                       progname);
+                               rc = CMD_HELP;
+                               return rc;
+                       }
+
                        name = argv[optind++];
                        switch (qctl->qc_type) {
                        case USRQUOTA:
@@ -9831,74 +9876,54 @@ quota_type:
                                goto out;
                        }
                }
-       } else if (qctl->qc_cmd == LUSTRE_Q_ITERQUOTA) {
-               if (optind + 1 != argc) {
-                       fprintf(stderr,
-                               "%s quota: mount point must be specified\n",
-                               progname);
-                       rc = CMD_HELP;
-                       goto out;
-               }
+       } else if (qctl->qc_type == ALLQUOTA) {
+               all = true;
+               qctl->qc_type = USRQUOTA;
+       }
 
-               if (qctl->qc_type == ALLQUOTA) {
-                       fprintf(stderr, "%s quota: no quota type to iterate\n",
-                               progname);
-                       rc = CMD_HELP;
-                       goto out;
+       do {
+               if (all) {
+                       qctl->qc_valid = param.qp_valid;
+                       if (qctl->qc_type == USRQUOTA) {
+                               qctl->qc_id = geteuid();
+                               rc = uid2name(&name, qctl->qc_id);
+                       } else {
+                               qctl->qc_id = getegid();
+                               rc = gid2name(&name, qctl->qc_id);
+                               memset(&qctl->qc_dqblk, 0,
+                                      sizeof(qctl->qc_dqblk));
+                       }
+                       if (rc)
+                               name = "<unknown>";
                }
 
-               if (end_qid != 0 && start_qid > end_qid) {
-                       fprintf(stderr,
-                               "%s quota: end qid is smaller than start qid\n",
-                               progname);
-                       rc = CMD_HELP;
-                       goto out;
-               }
+               print_quota_title(name, qctl, &param);
 
-               qctl->qc_allquota_qid_start = start_qid;
-               qctl->qc_allquota_qid_end = end_qid;
-               rc = iter_all_quota(argv[optind], qctl, quiet, human_readable);
-               goto out;
-       } else if (optind + 1 != argc || qctl->qc_type == ALLQUOTA) {
-               fprintf(stderr, "%s quota: missing quota info argument(s)\n",
-                       progname);
-               rc = CMD_HELP;
-               goto out;
-       }
+               if (optind == argc) {
+                       char mnt[PATH_MAX];
+                       int i = 0;
 
-       mnt = argv[optind];
-       if (show_pools) {
-               char *p;
+                       while (!llapi_search_mounts(NULL, i++, mnt, NULL)) {
+                               if (mnt[0] == '\0')
+                                       continue;
 
-               i = 0;
-               rc = llapi_get_poolbuf(mnt, &buf, &poollist, &poolcount);
-               if (rc)
-                       goto out;
+                               rc = do_quota_op(mnt, qctl, &param);
+                               if (rc)
+                                       break;
 
-               for (i = 0; i < poolcount; i++) {
-                       p = memchr(poollist[i], '.', MAXNAMLEN);
-                       if (!p) {
-                               fprintf(stderr, "bad string format %.*s\n",
-                                       MAXNAMLEN, poollist[i]);
-                               rc = -EINVAL;
-                               goto out;
+                               mnt[0] = '\0'; /* avoid matching in next loop */
                        }
-                       p++;
-                       printf("Quotas for pool: %s\n", p);
-                       snprintf(qctl->qc_poolname, LOV_MAXPOOLNAME + 1, "%s",
-                               p);
-                       rc = get_print_quota(mnt, name, qctl, verbose, quiet,
-                                            human_readable, show_default);
-                       if (rc)
-                               break;
-               }
-               goto out;
-       }
+               } else {
+                       int i = optind;
 
-       rc = get_print_quota(mnt, name, qctl, verbose, quiet,
-                            human_readable, show_default);
+                       while (i < argc) {
+                               rc = do_quota_op(argv[i++], qctl, &param);
+                               if (rc)
+                                       break;
+                       }
+               }
+       } while (all && ++qctl->qc_type <= GRPQUOTA);
 out:
-       free(buf);
        free(qctl);
        return rc;
 }