Blame SOURCES/xfsprogs-4.7.0-quota-fixes.patch

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