commit 52e81d72272a00c692cb6fdaa49df8b59a539c50
Author: Zorro Lang <zlang@redhat.com>
Date: Thu Aug 4 11:29:49 2016 +1000
xfs_quota: fall back silently if XFS_GETNEXTQUOTA fails
After XFS_GETNEXTQUOTA feature has been merged into linux kernel and
xfsprogs, xfs_quota use Q_XGETNEXTQUOTA for report and dump, and
fall back to old XFS_GETQUOTA ioctl if XFS_GETNEXTQUOTA fails.
But when XFS_GETNEXTQUOTA fails, xfs_quota print a warning as
"XFS_GETQUOTA: Invalid argument". That's due to kernel can't
recognize XFS_GETNEXTQUOTA ioctl and return EINVAL. At this time,
the warning is helpless, xfs_quota just need to fall back.
Signed-off-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
commit f61be1b4401e7653b2bdcd3aac2130a4da10faa5
Author: Eric Sandeen <sandeen@redhat.com>
Date: Fri Jun 3 11:04:15 2016 +1000
xfs_quota: only round up timer reporting > 1 day
I was too hasty with:
d1fe6ff xfs_quota: remove extra 30 seconds from time limit reporting
The point of that extra 30s, turns out, was to allow the user
to set a limit, query it, and get back what they just set, if
it is set to more than a day.
Without it, if we set a grace period to i.e. 3 days, and query it
1 second later, the rounding in the time_to_string function returns
"2 days" not "3 days" as it did before, because we are at
2 days 23:59:59 and it essentially applies a floor() for
brevity. I guess this was confusing.
(I've run into this same conundrum on my stove digital timer;
if you set it to 10m, it blinks "10" at you twice so that you
know what you set, then quickly flips to 9 as it counts down).
In some cases, however (and this is the case that prompted the
prior patch), we display a full "XYZ days hh:mm:ss" - we do this
if the verbose flag is set, or if the timer is less than one day.
In these cases, we should not add the 30s, because we are showing
full time resolution to the user.
Reported-by: Zorro Lang <zlang@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
commit a8b6f5274724ea2413d40f452f58874a36b78499
Author: Eric Sandeen <sandeen@sandeen.net>
Date: Mon May 30 12:21:31 2016 +1000
xfs_quota: check report_mount return value
The new call to report_mount doesn't check the return value
like every other caller does...
Returning 1 means it printed something; if the terse flag
is used and there is no usage, nothing gets printed.
If we set the NO_HEADER_FLAG anyway, then we won't see
the header for subsequent entries as we expect.
For example, project ID 0 has no usage in this case:
# xfs_quota -x -c "report -a" /mnt/test
Project quota on /mnt/test (/dev/sdb1)
Blocks
Project ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
#0 0 0 0 00 [--------]
project 2048 4 4 00 [--none--]
So using the terse flag results in no header when it prints
projects with usage:
# xfs_quota -x -c "report -t -a" /mnt/test
project 2048 4 4 00 [--none--]
With this fix it prints the header as expected:
# xfs_quota -x -c "report -t -a" /mnt/test
Project quota on /mnt/test (/dev/sdb1)
Blocks
Project ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
project 2048 4 4 00 [--none--]
Addresses-Coverity-Id: 1361552
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
commit 3d607a1134c55849952412d64e7658fb00312705
Author: Zorro Lang <zlang@redhat.com>
Date: Tue May 10 17:16:06 2016 +1000
xfs_quota: print quota id number if the name can't be found
When use GETNEXTQUOTA ioctl to report project quota, it always
report an unexpected quota:
(null) 0 0 0 00 [--------]
The ID 0 store the default quota, even if no one set default quota,
it still have quota accounting, but not enforced. So GETNEXTQUOTA
can find and report this undefined quota.
From this problem, I thought if others' quota name miss, (null) will
be printed too. e.g.
# xfs_quota -xc "limit -u bsoft=300m bhard=400m test" $mnt
# xfs_quota -xc "report -u" $mnt
User ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 0 0 00 [--------]
test 0 307200 409600 00 [--------]
# userdel -r test
# xfs_quota -xc "report -u" $mnt
User ID Used Soft Hard Warn/Grace
---------- --------------------------------------------------
root 0 0 0 00 [--------]
(null) 0 307200 409600 00 [--------]
So this problem same with above id 0's problem. To deal with this,
this patch will print id number if the name can't be found.
However, if we use the old GETQUOTA ioctl, it won't print project id
0 quota information if it's not defined. That's different with
GETNEXTQUOTA. For keep consistent, this patch also print project id
0 when use old GETQUOTA.
Signed-off-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
commit cef37d5a0ef68351ea97518249b0c91746e700e3
Author: Zorro Lang <zlang@redhat.com>
Date: Tue May 10 17:16:06 2016 +1000
xfs_quota: fully support users and groups beginning with digits
A normal user or group name allow beginning with digits, but xfs_quota
can't create a limit for that user or group. The reason is 'strtoul'
function only translate digits at the beginning, it will ignore
letters after digits.
There's a commit fd537fc50eeade63bbd2a66105f39d04a011a7f5, it try to
fix "xfsprogs: xfs_quota allow user or group names beginning with
digits". But it doesn't effect 'limit' command, so a command likes:
xfs_quota 'limit .... 12345678-user' xxxx
will try to create limit for username="12345678", not "12345678-user".
This patch will fix this problem, and a test case xfs/138 in xfstests
is used to reproduce this bug.
Signed-off-by: Zorro Lang <zlang@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
commit 43633a39ef424e9e867b34a5dd3ea6c44508a45c
Author: Eric Sandeen <sandeen@sandeen.net>
Date: Wed Feb 17 17:03:02 2016 +1100
xfs: wire up Q_XGETNEXTQUOTA / get_nextdqblk
Source kernel commit 296c24e26ee3af2dbfecb482e6bc9560bd34c455
Add code to allow the Q_XGETNEXTQUOTA quotactl to quickly find
all active quotas by examining the quota inode, and skipping
over unallocated or uninitialized regions.
Userspace can then use this interface rather than i.e. a
getpwent() loop when asked to report all active quotas.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Index: xfsprogs-4.5.0/quota/report.c
===================================================================
--- xfsprogs-4.5.0.orig/quota/report.c
+++ xfsprogs-4.5.0/quota/report.c
@@ -90,8 +90,10 @@ dump_file(
else
cmd = XFS_GETQUOTA;
+ /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA */
if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
- if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
+ if (errno != ENOENT && errno != ENOSYS && errno != ESRCH &&
+ cmd == XFS_GETQUOTA)
perror("XFS_GETQUOTA");
return 0;
}
@@ -347,8 +349,10 @@ report_mount(
else
cmd = XFS_GETQUOTA;
+ /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA*/
if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
- if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
+ if (errno != ENOENT && errno != ENOSYS && errno != ESRCH &&
+ cmd == XFS_GETQUOTA)
perror("XFS_GETQUOTA");
return 0;
}
@@ -389,7 +393,11 @@ report_mount(
name = p->pr_name;
}
}
- fprintf(fp, "%-10s", name);
+ /* If no name is found, print the id #num instead of (null) */
+ if (name != NULL)
+ fprintf(fp, "%-10s", name);
+ else
+ fprintf(fp, "#%-9u", d.d_id);
}
if (form & XFS_BLOCK_QUOTA) {
@@ -571,6 +579,16 @@ report_project_mount(
id = oid + 1;
}
} else {
+ if (!getprprid(0)) {
+ /*
+ * Print default project quota, even if projid 0
+ * isn't defined
+ */
+ if (report_mount(fp, 0, NULL, NULL,
+ form, XFS_PROJ_QUOTA, mount, flags))
+ flags |= NO_HEADER_FLAG;
+ }
+
setprent();
while ((p = getprent()) != NULL) {
if (report_mount(fp, p->pr_prid, p->pr_name, NULL,
Index: xfsprogs-4.5.0/quota/util.c
===================================================================
--- xfsprogs-4.5.0.orig/quota/util.c
+++ xfsprogs-4.5.0/quota/util.c
@@ -43,6 +43,18 @@ time_to_string(
timer = MAX(origin - now, 0);
}
+ /*
+ * If we are in verbose mode, or if less than a day remains, we
+ * will show "X days hh:mm:ss" so the user knows the exact timer status.
+ *
+ * Otherwise, we round down to the nearest day - so we add 30s here
+ * such that setting and reporting a limit in rapid succession will
+ * show the limit which was just set, rather than immediately reporting
+ * one day less.
+ */
+ if ((timer > SECONDS_IN_A_DAY) && !(flags & VERBOSE_FLAG))
+ timer += 30; /* seconds */
+
days = timer / SECONDS_IN_A_DAY;
if (days)
timer %= SECONDS_IN_A_DAY;
Index: xfsprogs-4.5.0/man/man8/xfs_quota.8
===================================================================
--- xfsprogs-4.5.0.orig/man/man8/xfs_quota.8
+++ xfsprogs-4.5.0/man/man8/xfs_quota.8
@@ -357,7 +357,9 @@ option outputs the report to
.I file
instead of stdout. The
.B \-a
-option reports on all filesystems. The
+option reports on all filesystems. By default, outputs the name of
+the user/group/project. If no name is defined for a given ID, outputs
+the numeric ID instead. The
.B \-n
option outputs the numeric ID instead of the name. The
.B \-L
Index: xfsprogs-4.5.0/libxcmd/input.c
===================================================================
--- xfsprogs-4.5.0.orig/libxcmd/input.c
+++ xfsprogs-4.5.0/libxcmd/input.c
@@ -366,7 +366,7 @@ uid_from_string(
char *sp;
uid_long = strtoul(user, &sp, 10);
- if (sp != user) {
+ if (sp != user && *sp == '\0') {
if ((uid_long == ULONG_MAX && errno == ERANGE)
|| (uid_long > (uid_t)-1))
return -1;
@@ -387,7 +387,7 @@ gid_from_string(
char *sp;
gid_long = strtoul(group, &sp, 10);
- if (sp != group) {
+ if (sp != group && *sp == '\0') {
if ((gid_long == ULONG_MAX && errno == ERANGE)
|| (gid_long > (gid_t)-1))
return -1;
Index: xfsprogs-4.5.0/libxfs/xfs_quota_defs.h
===================================================================
--- xfsprogs-4.5.0.orig/libxfs/xfs_quota_defs.h
+++ xfsprogs-4.5.0/libxfs/xfs_quota_defs.h
@@ -37,7 +37,7 @@ typedef __uint16_t xfs_qwarncnt_t;
#define XFS_DQ_PROJ 0x0002 /* project quota */
#define XFS_DQ_GROUP 0x0004 /* a group quota */
#define XFS_DQ_DIRTY 0x0008 /* dquot is dirty */
-#define XFS_DQ_FREEING 0x0010 /* dquot is beeing torn down */
+#define XFS_DQ_FREEING 0x0010 /* dquot is being torn down */
#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
@@ -116,6 +116,7 @@ typedef __uint16_t xfs_qwarncnt_t;
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
+#define XFS_QMOPT_DQNEXT 0x0008000 /* return next dquot >= this ID */
/*
* flags to xfs_trans_mod_dquot to indicate which field needs to be