All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: sandeen@sandeen.net, darrick.wong@oracle.com
Cc: linux-xfs@vger.kernel.org
Subject: [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime
Date: Mon, 26 Oct 2020 16:36:34 -0700	[thread overview]
Message-ID: <160375539460.881414.16375144747744518990.stgit@magnolia> (raw)
In-Reply-To: <160375524618.881414.16347303401529121282.stgit@magnolia>

From: Darrick J. Wong <darrick.wong@oracle.com>

Enhance xfs_quota to detect and report grace period expirations past
2038.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xqm.h  |   20 ++++++++++++++++-
 quota/edit.c   |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 quota/quota.c  |    6 +++--
 quota/quota.h  |    7 ++++++
 quota/report.c |    6 +++--
 5 files changed, 91 insertions(+), 13 deletions(-)


diff --git a/include/xqm.h b/include/xqm.h
index 8ab19072656e..573441db9860 100644
--- a/include/xqm.h
+++ b/include/xqm.h
@@ -47,7 +47,10 @@ typedef struct fs_disk_quota {
 	__s32		d_btimer;	/* similar to above; for disk blocks */
 	__u16		d_iwarns;	/* # warnings issued wrt num inodes */
 	__u16		d_bwarns;	/* # warnings issued wrt disk blocks */
-	__s32		d_padding2;	/* padding2 - for future use */
+	__s8		d_itimer_hi;	/* upper 8 bits of timer values */
+	__s8		d_btimer_hi;
+	__s8		d_rtbtimer_hi;
+	__s8		d_padding2;	/* padding2 - for future use */
 	__u64		d_rtb_hardlimit;/* absolute limit on realtime blks */
 	__u64		d_rtb_softlimit;/* preferred limit on RT disk blks */
 	__u64		d_rtbcount;	/* # realtime blocks owned */
@@ -93,6 +96,21 @@ typedef struct fs_disk_quota {
 #define FS_DQ_RTBWARNS	(1<<11)
 #define FS_DQ_WARNS_MASK	(FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
 
+/*
+ * Accounting values.  These can only be set for filesystem with
+ * non-transactional quotas that require quotacheck(8) in userspace.
+ */
+#define FS_DQ_BCOUNT		(1<<12)
+#define FS_DQ_ICOUNT		(1<<13)
+#define FS_DQ_RTBCOUNT		(1<<14)
+#define FS_DQ_ACCT_MASK		(FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
+
+/*
+ * Quota expiration timestamps are 40-bit signed integers, with the upper 8
+ * bits encoded in the _hi fields.
+ */
+#define FS_DQ_BIGTIME		(1<<15)
+
 /*
  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
  */
diff --git a/quota/edit.c b/quota/edit.c
index b3cad024b1f1..1a3b2d9f959b 100644
--- a/quota/edit.c
+++ b/quota/edit.c
@@ -417,6 +417,53 @@ restore_f(
 	return 0;
 }
 
+time64_t
+decode_timer(
+	const struct fs_disk_quota *d,
+	__s32			timer_lo,
+	__s8			timer_hi)
+{
+	if (d->d_fieldmask & FS_DQ_BIGTIME)
+		return (uint32_t)timer_lo | (int64_t)timer_hi << 32;
+	return timer_lo;
+}
+
+static inline void
+encode_timer(
+	const struct fs_disk_quota *d,
+	__s32			*timer_lo,
+	__s8			*timer_hi,
+	time64_t		timer)
+{
+	*timer_lo = timer;
+	if (d->d_fieldmask & FS_DQ_BIGTIME)
+		*timer_hi = timer >> 32;
+	else
+		*timer_hi = 0;
+}
+
+static inline bool want_bigtime(time64_t timer)
+{
+	return timer > INT32_MAX || timer < INT32_MIN;
+}
+
+static void
+encode_timers(
+	struct fs_disk_quota	*d,
+	time64_t		btimer,
+	time64_t		itimer,
+	time64_t		rtbtimer)
+{
+	d->d_fieldmask &= ~FS_DQ_BIGTIME;
+	if (want_bigtime(btimer) || want_bigtime(itimer) ||
+	    want_bigtime(rtbtimer))
+		d->d_fieldmask |= FS_DQ_BIGTIME;
+
+	encode_timer(d, &d->d_btimer, &d->d_btimer_hi, btimer);
+	encode_timer(d, &d->d_itimer, &d->d_itimer_hi, itimer);
+	encode_timer(d, &d->d_rtbtimer, &d->d_rtbtimer_hi, rtbtimer);
+}
+
 static void
 set_timer(
 	uint32_t		id,
@@ -426,6 +473,7 @@ set_timer(
 	time64_t		value)
 {
 	struct fs_disk_quota	d;
+	time64_t		btimer, itimer, rtbtimer;
 
 	memset(&d, 0, sizeof(d));
 
@@ -446,23 +494,28 @@ set_timer(
 
 		time(&now);
 
+		btimer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
+		itimer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
+		rtbtimer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
+
 		/* Only set grace time if user is already past soft limit */
 		if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
-			d.d_btimer = now + value;
+			btimer = now + value;
 		if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
-			d.d_itimer = now + value;
+			itimer = now + value;
 		if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
-			d.d_rtbtimer = now + value;
+			rtbtimer = now + value;
 	} else {
-		d.d_btimer = value;
-		d.d_itimer = value;
-		d.d_rtbtimer = value;
+		btimer = value;
+		itimer = value;
+		rtbtimer = value;
 	}
 
 	d.d_version = FS_DQUOT_VERSION;
 	d.d_flags = type;
 	d.d_fieldmask = mask;
 	d.d_id = id;
+	encode_timers(&d, btimer, itimer, rtbtimer);
 
 	if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
 		exitcode = 1;
diff --git a/quota/quota.c b/quota/quota.c
index 8ba0995d9174..0747cedcb8c2 100644
--- a/quota/quota.c
+++ b/quota/quota.c
@@ -101,7 +101,7 @@ quota_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
-		timer = d.d_btimer;
+		timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -123,7 +123,7 @@ quota_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
-		timer = d.d_itimer;
+		timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -145,7 +145,7 @@ quota_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
-		timer = d.d_rtbtimer;
+		timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;
diff --git a/quota/quota.h b/quota/quota.h
index 11f62b208e6a..78b0d66d2a4f 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -3,6 +3,8 @@
  * Copyright (c) 2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
+#ifndef XFS_QUOTA_QUOTA_H_
+#define XFS_QUOTA_QUOTA_H_
 
 #include "xqm.h"
 #include "libfrog/paths.h"
@@ -73,3 +75,8 @@ extern char *uid_to_name(uint32_t __uid);
 extern char *gid_to_name(uint32_t __gid);
 extern char *prid_to_name(uint32_t __prid);
 extern bool isdigits_only(const char *);
+
+time64_t decode_timer(const struct fs_disk_quota *d, __s32 timer_lo,
+		__s8 timer_hi);
+
+#endif /* XFS_QUOTA_QUOTA_H_ */
diff --git a/quota/report.c b/quota/report.c
index 2d5024e95177..6ac5549097b7 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -398,7 +398,7 @@ report_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
-		timer = d.d_btimer;
+		timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -420,7 +420,7 @@ report_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
-		timer = d.d_itimer;
+		timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -442,7 +442,7 @@ report_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
-		timer = d.d_rtbtimer;
+		timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;


  parent reply	other threads:[~2020-10-26 23:38 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
2020-10-29  9:44   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 02/26] libxfs: refactor NSEC_PER_SEC Darrick J. Wong
2020-10-29  9:44   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK Darrick J. Wong
2020-10-29  9:45   ` Christoph Hellwig
2020-10-29  9:45     ` Christoph Hellwig
2020-10-29 17:25       ` Darrick J. Wong
2020-10-30  8:20         ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 04/26] libfrog: convert cvttime to return time64_t Darrick J. Wong
2020-10-29  9:45   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
2020-10-29  9:47   ` Christoph Hellwig
2020-10-29 17:32     ` Darrick J. Wong
2020-10-30  8:21       ` Christoph Hellwig
2020-11-16 20:45   ` Eric Sandeen
2020-10-26 23:34 ` [PATCH 06/26] xfs_db: refactor timestamp printing Darrick J. Wong
2020-10-29  9:47   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 07/26] xfs_db: refactor quota timer printing Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-11-23 20:14   ` Eric Sandeen
2020-11-24  0:25     ` Darrick J. Wong
2020-10-26 23:35 ` [PATCH 09/26] xfs: explicitly define inode timestamp range Darrick J. Wong
2020-10-26 23:35 ` [PATCH 10/26] xfs: refactor quota expiration timer modification Darrick J. Wong
2020-10-26 23:35 ` [PATCH 11/26] xfs: refactor default quota grace period setting code Darrick J. Wong
2020-10-26 23:35 ` [PATCH 12/26] xfs: refactor quota timestamp coding Darrick J. Wong
2020-10-26 23:35 ` [PATCH 13/26] xfs: move xfs_log_dinode_to_disk to the log recovery code Darrick J. Wong
2020-10-26 23:35 ` [PATCH 14/26] xfs: redefine xfs_timestamp_t Darrick J. Wong
2020-10-26 23:35 ` [PATCH 15/26] xfs: redefine xfs_ictimestamp_t Darrick J. Wong
2020-10-26 23:35 ` [PATCH 16/26] xfs: widen ondisk inode timestamps to deal with y2038+ Darrick J. Wong
2020-10-26 23:35 ` [PATCH 17/26] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
2020-10-26 23:36 ` [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry Darrick J. Wong
2020-10-29  9:49   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
2020-10-29  9:50   ` Christoph Hellwig
2020-10-29 17:45     ` Darrick J. Wong
2020-10-30  8:23       ` Christoph Hellwig
2020-11-16 21:16   ` Eric Sandeen
2020-11-16 22:41     ` Darrick J. Wong
2020-11-17 17:45   ` [PATCH v2 " Darrick J. Wong
2020-11-17 18:18     ` Eric Sandeen
2020-10-26 23:36 ` [PATCH 21/26] xfs_db: support printing time limits Darrick J. Wong
2020-10-29  9:50   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
2020-10-29  9:51   ` Christoph Hellwig
2020-11-16 21:15   ` [PATCH v2 " Darrick J. Wong
2020-10-26 23:36 ` Darrick J. Wong [this message]
2020-10-29  9:51   ` [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime Christoph Hellwig
2020-10-26 23:36 ` [PATCH 24/26] xfs_repair: support bigtime timestamp checking Darrick J. Wong
2020-10-29  9:52   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 25/26] mkfs: format bigtime filesystems Darrick J. Wong
2020-10-29  9:52   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 26/26] xfs: enable big timestamps Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=160375539460.881414.16375144747744518990.stgit@magnolia \
    --to=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@sandeen.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.