Linux-XFS Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot
@ 2020-06-30 15:41 Darrick J. Wong
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
                   ` (17 more replies)
  0 siblings, 18 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:41 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

Hi all,

This series replaces q_core (the ondisk quota structure) in the incore
dquot structure with a quota resource control structure containing the
count, reservation, limits, timers, and warnings.  Each dquot gets three
of these resource control structures (blocks, inodes, rt blocks).

Doing this enables us to remove a whole lot of noisy endian conversions
in the quota code, and enables us to refactor a bunch of open-coded
logic to pass around pointers to quota resource control structs.

Note that these cleanups are a prerequisite for the bigtime patchset, as
it depends on incore quota timers being time64_t to take advantage of
the 64-bit time functions in the kernel with fewer places to trip over
the ondisk format.

If you're going to start using this mess, you probably ought to just
pull from my git trees, which are linked below.

This is an extraordinary way to destroy everything.  Enjoy!
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=remove-quota-qcore

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=remove-quota-qcore
---
 fs/xfs/libxfs/xfs_quota_defs.h |    2 
 fs/xfs/scrub/quota.c           |   69 +++-----
 fs/xfs/xfs_dquot.c             |  283 +++++++++++++++++++---------------
 fs/xfs/xfs_dquot.h             |   54 +++++--
 fs/xfs/xfs_dquot_item.c        |    8 +
 fs/xfs/xfs_iomap.c             |    6 -
 fs/xfs/xfs_qm.c                |   92 +++++------
 fs/xfs/xfs_qm.h                |   42 ++---
 fs/xfs/xfs_qm_bhv.c            |   20 +-
 fs/xfs/xfs_qm_syscalls.c       |  231 +++++++++++++++-------------
 fs/xfs/xfs_quotaops.c          |   12 +
 fs/xfs/xfs_trace.h             |  160 ++++++++++++++++++-
 fs/xfs/xfs_trans_dquot.c       |  329 ++++++++++++++++++++--------------------
 13 files changed, 744 insertions(+), 564 deletions(-)


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
@ 2020-06-30 15:41 ` Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
                   ` (16 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:41 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
can't lock the dquot buf to flush the dquot.  This prevents the AIL from
blocking on the dquot, but it also forgets to clear the FREEING flag on
its way out.  A subsequent purge attempt will see the FREEING flag is
set and bail out, which leads to dqpurge_all failing to purge all the
dquots.  This causes unmounts and quotaoff operations to hang.

Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_qm.c |    1 +
 1 file changed, 1 insertion(+)


diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index d6cd83317344..938023dd8ce5 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -148,6 +148,7 @@ xfs_qm_dqpurge(
 			error = xfs_bwrite(bp);
 			xfs_buf_relse(bp);
 		} else if (error == -EAGAIN) {
+			dqp->dq_flags &= ~XFS_DQ_FREEING;
 			goto out_unlock;
 		}
 		xfs_dqflock(dqp);


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 02/18] xfs: fix inode quota reservation checks
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
                   ` (15 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

xfs_trans_dqresv is the function that we use to make reservations
against resource quotas.  Each resource contains two counters: the
q_core counter, which tracks resources allocated on disk; and the dquot
reservation counter, which tracks how much of that resource has either
been allocated or reserved by threads that are working on metadata
updates.

For disk blocks, we compare the proposed reservation counter against the
hard and soft limits to decide if we're going to fail the operation.
However, for inodes we inexplicably compare against the q_core counter,
not the incore reservation count.

Since the q_core counter is always lower than the reservation count and
we unlock the dquot between reservation and transaction commit, this
means that multiple threads can reserve the last inode count before we
hit the hard limit, and when they commit, we'll be well over the hard
limit.

Fix this by checking against the incore inode reservation counter, since
we would appear to maintain that correctly (and that's what we report in
GETQUOTA).

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_trans_dquot.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index c0f73b82c055..ed0ce8b301b4 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -647,7 +647,7 @@ xfs_trans_dqresv(
 			}
 		}
 		if (ninos > 0) {
-			total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
+			total_count = dqp->q_res_icount + ninos;
 			timer = be32_to_cpu(dqp->q_core.d_itimer);
 			warns = be16_to_cpu(dqp->q_core.d_iwarns);
 			warnlimit = defq->iwarnlimit;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
  2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
                     ` (3 more replies)
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
                   ` (14 subsequent siblings)
  17 siblings, 4 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

While loading dquot records off disk, make sure that the quota type
flags are the same between the incore dquot and the ondisk dquot.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index d5b7f03e93c8..46c8ca83c04d 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -524,13 +524,27 @@ xfs_dquot_alloc(
 }
 
 /* Copy the in-core quota fields in from the on-disk buffer. */
-STATIC void
+STATIC int
 xfs_dquot_from_disk(
 	struct xfs_dquot	*dqp,
 	struct xfs_buf		*bp)
 {
 	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
 
+	/*
+	 * The only field the verifier didn't check was the quota type flag, so
+	 * do that here.
+	 */
+	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
+	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
+	    dqp->q_core.d_id != ddqp->d_id) {
+		xfs_alert(bp->b_mount,
+			  "Metadata corruption detected at %pS, quota %u",
+			  __this_address, be32_to_cpu(dqp->q_core.d_id));
+		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
+		return -EFSCORRUPTED;
+	}
+
 	/* copy everything from disk dquot to the incore dquot */
 	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
 
@@ -544,6 +558,7 @@ xfs_dquot_from_disk(
 
 	/* initialize the dquot speculative prealloc thresholds */
 	xfs_dquot_set_prealloc_limits(dqp);
+	return 0;
 }
 
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
@@ -617,9 +632,11 @@ xfs_qm_dqread(
 	 * further.
 	 */
 	ASSERT(xfs_buf_islocked(bp));
-	xfs_dquot_from_disk(dqp, bp);
-
+	error = xfs_dquot_from_disk(dqp, bp);
 	xfs_buf_relse(bp);
+	if (error)
+		goto err;
+
 	*dqpp = dqp;
 	return error;
 


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (2 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
                     ` (3 more replies)
  2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
                   ` (13 subsequent siblings)
  17 siblings, 4 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Use the incore dq_flags to figure out the dquot type.  This is the first
step towards removing xfs_disk_dquot from the incore dquot.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
 fs/xfs/scrub/quota.c           |    4 ----
 fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
 fs/xfs/xfs_dquot.h             |    2 ++
 fs/xfs/xfs_dquot_item.c        |    6 ++++--
 fs/xfs/xfs_qm.c                |    4 ++--
 fs/xfs/xfs_qm.h                |    2 +-
 fs/xfs/xfs_qm_syscalls.c       |    9 +++------
 8 files changed, 45 insertions(+), 17 deletions(-)


diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
index 56d9dd787e7b..459023b0a304 100644
--- a/fs/xfs/libxfs/xfs_quota_defs.h
+++ b/fs/xfs/libxfs/xfs_quota_defs.h
@@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
 
 #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
 
+#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
+
 #define XFS_DQ_FLAGS \
 	{ XFS_DQ_USER,		"USER" }, \
 	{ XFS_DQ_PROJ,		"PROJ" }, \
diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 905a34558361..710659d3fa28 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -108,10 +108,6 @@ xchk_quota_item(
 
 	sqi->last_id = id;
 
-	/* Did we get the dquot type we wanted? */
-	if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
-		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
-
 	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 46c8ca83c04d..59d1bce34a98 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -561,6 +561,16 @@ xfs_dquot_from_disk(
 	return 0;
 }
 
+/* Copy the in-core quota fields into the on-disk buffer. */
+void
+xfs_dquot_to_disk(
+	struct xfs_disk_dquot	*ddqp,
+	struct xfs_dquot	*dqp)
+{
+	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
+	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
+}
+
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
 static int
 xfs_qm_dqread_alloc(
@@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done(
 	xfs_dqfunlock(dqp);
 }
 
+/* Check incore dquot for errors before we flush. */
+static xfs_failaddr_t
+xfs_qm_dqflush_check(
+	struct xfs_dquot	*dqp)
+{
+	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
+		return __this_address;
+
+	return NULL;
+}
+
 /*
  * Write a modified dquot to disk.
  * The dquot must be locked and the flush lock too taken by caller.
@@ -1166,8 +1187,16 @@ xfs_qm_dqflush(
 		goto out_abort;
 	}
 
-	/* This is the only portion of data that needs to persist */
-	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
+	fa = xfs_qm_dqflush_check(dqp);
+	if (fa) {
+		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
+				be32_to_cpu(dqp->q_core.d_id), fa);
+		xfs_buf_relse(bp);
+		error = -EFSCORRUPTED;
+		goto out_abort;
+	}
+
+	xfs_dquot_to_disk(ddqp, dqp);
 
 	/*
 	 * Clear the dirty field and remember the flush lsn for later use.
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 71e36c85e20b..1b1a4261a580 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
 	return false;
 }
 
+void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
+
 #define XFS_DQ_IS_LOCKED(dqp)	(mutex_is_locked(&((dqp)->q_qlock)))
 #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
 #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index 349c92d26570..ff0ab65cf413 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format(
 	struct xfs_log_item	*lip,
 	struct xfs_log_vec	*lv)
 {
+	struct xfs_disk_dquot	ddq;
 	struct xfs_dq_logitem	*qlip = DQUOT_ITEM(lip);
 	struct xfs_log_iovec	*vecp = NULL;
 	struct xfs_dq_logformat	*qlf;
@@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format(
 	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
 	xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
 
-	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
-			&qlip->qli_dquot->q_core,
+	xfs_dquot_to_disk(&ddq, qlip->qli_dquot);
+
+	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq,
 			sizeof(struct xfs_disk_dquot));
 }
 
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 938023dd8ce5..632025c2f00b 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -161,7 +161,7 @@ xfs_qm_dqpurge(
 	xfs_dqfunlock(dqp);
 	xfs_dqunlock(dqp);
 
-	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
 			  be32_to_cpu(dqp->q_core.d_id));
 	qi->qi_dquots--;
 
@@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one(
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 
 	mutex_lock(&qi->qi_tree_lock);
-	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
 			  be32_to_cpu(dqp->q_core.d_id));
 
 	qi->qi_dquots--;
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 7b0e771fcbce..43b4650cdcdf 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -85,7 +85,7 @@ xfs_dquot_tree(
 	struct xfs_quotainfo	*qi,
 	int			type)
 {
-	switch (type) {
+	switch (type & XFS_DQ_ALLTYPES) {
 	case XFS_DQ_USER:
 		return &qi->qi_uquota_tree;
 	case XFS_DQ_GROUP:
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 7effd7a28136..8cbb65f01bf1 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc(
 	 * gets turned off. No need to confuse the user level code,
 	 * so return zeroes in that case.
 	 */
-	if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
-	     dqp->q_core.d_flags == XFS_DQ_USER) ||
-	    (!XFS_IS_GQUOTA_ENFORCED(mp) &&
-	     dqp->q_core.d_flags == XFS_DQ_GROUP) ||
-	    (!XFS_IS_PQUOTA_ENFORCED(mp) &&
-	     dqp->q_core.d_flags == XFS_DQ_PROJ)) {
+	if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) ||
+	    (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) ||
+	    (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) {
 		dst->d_spc_timer = 0;
 		dst->d_ino_timer = 0;
 		dst->d_rt_spc_timer = 0;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 05/18] xfs: stop using q_core.d_id in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (3 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
                   ` (12 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add a dquot id field to the incore dquot, and use that instead of the
one in qcore.  This eliminates a bunch of endian conversions and will
eventually allow us to remove qcore entirely.

We also rearrange the start of xfs_dquot to remove padding holes, saving
8 bytes.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/scrub/quota.c     |   19 ++++++++++++-------
 fs/xfs/xfs_dquot.c       |   25 +++++++++++--------------
 fs/xfs/xfs_dquot.h       |    5 +++--
 fs/xfs/xfs_dquot_item.c  |    2 +-
 fs/xfs/xfs_qm.c          |   22 ++++++++++------------
 fs/xfs/xfs_qm_syscalls.c |    4 ++--
 fs/xfs/xfs_trace.h       |    2 +-
 fs/xfs/xfs_trans_dquot.c |    8 +++-----
 8 files changed, 43 insertions(+), 44 deletions(-)


diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 710659d3fa28..9a271f115882 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -92,7 +92,6 @@ xchk_quota_item(
 	unsigned long long	icount;
 	unsigned long long	rcount;
 	xfs_ino_t		fs_icount;
-	xfs_dqid_t		id = be32_to_cpu(d->d_id);
 	int			error = 0;
 
 	if (xchk_should_terminate(sc, &error))
@@ -102,11 +101,11 @@ xchk_quota_item(
 	 * Except for the root dquot, the actual dquot we got must either have
 	 * the same or higher id as we saw before.
 	 */
-	offset = id / qi->qi_dqperchunk;
-	if (id && id <= sqi->last_id)
+	offset = dq->q_id / qi->qi_dqperchunk;
+	if (dq->q_id && dq->q_id <= sqi->last_id)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
-	sqi->last_id = id;
+	sqi->last_id = dq->q_id;
 
 	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
@@ -171,13 +170,19 @@ xchk_quota_item(
 	 * lower limit than the actual usage.  However, we flag it for
 	 * admin review.
 	 */
-	if (id != 0 && bhard != 0 && bcount > bhard)
+	if (dq->q_id == 0)
+		goto out;
+
+	if (bhard != 0 && bcount > bhard)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
-	if (id != 0 && ihard != 0 && icount > ihard)
+
+	if (ihard != 0 && icount > ihard)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
-	if (id != 0 && rhard != 0 && rcount > rhard)
+
+	if (rhard != 0 && rcount > rhard)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
+out:
 	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 		return -EFSCORRUPTED;
 
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 59d1bce34a98..76b35888e726 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits(
 	struct xfs_def_quota	*defq;
 	int			prealloc = 0;
 
-	ASSERT(d->d_id);
+	ASSERT(dq->q_id);
 	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
 
 	if (defq->bsoftlimit && !d->d_blk_softlimit) {
@@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers(
 	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_def_quota	*defq;
 
-	ASSERT(d->d_id);
+	ASSERT(dq->q_id);
 	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
 
 #ifdef DEBUG
@@ -365,7 +365,7 @@ xfs_dquot_disk_alloc(
 	 * Make a chunk of dquots out of this buffer and log
 	 * the entire thing.
 	 */
-	xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
+	xfs_qm_init_dquot_blk(tp, mp, dqp->q_id,
 			      dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
 	xfs_buf_set_ref(bp, XFS_DQUOT_REF);
 
@@ -478,7 +478,7 @@ xfs_dquot_alloc(
 	dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0);
 
 	dqp->dq_flags = type;
-	dqp->q_core.d_id = cpu_to_be32(id);
+	dqp->q_id = id;
 	dqp->q_mount = mp;
 	INIT_LIST_HEAD(&dqp->q_lru);
 	mutex_init(&dqp->q_qlock);
@@ -537,10 +537,10 @@ xfs_dquot_from_disk(
 	 */
 	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
 	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
-	    dqp->q_core.d_id != ddqp->d_id) {
+	    dqp->q_id != be32_to_cpu(ddqp->d_id)) {
 		xfs_alert(bp->b_mount,
 			  "Metadata corruption detected at %pS, quota %u",
-			  __this_address, be32_to_cpu(dqp->q_core.d_id));
+			  __this_address, dqp->q_id);
 		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
 		return -EFSCORRUPTED;
 	}
@@ -1177,11 +1177,10 @@ xfs_qm_dqflush(
 	ddqp = &dqb->dd_diskdq;
 
 	/* sanity check the in-core structure before we flush */
-	fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id),
-			      0);
+	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
 	if (fa) {
 		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
-				be32_to_cpu(dqp->q_core.d_id), fa);
+				dqp->q_id, fa);
 		xfs_buf_relse(bp);
 		error = -EFSCORRUPTED;
 		goto out_abort;
@@ -1190,7 +1189,7 @@ xfs_qm_dqflush(
 	fa = xfs_qm_dqflush_check(dqp);
 	if (fa) {
 		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
-				be32_to_cpu(dqp->q_core.d_id), fa);
+				dqp->q_id, fa);
 		xfs_buf_relse(bp);
 		error = -EFSCORRUPTED;
 		goto out_abort;
@@ -1263,8 +1262,7 @@ xfs_dqlock2(
 {
 	if (d1 && d2) {
 		ASSERT(d1 != d2);
-		if (be32_to_cpu(d1->q_core.d_id) >
-		    be32_to_cpu(d2->q_core.d_id)) {
+		if (d1->q_id > d2->q_id) {
 			mutex_lock(&d2->q_qlock);
 			mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
 		} else {
@@ -1332,9 +1330,8 @@ xfs_qm_dqiterate(
 			return error;
 
 		error = iter_fn(dq, dqtype, priv);
-		id = be32_to_cpu(dq->q_core.d_id);
+		id = dq->q_id + 1;
 		xfs_qm_dqput(dq);
-		id++;
 	} while (error == 0 && id != 0);
 
 	return error;
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 1b1a4261a580..5ea1f1515979 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -31,12 +31,13 @@ enum {
  * The incore dquot structure
  */
 struct xfs_dquot {
-	uint			dq_flags;
 	struct list_head	q_lru;
 	struct xfs_mount	*q_mount;
+	xfs_dqid_t		q_id;
+	uint			dq_flags;
 	uint			q_nrefs;
-	xfs_daddr_t		q_blkno;
 	int			q_bufoffset;
+	xfs_daddr_t		q_blkno;
 	xfs_fileoff_t		q_fileoffset;
 
 	struct xfs_disk_dquot	q_core;
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index ff0ab65cf413..378d919997f1 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format(
 	qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
 	qlf->qlf_type = XFS_LI_DQUOT;
 	qlf->qlf_size = 2;
-	qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id);
+	qlf->qlf_id = qlip->qli_dquot->q_id;
 	qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
 	qlf->qlf_len = 1;
 	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 632025c2f00b..95e51186bd57 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -79,7 +79,7 @@ xfs_qm_dquot_walk(
 		for (i = 0; i < nr_found; i++) {
 			struct xfs_dquot *dqp = batch[i];
 
-			next_index = be32_to_cpu(dqp->q_core.d_id) + 1;
+			next_index = dqp->q_id + 1;
 
 			error = execute(batch[i], data);
 			if (error == -EAGAIN) {
@@ -161,8 +161,7 @@ xfs_qm_dqpurge(
 	xfs_dqfunlock(dqp);
 	xfs_dqunlock(dqp);
 
-	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
-			  be32_to_cpu(dqp->q_core.d_id));
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
 	qi->qi_dquots--;
 
 	/*
@@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust(
 	 *
 	 * There are no timers for the default values set in the root dquot.
 	 */
-	if (dqp->q_core.d_id) {
+	if (dqp->q_id) {
 		xfs_qm_adjust_dqlimits(mp, dqp);
 		xfs_qm_adjust_dqtimers(mp, dqp);
 	}
@@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one(
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 
 	mutex_lock(&qi->qi_tree_lock);
-	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
-			  be32_to_cpu(dqp->q_core.d_id));
+	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
 
 	qi->qi_dquots--;
 	mutex_unlock(&qi->qi_tree_lock);
@@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve(
 			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
 
 	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
-	    i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) {
+	    i_uid_read(VFS_I(ip)) != udqp->q_id) {
 		udq_delblks = udqp;
 		/*
 		 * If there are delayed allocation blocks, then we have to
@@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve(
 		}
 	}
 	if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
-	    i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) {
+	    i_gid_read(VFS_I(ip)) != gdqp->q_id) {
 		gdq_delblks = gdqp;
 		if (delblks) {
 			ASSERT(ip->i_gdquot);
@@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve(
 	}
 
 	if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
-	    ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) {
+	    ip->i_d.di_projid != pdqp->q_id) {
 		pdq_delblks = pdqp;
 		if (delblks) {
 			ASSERT(ip->i_pdquot);
@@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach(
 
 	if (udqp && XFS_IS_UQUOTA_ON(mp)) {
 		ASSERT(ip->i_udquot == NULL);
-		ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id));
+		ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id);
 
 		ip->i_udquot = xfs_qm_dqhold(udqp);
 		xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
 	}
 	if (gdqp && XFS_IS_GQUOTA_ON(mp)) {
 		ASSERT(ip->i_gdquot == NULL);
-		ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id));
+		ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id);
 
 		ip->i_gdquot = xfs_qm_dqhold(gdqp);
 		xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
 	}
 	if (pdqp && XFS_IS_PQUOTA_ON(mp)) {
 		ASSERT(ip->i_pdquot == NULL);
-		ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id));
+		ASSERT(ip->i_d.di_projid == pdqp->q_id);
 
 		ip->i_pdquot = xfs_qm_dqhold(pdqp);
 		xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 8cbb65f01bf1..90a11e7daf92 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc(
 	if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) ||
 	     (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) ||
 	     (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) &&
-	    dqp->q_core.d_id != 0) {
+	    dqp->q_id != 0) {
 		if ((dst->d_space > dst->d_spc_softlimit) &&
 		    (dst->d_spc_softlimit > 0)) {
 			ASSERT(dst->d_spc_timer != 0);
@@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next(
 		return error;
 
 	/* Fill in the ID we actually read from disk */
-	*id = be32_to_cpu(dqp->q_core.d_id);
+	*id = dqp->q_id;
 
 	xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
 
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 2c5df8315351..78d9dbc7614d 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
 	), \
 	TP_fast_assign(
 		__entry->dev = dqp->q_mount->m_super->s_dev;
-		__entry->id = be32_to_cpu(dqp->q_core.d_id);
+		__entry->id = dqp->q_id;
 		__entry->flags = dqp->dq_flags;
 		__entry->nrefs = dqp->q_nrefs;
 		__entry->res_bcount = dqp->q_res_bcount;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index ed0ce8b301b4..a2656ec6ea76 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas(
 			 * Get any default limits in use.
 			 * Start/reset the timer(s) if needed.
 			 */
-			if (d->d_id) {
+			if (dqp->q_id) {
 				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
 				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
 			}
@@ -558,8 +558,7 @@ xfs_quota_warn(
 	else
 		qtype = GRPQUOTA;
 
-	quota_send_warning(make_kqid(&init_user_ns, qtype,
-				     be32_to_cpu(dqp->q_core.d_id)),
+	quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
 			   mp->m_super->s_dev, type);
 }
 
@@ -618,8 +617,7 @@ xfs_trans_dqresv(
 		resbcountp = &dqp->q_res_rtbcount;
 	}
 
-	if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
-	    dqp->q_core.d_id &&
+	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
 	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
 	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
 	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 06/18] xfs: use a per-resource struct for incore dquot data
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (4 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
                   ` (11 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Introduce a new struct xfs_dquot_res that we'll use to track all the
incore data for a particular resource type (block, inode, rt block).
This will help us (once we've eliminated q_core) to declutter quota
functions that currently open-code field access or pass around fields
around explicitly.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c       |    6 +++---
 fs/xfs/xfs_dquot.h       |   18 +++++++++++-------
 fs/xfs/xfs_iomap.c       |    6 +++---
 fs/xfs/xfs_qm.c          |    6 +++---
 fs/xfs/xfs_qm_bhv.c      |    8 ++++----
 fs/xfs/xfs_qm_syscalls.c |    6 +++---
 fs/xfs/xfs_trace.h       |    2 +-
 fs/xfs/xfs_trans_dquot.c |   42 +++++++++++++++++++++---------------------
 8 files changed, 49 insertions(+), 45 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 76b35888e726..03624a8f0566 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -552,9 +552,9 @@ xfs_dquot_from_disk(
 	 * Reservation counters are defined as reservation plus current usage
 	 * to avoid having to add every time.
 	 */
-	dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount);
-	dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
-	dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);
+	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
+	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
+	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
 
 	/* initialize the dquot speculative prealloc thresholds */
 	xfs_dquot_set_prealloc_limits(dqp);
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 5ea1f1515979..cb20df1e774f 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -27,6 +27,11 @@ enum {
 	XFS_QLOWSP_MAX
 };
 
+struct xfs_dquot_res {
+	/* Total resources allocated and reserved. */
+	xfs_qcnt_t		reserved;
+};
+
 /*
  * The incore dquot structure
  */
@@ -40,14 +45,13 @@ struct xfs_dquot {
 	xfs_daddr_t		q_blkno;
 	xfs_fileoff_t		q_fileoffset;
 
+	struct xfs_dquot_res	q_blk;	/* regular blocks */
+	struct xfs_dquot_res	q_ino;	/* inodes */
+	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
+
 	struct xfs_disk_dquot	q_core;
 	struct xfs_dq_logitem	q_logitem;
-	/* total regular nblks used+reserved */
-	xfs_qcnt_t		q_res_bcount;
-	/* total inos allocd+reserved */
-	xfs_qcnt_t		q_res_icount;
-	/* total realtime blks used+reserved */
-	xfs_qcnt_t		q_res_rtbcount;
+
 	xfs_qcnt_t		q_prealloc_lo_wmark;
 	xfs_qcnt_t		q_prealloc_hi_wmark;
 	int64_t			q_low_space[XFS_QLOWSP_MAX];
@@ -138,7 +142,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
 {
 	int64_t freesp;
 
-	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_res_bcount;
+	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
 	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
 		return true;
 
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index b9a8c3798e08..f60a6e44363b 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -307,7 +307,7 @@ xfs_quota_need_throttle(
 		return false;
 
 	/* under the lo watermark, no throttle */
-	if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark)
+	if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark)
 		return false;
 
 	return true;
@@ -326,13 +326,13 @@ xfs_quota_calc_throttle(
 	struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
 
 	/* no dq, or over hi wmark, squash the prealloc completely */
-	if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
+	if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) {
 		*qblocks = 0;
 		*qfreesp = 0;
 		return;
 	}
 
-	freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount;
+	freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved;
 	if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
 		shift = 2;
 		if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 95e51186bd57..6ce3a4402041 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust(
 	 * resource usage.
 	 */
 	be64_add_cpu(&dqp->q_core.d_icount, 1);
-	dqp->q_res_icount++;
+	dqp->q_ino.reserved++;
 	if (nblks) {
 		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
-		dqp->q_res_bcount += nblks;
+		dqp->q_blk.reserved += nblks;
 	}
 	if (rtblks) {
 		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
-		dqp->q_res_rtbcount += rtblks;
+		dqp->q_rtb.reserved += rtblks;
 	}
 
 	/*
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index fc2fa418919f..94b2b4b0fc17 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot(
 	if (limit && statp->f_blocks > limit) {
 		statp->f_blocks = limit;
 		statp->f_bfree = statp->f_bavail =
-			(statp->f_blocks > dqp->q_res_bcount) ?
-			 (statp->f_blocks - dqp->q_res_bcount) : 0;
+			(statp->f_blocks > dqp->q_blk.reserved) ?
+			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
 	}
 
 	limit = dqp->q_core.d_ino_softlimit ?
@@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot(
 	if (limit && statp->f_files > limit) {
 		statp->f_files = limit;
 		statp->f_ffree =
-			(statp->f_files > dqp->q_res_icount) ?
-			 (statp->f_files - dqp->q_res_icount) : 0;
+			(statp->f_files > dqp->q_ino.reserved) ?
+			 (statp->f_files - dqp->q_ino.reserved) : 0;
 	}
 }
 
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 90a11e7daf92..56fe80395679 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc(
 		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
 	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
 	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
-	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount);
-	dst->d_ino_count = dqp->q_res_icount;
+	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
+	dst->d_ino_count = dqp->q_ino.reserved;
 	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
 	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
 	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
@@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc(
 		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
 	dst->d_rt_spc_softlimit =
 		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
-	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount);
+	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
 	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
 	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
 
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 78d9dbc7614d..71567ed367f2 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
 		__entry->id = dqp->q_id;
 		__entry->flags = dqp->dq_flags;
 		__entry->nrefs = dqp->q_nrefs;
-		__entry->res_bcount = dqp->q_res_bcount;
+		__entry->res_bcount = dqp->q_blk.reserved;
 		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
 		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
 		__entry->blk_hardlimit =
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index a2656ec6ea76..469bf7946d3d 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas(
 
 				if (qtrx->qt_blk_res != blk_res_used) {
 					if (qtrx->qt_blk_res > blk_res_used)
-						dqp->q_res_bcount -= (xfs_qcnt_t)
+						dqp->q_blk.reserved -= (xfs_qcnt_t)
 							(qtrx->qt_blk_res -
 							 blk_res_used);
 					else
-						dqp->q_res_bcount -= (xfs_qcnt_t)
+						dqp->q_blk.reserved -= (xfs_qcnt_t)
 							(blk_res_used -
 							 qtrx->qt_blk_res);
 				}
@@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas(
 				 * deliberately skip quota reservations.
 				 */
 				if (qtrx->qt_bcount_delta) {
-					dqp->q_res_bcount +=
+					dqp->q_blk.reserved +=
 					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
 				}
 			}
@@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas(
 				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
 					if (qtrx->qt_rtblk_res >
 					    qtrx->qt_rtblk_res_used)
-					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
+					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
 						       (qtrx->qt_rtblk_res -
 							qtrx->qt_rtblk_res_used);
 					else
-					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
+					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
 						       (qtrx->qt_rtblk_res_used -
 							qtrx->qt_rtblk_res);
 				}
 			} else {
 				if (qtrx->qt_rtbcount_delta)
-					dqp->q_res_rtbcount +=
+					dqp->q_rtb.reserved +=
 					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
 			}
 
@@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas(
 				ASSERT(qtrx->qt_ino_res >=
 				       qtrx->qt_ino_res_used);
 				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
-					dqp->q_res_icount -= (xfs_qcnt_t)
+					dqp->q_ino.reserved -= (xfs_qcnt_t)
 						(qtrx->qt_ino_res -
 						 qtrx->qt_ino_res_used);
 			} else {
 				if (qtrx->qt_icount_delta)
-					dqp->q_res_icount +=
+					dqp->q_ino.reserved +=
 					    (xfs_qcnt_t)qtrx->qt_icount_delta;
 			}
 
-			ASSERT(dqp->q_res_bcount >=
+			ASSERT(dqp->q_blk.reserved >=
 				be64_to_cpu(dqp->q_core.d_bcount));
-			ASSERT(dqp->q_res_icount >=
+			ASSERT(dqp->q_ino.reserved >=
 				be64_to_cpu(dqp->q_core.d_icount));
-			ASSERT(dqp->q_res_rtbcount >=
+			ASSERT(dqp->q_rtb.reserved >=
 				be64_to_cpu(dqp->q_core.d_rtbcount));
 		}
 	}
@@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots(
 			if (qtrx->qt_blk_res) {
 				xfs_dqlock(dqp);
 				locked = true;
-				dqp->q_res_bcount -=
+				dqp->q_blk.reserved -=
 					(xfs_qcnt_t)qtrx->qt_blk_res;
 			}
 			if (qtrx->qt_ino_res) {
@@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots(
 					xfs_dqlock(dqp);
 					locked = true;
 				}
-				dqp->q_res_icount -=
+				dqp->q_ino.reserved -=
 					(xfs_qcnt_t)qtrx->qt_ino_res;
 			}
 
@@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots(
 					xfs_dqlock(dqp);
 					locked = true;
 				}
-				dqp->q_res_rtbcount -=
+				dqp->q_rtb.reserved -=
 					(xfs_qcnt_t)qtrx->qt_rtblk_res;
 			}
 			if (locked)
@@ -602,7 +602,7 @@ xfs_trans_dqresv(
 		timer = be32_to_cpu(dqp->q_core.d_btimer);
 		warns = be16_to_cpu(dqp->q_core.d_bwarns);
 		warnlimit = defq->bwarnlimit;
-		resbcountp = &dqp->q_res_bcount;
+		resbcountp = &dqp->q_blk.reserved;
 	} else {
 		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
 		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
@@ -614,7 +614,7 @@ xfs_trans_dqresv(
 		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
 		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
 		warnlimit = defq->rtbwarnlimit;
-		resbcountp = &dqp->q_res_rtbcount;
+		resbcountp = &dqp->q_rtb.reserved;
 	}
 
 	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
@@ -675,11 +675,11 @@ xfs_trans_dqresv(
 
 	/*
 	 * Change the reservation, but not the actual usage.
-	 * Note that q_res_bcount = q_core.d_bcount + resv
+	 * Note that q_blk.reserved = q_core.d_bcount + resv
 	 */
 	(*resbcountp) += (xfs_qcnt_t)nblks;
 	if (ninos != 0)
-		dqp->q_res_icount += (xfs_qcnt_t)ninos;
+		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
 
 	/*
 	 * note the reservation amt in the trans struct too,
@@ -700,9 +700,9 @@ xfs_trans_dqresv(
 					    XFS_TRANS_DQ_RES_INOS,
 					    ninos);
 	}
-	ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
-	ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
-	ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
+	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
+	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
+	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
 
 	xfs_dqunlock(dqp);
 	return 0;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (5 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
                     ` (3 more replies)
  2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
                   ` (10 subsequent siblings)
  17 siblings, 4 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add limits fields in the incore dquot, and use that instead of the ones
in qcore.  This eliminates a bunch of endian conversions and will
eventually allow us to remove qcore entirely.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/scrub/quota.c     |   36 ++++--------
 fs/xfs/xfs_dquot.c       |  136 ++++++++++++++++++++++++++--------------------
 fs/xfs/xfs_dquot.h       |    6 ++
 fs/xfs/xfs_qm.c          |   14 ++---
 fs/xfs/xfs_qm.h          |   12 ++--
 fs/xfs/xfs_qm_bhv.c      |   12 ++--
 fs/xfs/xfs_qm_syscalls.c |   40 ++++++--------
 fs/xfs/xfs_trace.h       |   12 +---
 fs/xfs/xfs_trans_dquot.c |   12 ++--
 9 files changed, 139 insertions(+), 141 deletions(-)


diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 9a271f115882..1a1c6996fc69 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -82,12 +82,6 @@ xchk_quota_item(
 	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 	xfs_fileoff_t		offset;
-	unsigned long long	bsoft;
-	unsigned long long	isoft;
-	unsigned long long	rsoft;
-	unsigned long long	bhard;
-	unsigned long long	ihard;
-	unsigned long long	rhard;
 	unsigned long long	bcount;
 	unsigned long long	icount;
 	unsigned long long	rcount;
@@ -110,15 +104,6 @@ xchk_quota_item(
 	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
-	/* Check the limits. */
-	bhard = be64_to_cpu(d->d_blk_hardlimit);
-	ihard = be64_to_cpu(d->d_ino_hardlimit);
-	rhard = be64_to_cpu(d->d_rtb_hardlimit);
-
-	bsoft = be64_to_cpu(d->d_blk_softlimit);
-	isoft = be64_to_cpu(d->d_ino_softlimit);
-	rsoft = be64_to_cpu(d->d_rtb_softlimit);
-
 	/*
 	 * Warn if the hard limits are larger than the fs.
 	 * Administrators can do this, though in production this seems
@@ -127,19 +112,19 @@ xchk_quota_item(
 	 * Complain about corruption if the soft limit is greater than
 	 * the hard limit.
 	 */
-	if (bhard > mp->m_sb.sb_dblocks)
+	if (dq->q_blk.hardlimit > mp->m_sb.sb_dblocks)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
-	if (bsoft > bhard)
+	if (dq->q_blk.softlimit > dq->q_blk.hardlimit)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
-	if (ihard > M_IGEO(mp)->maxicount)
+	if (dq->q_ino.hardlimit > M_IGEO(mp)->maxicount)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
-	if (isoft > ihard)
+	if (dq->q_ino.softlimit > dq->q_ino.hardlimit)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
-	if (rhard > mp->m_sb.sb_rblocks)
+	if (dq->q_rtb.hardlimit > mp->m_sb.sb_rblocks)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
-	if (rsoft > rhard)
+	if (dq->q_rtb.softlimit > dq->q_rtb.hardlimit)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
 	/* Check the resource counts. */
@@ -173,13 +158,16 @@ xchk_quota_item(
 	if (dq->q_id == 0)
 		goto out;
 
-	if (bhard != 0 && bcount > bhard)
+	if (dq->q_blk.hardlimit != 0 &&
+	    bcount > dq->q_blk.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
-	if (ihard != 0 && icount > ihard)
+	if (dq->q_ino.hardlimit != 0 &&
+	    icount > dq->q_ino.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
-	if (rhard != 0 && rcount > rhard)
+	if (dq->q_rtb.hardlimit != 0 &&
+	    rcount > dq->q_rtb.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
 out:
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 03624a8f0566..63f744bcbc90 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -70,29 +70,28 @@ xfs_qm_adjust_dqlimits(
 	struct xfs_dquot	*dq)
 {
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
-	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_def_quota	*defq;
 	int			prealloc = 0;
 
 	ASSERT(dq->q_id);
 	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
 
-	if (defq->bsoftlimit && !d->d_blk_softlimit) {
-		d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
+	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
+		dq->q_blk.softlimit = defq->bsoftlimit;
 		prealloc = 1;
 	}
-	if (defq->bhardlimit && !d->d_blk_hardlimit) {
-		d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
+	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
+		dq->q_blk.hardlimit = defq->bhardlimit;
 		prealloc = 1;
 	}
-	if (defq->isoftlimit && !d->d_ino_softlimit)
-		d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
-	if (defq->ihardlimit && !d->d_ino_hardlimit)
-		d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
-	if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
-		d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
-	if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
-		d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
+	if (defq->isoftlimit && !dq->q_ino.softlimit)
+		dq->q_ino.softlimit = defq->isoftlimit;
+	if (defq->ihardlimit && !dq->q_ino.hardlimit)
+		dq->q_ino.hardlimit = defq->ihardlimit;
+	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
+		dq->q_rtb.softlimit = defq->rtbsoftlimit;
+	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
+		dq->q_rtb.hardlimit = defq->rtbhardlimit;
 
 	if (prealloc)
 		xfs_dquot_set_prealloc_limits(dq);
@@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
 	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
 
 #ifdef DEBUG
-	if (d->d_blk_hardlimit)
-		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
-		       be64_to_cpu(d->d_blk_hardlimit));
-	if (d->d_ino_hardlimit)
-		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
-		       be64_to_cpu(d->d_ino_hardlimit));
-	if (d->d_rtb_hardlimit)
-		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
-		       be64_to_cpu(d->d_rtb_hardlimit));
+	if (dq->q_blk.hardlimit)
+		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
+	if (dq->q_ino.hardlimit)
+		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
+	if (dq->q_rtb.hardlimit)
+		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
 #endif
 
 	if (!d->d_btimer) {
-		if ((d->d_blk_softlimit &&
-		     (be64_to_cpu(d->d_bcount) >
-		      be64_to_cpu(d->d_blk_softlimit))) ||
-		    (d->d_blk_hardlimit &&
-		     (be64_to_cpu(d->d_bcount) >
-		      be64_to_cpu(d->d_blk_hardlimit)))) {
+		if ((dq->q_blk.softlimit &&
+		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
+		    (dq->q_blk.hardlimit &&
+		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
 			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->btimelimit);
 		} else {
 			d->d_bwarns = 0;
 		}
 	} else {
-		if ((!d->d_blk_softlimit ||
-		     (be64_to_cpu(d->d_bcount) <=
-		      be64_to_cpu(d->d_blk_softlimit))) &&
-		    (!d->d_blk_hardlimit ||
-		    (be64_to_cpu(d->d_bcount) <=
-		     be64_to_cpu(d->d_blk_hardlimit)))) {
+		if ((!dq->q_blk.softlimit ||
+		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
+		    (!dq->q_blk.hardlimit ||
+		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
 			d->d_btimer = 0;
 		}
 	}
 
 	if (!d->d_itimer) {
-		if ((d->d_ino_softlimit &&
-		     (be64_to_cpu(d->d_icount) >
-		      be64_to_cpu(d->d_ino_softlimit))) ||
-		    (d->d_ino_hardlimit &&
-		     (be64_to_cpu(d->d_icount) >
-		      be64_to_cpu(d->d_ino_hardlimit)))) {
+		if ((dq->q_ino.softlimit &&
+		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
+		    (dq->q_ino.hardlimit &&
+		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
 			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->itimelimit);
 		} else {
 			d->d_iwarns = 0;
 		}
 	} else {
-		if ((!d->d_ino_softlimit ||
-		     (be64_to_cpu(d->d_icount) <=
-		      be64_to_cpu(d->d_ino_softlimit)))  &&
-		    (!d->d_ino_hardlimit ||
-		     (be64_to_cpu(d->d_icount) <=
-		      be64_to_cpu(d->d_ino_hardlimit)))) {
+		if ((!dq->q_ino.softlimit ||
+		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
+		    (!dq->q_ino.hardlimit ||
+		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
 			d->d_itimer = 0;
 		}
 	}
 
 	if (!d->d_rtbtimer) {
-		if ((d->d_rtb_softlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >
-		      be64_to_cpu(d->d_rtb_softlimit))) ||
-		    (d->d_rtb_hardlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >
-		      be64_to_cpu(d->d_rtb_hardlimit)))) {
+		if ((dq->q_rtb.softlimit &&
+		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
+		    (dq->q_rtb.hardlimit &&
+		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
 			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->rtbtimelimit);
 		} else {
 			d->d_rtbwarns = 0;
 		}
 	} else {
-		if ((!d->d_rtb_softlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <=
-		      be64_to_cpu(d->d_rtb_softlimit))) &&
-		    (!d->d_rtb_hardlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <=
-		      be64_to_cpu(d->d_rtb_hardlimit)))) {
+		if ((!dq->q_rtb.softlimit ||
+		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
+		    (!dq->q_rtb.hardlimit ||
+		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
 			d->d_rtbtimer = 0;
 		}
 	}
@@ -290,8 +274,8 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
 {
 	uint64_t space;
 
-	dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
-	dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
+	dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit;
+	dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit;
 	if (!dqp->q_prealloc_lo_wmark) {
 		dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
 		do_div(dqp->q_prealloc_lo_wmark, 100);
@@ -547,6 +531,12 @@ xfs_dquot_from_disk(
 
 	/* copy everything from disk dquot to the incore dquot */
 	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
+	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
+	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
+	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
+	dqp->q_ino.softlimit = be64_to_cpu(ddqp->d_ino_softlimit);
+	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
+	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
 
 	/*
 	 * Reservation counters are defined as reservation plus current usage
@@ -569,6 +559,12 @@ xfs_dquot_to_disk(
 {
 	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
 	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
+	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
+	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
+	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
+	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
+	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
+	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
 }
 
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
@@ -1123,9 +1119,29 @@ static xfs_failaddr_t
 xfs_qm_dqflush_check(
 	struct xfs_dquot	*dqp)
 {
+	struct xfs_disk_dquot	*ddq = &dqp->q_core;
+
 	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
 		return __this_address;
 
+	if (dqp->q_id == 0)
+		return NULL;
+
+	if (dqp->q_blk.softlimit &&
+	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
+	    !ddq->d_btimer)
+		return __this_address;
+
+	if (dqp->q_ino.softlimit &&
+	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
+	    !ddq->d_itimer)
+		return __this_address;
+
+	if (dqp->q_rtb.softlimit &&
+	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
+	    !ddq->d_rtbtimer)
+		return __this_address;
+
 	return NULL;
 }
 
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index cb20df1e774f..edb49788c476 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -30,6 +30,10 @@ enum {
 struct xfs_dquot_res {
 	/* Total resources allocated and reserved. */
 	xfs_qcnt_t		reserved;
+
+	/* Absolute and preferred limits. */
+	xfs_qcnt_t		hardlimit;
+	xfs_qcnt_t		softlimit;
 };
 
 /*
@@ -142,7 +146,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
 {
 	int64_t freesp;
 
-	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
+	freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
 	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
 		return true;
 
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 6ce3a4402041..54fc3aac1a68 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -550,26 +550,24 @@ xfs_qm_set_defquota(
 {
 	struct xfs_dquot	*dqp;
 	struct xfs_def_quota	*defq;
-	struct xfs_disk_dquot	*ddqp;
 	int			error;
 
 	error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
 	if (error)
 		return;
 
-	ddqp = &dqp->q_core;
 	defq = xfs_get_defquota(qinf, xfs_dquot_type(dqp));
 
 	/*
 	 * Timers and warnings have been already set, let's just set the
 	 * default limits for this quota type
 	 */
-	defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
-	defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
-	defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
-	defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
-	defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
-	defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
+	defq->bhardlimit = dqp->q_blk.hardlimit;
+	defq->bsoftlimit = dqp->q_blk.softlimit;
+	defq->ihardlimit = dqp->q_ino.hardlimit;
+	defq->isoftlimit = dqp->q_ino.softlimit;
+	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
+	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
 	xfs_qm_dqdestroy(dqp);
 }
 
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 43b4650cdcdf..84cb8af468b7 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -20,12 +20,12 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
 #define XFS_DQITER_MAP_SIZE	10
 
 #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
-	!dqp->q_core.d_blk_hardlimit && \
-	!dqp->q_core.d_blk_softlimit && \
-	!dqp->q_core.d_rtb_hardlimit && \
-	!dqp->q_core.d_rtb_softlimit && \
-	!dqp->q_core.d_ino_hardlimit && \
-	!dqp->q_core.d_ino_softlimit && \
+	!dqp->q_blk.hardlimit && \
+	!dqp->q_blk.softlimit && \
+	!dqp->q_rtb.hardlimit && \
+	!dqp->q_rtb.softlimit && \
+	!dqp->q_ino.hardlimit && \
+	!dqp->q_ino.softlimit && \
 	!dqp->q_core.d_bcount && \
 	!dqp->q_core.d_rtbcount && \
 	!dqp->q_core.d_icount)
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index 94b2b4b0fc17..0993217e5ac8 100644
--- a/fs/xfs/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
@@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot(
 {
 	uint64_t		limit;
 
-	limit = dqp->q_core.d_blk_softlimit ?
-		be64_to_cpu(dqp->q_core.d_blk_softlimit) :
-		be64_to_cpu(dqp->q_core.d_blk_hardlimit);
+	limit = dqp->q_blk.softlimit ?
+		dqp->q_blk.softlimit :
+		dqp->q_blk.hardlimit;
 	if (limit && statp->f_blocks > limit) {
 		statp->f_blocks = limit;
 		statp->f_bfree = statp->f_bavail =
@@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot(
 			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
 	}
 
-	limit = dqp->q_core.d_ino_softlimit ?
-		be64_to_cpu(dqp->q_core.d_ino_softlimit) :
-		be64_to_cpu(dqp->q_core.d_ino_hardlimit);
+	limit = dqp->q_ino.softlimit ?
+		dqp->q_ino.softlimit :
+		dqp->q_ino.hardlimit;
 	if (limit && statp->f_files > limit) {
 		statp->f_files = limit;
 		statp->f_ffree =
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 56fe80395679..ab596d389e3e 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -495,13 +495,13 @@ xfs_qm_scall_setqlim(
 	 */
 	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
-			be64_to_cpu(ddq->d_blk_hardlimit);
+			dqp->q_blk.hardlimit;
 	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
-			be64_to_cpu(ddq->d_blk_softlimit);
+			dqp->q_blk.softlimit;
 	if (hard == 0 || hard >= soft) {
-		ddq->d_blk_hardlimit = cpu_to_be64(hard);
-		ddq->d_blk_softlimit = cpu_to_be64(soft);
+		dqp->q_blk.hardlimit = hard;
+		dqp->q_blk.softlimit = soft;
 		xfs_dquot_set_prealloc_limits(dqp);
 		if (id == 0) {
 			defq->bhardlimit = hard;
@@ -512,13 +512,13 @@ xfs_qm_scall_setqlim(
 	}
 	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
-			be64_to_cpu(ddq->d_rtb_hardlimit);
+			dqp->q_rtb.hardlimit;
 	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
-			be64_to_cpu(ddq->d_rtb_softlimit);
+			dqp->q_rtb.softlimit;
 	if (hard == 0 || hard >= soft) {
-		ddq->d_rtb_hardlimit = cpu_to_be64(hard);
-		ddq->d_rtb_softlimit = cpu_to_be64(soft);
+		dqp->q_rtb.hardlimit = hard;
+		dqp->q_rtb.softlimit = soft;
 		if (id == 0) {
 			defq->rtbhardlimit = hard;
 			defq->rtbsoftlimit = soft;
@@ -529,13 +529,13 @@ xfs_qm_scall_setqlim(
 
 	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
 		(xfs_qcnt_t) newlim->d_ino_hardlimit :
-			be64_to_cpu(ddq->d_ino_hardlimit);
+			dqp->q_ino.hardlimit;
 	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
 		(xfs_qcnt_t) newlim->d_ino_softlimit :
-			be64_to_cpu(ddq->d_ino_softlimit);
+			dqp->q_ino.softlimit;
 	if (hard == 0 || hard >= soft) {
-		ddq->d_ino_hardlimit = cpu_to_be64(hard);
-		ddq->d_ino_softlimit = cpu_to_be64(soft);
+		dqp->q_ino.hardlimit = hard;
+		dqp->q_ino.softlimit = soft;
 		if (id == 0) {
 			defq->ihardlimit = hard;
 			defq->isoftlimit = soft;
@@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc(
 	struct qc_dqblk		*dst)
 {
 	memset(dst, 0, sizeof(*dst));
-	dst->d_spc_hardlimit =
-		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
-	dst->d_spc_softlimit =
-		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
+	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
+	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
 	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
 	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
 	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
@@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc(
 	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
 	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
 	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
-	dst->d_rt_spc_hardlimit =
-		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
-	dst->d_rt_spc_softlimit =
-		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
+	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
+	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
 	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
 	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
 	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
@@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc(
 		    (dst->d_spc_softlimit > 0)) {
 			ASSERT(dst->d_spc_timer != 0);
 		}
-		if ((dst->d_ino_count > dst->d_ino_softlimit) &&
-		    (dst->d_ino_softlimit > 0)) {
+		if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
+		    (dqp->q_ino.softlimit > 0)) {
 			ASSERT(dst->d_ino_timer != 0);
 		}
 	}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 71567ed367f2..7f744a37dc0e 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
 		__entry->res_bcount = dqp->q_blk.reserved;
 		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
 		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
-		__entry->blk_hardlimit =
-			be64_to_cpu(dqp->q_core.d_blk_hardlimit);
-		__entry->blk_softlimit =
-			be64_to_cpu(dqp->q_core.d_blk_softlimit);
-		__entry->ino_hardlimit =
-			be64_to_cpu(dqp->q_core.d_ino_hardlimit);
-		__entry->ino_softlimit =
-			be64_to_cpu(dqp->q_core.d_ino_softlimit);
+		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
+		__entry->blk_softlimit = dqp->q_blk.softlimit;
+		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
+		__entry->ino_softlimit = dqp->q_ino.softlimit;
 	),
 	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
 		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 469bf7946d3d..7a3d64eb9fbf 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -593,10 +593,10 @@ xfs_trans_dqresv(
 	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
 
 	if (flags & XFS_TRANS_DQ_RES_BLKS) {
-		hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
+		hardlimit = dqp->q_blk.hardlimit;
 		if (!hardlimit)
 			hardlimit = defq->bhardlimit;
-		softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
+		softlimit = dqp->q_blk.softlimit;
 		if (!softlimit)
 			softlimit = defq->bsoftlimit;
 		timer = be32_to_cpu(dqp->q_core.d_btimer);
@@ -605,10 +605,10 @@ xfs_trans_dqresv(
 		resbcountp = &dqp->q_blk.reserved;
 	} else {
 		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
-		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
+		hardlimit = dqp->q_rtb.hardlimit;
 		if (!hardlimit)
 			hardlimit = defq->rtbhardlimit;
-		softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
+		softlimit = dqp->q_rtb.softlimit;
 		if (!softlimit)
 			softlimit = defq->rtbsoftlimit;
 		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
@@ -649,10 +649,10 @@ xfs_trans_dqresv(
 			timer = be32_to_cpu(dqp->q_core.d_itimer);
 			warns = be16_to_cpu(dqp->q_core.d_iwarns);
 			warnlimit = defq->iwarnlimit;
-			hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
+			hardlimit = dqp->q_ino.hardlimit;
 			if (!hardlimit)
 				hardlimit = defq->ihardlimit;
-			softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
+			softlimit = dqp->q_ino.softlimit;
 			if (!softlimit)
 				softlimit = defq->isoftlimit;
 


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 08/18] xfs: stop using q_core counters in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (6 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
                   ` (9 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add counter fields to the incore dquot, and use that instead of the ones
in qcore.  This eliminates a bunch of endian conversions and will
eventually allow us to remove qcore entirely.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/scrub/quota.c     |   18 ++++++------------
 fs/xfs/xfs_dquot.c       |   47 +++++++++++++++++++++++++---------------------
 fs/xfs/xfs_dquot.h       |    3 +++
 fs/xfs/xfs_qm.c          |    6 +++---
 fs/xfs/xfs_qm.h          |    6 +++---
 fs/xfs/xfs_trace.h       |    4 ++--
 fs/xfs/xfs_trans_dquot.c |   36 ++++++++++++++---------------------
 7 files changed, 57 insertions(+), 63 deletions(-)


diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 1a1c6996fc69..2fc2625feca0 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -82,9 +82,6 @@ xchk_quota_item(
 	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 	xfs_fileoff_t		offset;
-	unsigned long long	bcount;
-	unsigned long long	icount;
-	unsigned long long	rcount;
 	xfs_ino_t		fs_icount;
 	int			error = 0;
 
@@ -128,9 +125,6 @@ xchk_quota_item(
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
 	/* Check the resource counts. */
-	bcount = be64_to_cpu(d->d_bcount);
-	icount = be64_to_cpu(d->d_icount);
-	rcount = be64_to_cpu(d->d_rtbcount);
 	fs_icount = percpu_counter_sum(&mp->m_icount);
 
 	/*
@@ -139,15 +133,15 @@ xchk_quota_item(
 	 * if there are no quota limits.
 	 */
 	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
-		if (mp->m_sb.sb_dblocks < bcount)
+		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
 			xchk_fblock_set_warning(sc, XFS_DATA_FORK,
 					offset);
 	} else {
-		if (mp->m_sb.sb_dblocks < bcount)
+		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
 			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
 					offset);
 	}
-	if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks)
+	if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks)
 		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
 
 	/*
@@ -159,15 +153,15 @@ xchk_quota_item(
 		goto out;
 
 	if (dq->q_blk.hardlimit != 0 &&
-	    bcount > dq->q_blk.hardlimit)
+	    dq->q_blk.count > dq->q_blk.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
 	if (dq->q_ino.hardlimit != 0 &&
-	    icount > dq->q_ino.hardlimit)
+	    dq->q_ino.count > dq->q_ino.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
 	if (dq->q_rtb.hardlimit != 0 &&
-	    rcount > dq->q_rtb.hardlimit)
+	    dq->q_rtb.count > dq->q_rtb.hardlimit)
 		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
 
 out:
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 63f744bcbc90..02eae8c2ba1b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers(
 
 	if (!d->d_btimer) {
 		if ((dq->q_blk.softlimit &&
-		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
+		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
 		    (dq->q_blk.hardlimit &&
-		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
+		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
 			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->btimelimit);
 		} else {
@@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!dq->q_blk.softlimit ||
-		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
+		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
 		    (!dq->q_blk.hardlimit ||
-		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
+		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
 			d->d_btimer = 0;
 		}
 	}
 
 	if (!d->d_itimer) {
 		if ((dq->q_ino.softlimit &&
-		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
+		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
 		    (dq->q_ino.hardlimit &&
-		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
+		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
 			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->itimelimit);
 		} else {
@@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!dq->q_ino.softlimit ||
-		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
+		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
 		    (!dq->q_ino.hardlimit ||
-		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
+		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
 			d->d_itimer = 0;
 		}
 	}
 
 	if (!d->d_rtbtimer) {
 		if ((dq->q_rtb.softlimit &&
-		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
+		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
 		    (dq->q_rtb.hardlimit &&
-		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
+		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
 			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->rtbtimelimit);
 		} else {
@@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!dq->q_rtb.softlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
+		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
 		    (!dq->q_rtb.hardlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
+		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
 			d->d_rtbtimer = 0;
 		}
 	}
@@ -538,13 +538,17 @@ xfs_dquot_from_disk(
 	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
 	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
 
+	dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount);
+	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
+	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
+
 	/*
 	 * Reservation counters are defined as reservation plus current usage
 	 * to avoid having to add every time.
 	 */
-	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
-	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
-	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
+	dqp->q_blk.reserved = dqp->q_blk.count;
+	dqp->q_ino.reserved = dqp->q_ino.count;
+	dqp->q_rtb.reserved = dqp->q_rtb.count;
 
 	/* initialize the dquot speculative prealloc thresholds */
 	xfs_dquot_set_prealloc_limits(dqp);
@@ -565,6 +569,10 @@ xfs_dquot_to_disk(
 	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
 	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
 	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
+
+	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
+	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
+	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
 }
 
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
@@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check(
 	if (dqp->q_id == 0)
 		return NULL;
 
-	if (dqp->q_blk.softlimit &&
-	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
+	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
 	    !ddq->d_btimer)
 		return __this_address;
 
-	if (dqp->q_ino.softlimit &&
-	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
+	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
 	    !ddq->d_itimer)
 		return __this_address;
 
-	if (dqp->q_rtb.softlimit &&
-	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
+	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
 	    !ddq->d_rtbtimer)
 		return __this_address;
 
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index edb49788c476..23e05b0d7567 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -31,6 +31,9 @@ struct xfs_dquot_res {
 	/* Total resources allocated and reserved. */
 	xfs_qcnt_t		reserved;
 
+	/* Total resources allocated. */
+	xfs_qcnt_t		count;
+
 	/* Absolute and preferred limits. */
 	xfs_qcnt_t		hardlimit;
 	xfs_qcnt_t		softlimit;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 54fc3aac1a68..b47bba204240 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust(
 	 * Adjust the inode count and the block count to reflect this inode's
 	 * resource usage.
 	 */
-	be64_add_cpu(&dqp->q_core.d_icount, 1);
+	dqp->q_ino.count++;
 	dqp->q_ino.reserved++;
 	if (nblks) {
-		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
+		dqp->q_blk.count += nblks;
 		dqp->q_blk.reserved += nblks;
 	}
 	if (rtblks) {
-		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
+		dqp->q_rtb.count += rtblks;
 		dqp->q_rtb.reserved += rtblks;
 	}
 
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 84cb8af468b7..6ed4ae942603 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -26,9 +26,9 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
 	!dqp->q_rtb.softlimit && \
 	!dqp->q_ino.hardlimit && \
 	!dqp->q_ino.softlimit && \
-	!dqp->q_core.d_bcount && \
-	!dqp->q_core.d_rtbcount && \
-	!dqp->q_core.d_icount)
+	!dqp->q_blk.count && \
+	!dqp->q_rtb.count && \
+	!dqp->q_ino.count)
 
 /*
  * This defines the unit of allocation of dquots.
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 7f744a37dc0e..851f97dfe9e3 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
 		__entry->flags = dqp->dq_flags;
 		__entry->nrefs = dqp->q_nrefs;
 		__entry->res_bcount = dqp->q_blk.reserved;
-		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
-		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
+		__entry->bcount = dqp->q_blk.count;
+		__entry->icount = dqp->q_ino.count;
 		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
 		__entry->blk_softlimit = dqp->q_blk.softlimit;
 		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 7a3d64eb9fbf..b36d747989a7 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas(
 	int			i, j;
 	struct xfs_dquot	*dqp;
 	struct xfs_dqtrx	*qtrx, *qa;
-	struct xfs_disk_dquot	*d;
 	int64_t			totalbdelta;
 	int64_t			totalrtbdelta;
 
@@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas(
 			/*
 			 * adjust the actual number of blocks used
 			 */
-			d = &dqp->q_core;
 
 			/*
 			 * The issue here is - sometimes we don't make a blkquota
@@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas(
 				qtrx->qt_delrtb_delta;
 #ifdef DEBUG
 			if (totalbdelta < 0)
-				ASSERT(be64_to_cpu(d->d_bcount) >=
-				       -totalbdelta);
+				ASSERT(dqp->q_blk.count >= -totalbdelta);
 
 			if (totalrtbdelta < 0)
-				ASSERT(be64_to_cpu(d->d_rtbcount) >=
-				       -totalrtbdelta);
+				ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
 
 			if (qtrx->qt_icount_delta < 0)
-				ASSERT(be64_to_cpu(d->d_icount) >=
-				       -qtrx->qt_icount_delta);
+				ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
 #endif
 			if (totalbdelta)
-				be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
+				dqp->q_blk.count += totalbdelta;
 
 			if (qtrx->qt_icount_delta)
-				be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
+				dqp->q_ino.count += qtrx->qt_icount_delta;
 
 			if (totalrtbdelta)
-				be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
+				dqp->q_rtb.count += totalrtbdelta;
 
 			/*
 			 * Get any default limits in use.
@@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas(
 					    (xfs_qcnt_t)qtrx->qt_icount_delta;
 			}
 
-			ASSERT(dqp->q_blk.reserved >=
-				be64_to_cpu(dqp->q_core.d_bcount));
-			ASSERT(dqp->q_ino.reserved >=
-				be64_to_cpu(dqp->q_core.d_icount));
-			ASSERT(dqp->q_rtb.reserved >=
-				be64_to_cpu(dqp->q_core.d_rtbcount));
+			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
+			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
+			ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
 		}
 	}
 }
@@ -645,7 +637,7 @@ xfs_trans_dqresv(
 			}
 		}
 		if (ninos > 0) {
-			total_count = dqp->q_res_icount + ninos;
+			total_count = dqp->q_ino.reserved + ninos;
 			timer = be32_to_cpu(dqp->q_core.d_itimer);
 			warns = be16_to_cpu(dqp->q_core.d_iwarns);
 			warnlimit = defq->iwarnlimit;
@@ -675,7 +667,7 @@ xfs_trans_dqresv(
 
 	/*
 	 * Change the reservation, but not the actual usage.
-	 * Note that q_blk.reserved = q_core.d_bcount + resv
+	 * Note that q_blk.reserved = q_blk.count + resv
 	 */
 	(*resbcountp) += (xfs_qcnt_t)nblks;
 	if (ninos != 0)
@@ -700,9 +692,9 @@ xfs_trans_dqresv(
 					    XFS_TRANS_DQ_RES_INOS,
 					    ninos);
 	}
-	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
-	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
-	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
+	ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
+	ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
+	ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
 
 	xfs_dqunlock(dqp);
 	return 0;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 09/18] xfs: stop using q_core warning counters in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (7 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
                     ` (2 more replies)
  2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
                   ` (8 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add warning counter fields to the incore dquot, and use that instead of
the ones in qcore.  This eliminates a bunch of endian conversions and
will eventually allow us to remove qcore entirely.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c       |   14 +++++++++++---
 fs/xfs/xfs_dquot.h       |    8 ++++++++
 fs/xfs/xfs_qm.c          |   12 ++++++------
 fs/xfs/xfs_qm_syscalls.c |   12 ++++++------
 fs/xfs/xfs_trans_dquot.c |    6 +++---
 5 files changed, 34 insertions(+), 18 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 02eae8c2ba1b..a1edb49ceda5 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers(
 			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->btimelimit);
 		} else {
-			d->d_bwarns = 0;
+			dq->q_blk.warnings = 0;
 		}
 	} else {
 		if ((!dq->q_blk.softlimit ||
@@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers(
 			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->itimelimit);
 		} else {
-			d->d_iwarns = 0;
+			dq->q_ino.warnings = 0;
 		}
 	} else {
 		if ((!dq->q_ino.softlimit ||
@@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers(
 			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
 					defq->rtbtimelimit);
 		} else {
-			d->d_rtbwarns = 0;
+			dq->q_rtb.warnings = 0;
 		}
 	} else {
 		if ((!dq->q_rtb.softlimit ||
@@ -542,6 +542,10 @@ xfs_dquot_from_disk(
 	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
 	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
 
+	dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns);
+	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
+	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
+
 	/*
 	 * Reservation counters are defined as reservation plus current usage
 	 * to avoid having to add every time.
@@ -573,6 +577,10 @@ xfs_dquot_to_disk(
 	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
 	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
 	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
+
+	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
+	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
+	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
 }
 
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 23e05b0d7567..5840bc54b772 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -37,6 +37,14 @@ struct xfs_dquot_res {
 	/* Absolute and preferred limits. */
 	xfs_qcnt_t		hardlimit;
 	xfs_qcnt_t		softlimit;
+
+	/*
+	 * For root dquots, this is the maximum number of warnings that will
+	 * be issued for this quota type.  Otherwise, this is the number of
+	 * warnings issued against this quota.  Note that none of this is
+	 * implemented.
+	 */
+	xfs_qwarncnt_t		warnings;
 };
 
 /*
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index b47bba204240..4e233cfef46d 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -616,12 +616,12 @@ xfs_qm_init_timelimits(
 		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
 	if (ddqp->d_rtbtimer)
 		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
-	if (ddqp->d_bwarns)
-		defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns);
-	if (ddqp->d_iwarns)
-		defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns);
-	if (ddqp->d_rtbwarns)
-		defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns);
+	if (dqp->q_blk.warnings)
+		defq->bwarnlimit = dqp->q_blk.warnings;
+	if (dqp->q_ino.warnings)
+		defq->iwarnlimit = dqp->q_ino.warnings;
+	if (dqp->q_rtb.warnings)
+		defq->rtbwarnlimit = dqp->q_rtb.warnings;
 
 	xfs_qm_dqdestroy(dqp);
 }
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index ab596d389e3e..5d3bccdbd3bf 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -548,11 +548,11 @@ xfs_qm_scall_setqlim(
 	 * Update warnings counter(s) if requested
 	 */
 	if (newlim->d_fieldmask & QC_SPC_WARNS)
-		ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns);
+		dqp->q_blk.warnings = newlim->d_spc_warns;
 	if (newlim->d_fieldmask & QC_INO_WARNS)
-		ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns);
+		dqp->q_ino.warnings = newlim->d_ino_warns;
 	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
-		ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns);
+		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
 
 	if (id == 0) {
 		if (newlim->d_fieldmask & QC_SPC_WARNS)
@@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc(
 	dst->d_ino_count = dqp->q_ino.reserved;
 	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
 	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
-	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
-	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
+	dst->d_ino_warns = dqp->q_ino.warnings;
+	dst->d_spc_warns = dqp->q_blk.warnings;
 	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
 	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
 	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
 	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
-	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
+	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
 
 	/*
 	 * Internally, we don't reset all the timers when quota enforcement
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index b36d747989a7..21ed8eda3c80 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -592,7 +592,7 @@ xfs_trans_dqresv(
 		if (!softlimit)
 			softlimit = defq->bsoftlimit;
 		timer = be32_to_cpu(dqp->q_core.d_btimer);
-		warns = be16_to_cpu(dqp->q_core.d_bwarns);
+		warns = dqp->q_blk.warnings;
 		warnlimit = defq->bwarnlimit;
 		resbcountp = &dqp->q_blk.reserved;
 	} else {
@@ -604,7 +604,7 @@ xfs_trans_dqresv(
 		if (!softlimit)
 			softlimit = defq->rtbsoftlimit;
 		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
-		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
+		warns = dqp->q_rtb.warnings;
 		warnlimit = defq->rtbwarnlimit;
 		resbcountp = &dqp->q_rtb.reserved;
 	}
@@ -639,7 +639,7 @@ xfs_trans_dqresv(
 		if (ninos > 0) {
 			total_count = dqp->q_ino.reserved + ninos;
 			timer = be32_to_cpu(dqp->q_core.d_itimer);
-			warns = be16_to_cpu(dqp->q_core.d_iwarns);
+			warns = dqp->q_ino.warnings;
 			warnlimit = defq->iwarnlimit;
 			hardlimit = dqp->q_ino.hardlimit;
 			if (!hardlimit)


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 10/18] xfs: stop using q_core timers in the quota code
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (8 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
@ 2020-06-30 15:42 ` Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
                     ` (2 more replies)
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
                   ` (7 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:42 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add timers fields to the incore dquot, and use that instead of the ones
in qcore.  This eliminates a bunch of endian conversions and will
eventually allow us to remove qcore entirely.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c       |   41 +++++++++++++++++++++++------------------
 fs/xfs/xfs_dquot.h       |    7 +++++++
 fs/xfs/xfs_qm.c          |   15 ++++++---------
 fs/xfs/xfs_qm_syscalls.c |   18 ++++++++----------
 fs/xfs/xfs_trans_dquot.c |    6 +++---
 5 files changed, 47 insertions(+), 40 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index a1edb49ceda5..7434ee57ec43 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers(
 	struct xfs_dquot	*dq)
 {
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
-	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_def_quota	*defq;
 
 	ASSERT(dq->q_id);
@@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers(
 		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
 #endif
 
-	if (!d->d_btimer) {
+	if (!dq->q_blk.timer) {
 		if ((dq->q_blk.softlimit &&
 		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
 		    (dq->q_blk.hardlimit &&
 		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
-			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
-					defq->btimelimit);
+			dq->q_blk.timer = ktime_get_real_seconds() +
+					defq->btimelimit;
 		} else {
 			dq->q_blk.warnings = 0;
 		}
@@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers(
 		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
 		    (!dq->q_blk.hardlimit ||
 		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
-			d->d_btimer = 0;
+			dq->q_blk.timer = 0;
 		}
 	}
 
-	if (!d->d_itimer) {
+	if (!dq->q_ino.timer) {
 		if ((dq->q_ino.softlimit &&
 		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
 		    (dq->q_ino.hardlimit &&
 		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
-			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
-					defq->itimelimit);
+			dq->q_ino.timer = ktime_get_real_seconds() +
+					defq->itimelimit;
 		} else {
 			dq->q_ino.warnings = 0;
 		}
@@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers(
 		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
 		    (!dq->q_ino.hardlimit ||
 		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
-			d->d_itimer = 0;
+			dq->q_ino.timer = 0;
 		}
 	}
 
-	if (!d->d_rtbtimer) {
+	if (!dq->q_rtb.timer) {
 		if ((dq->q_rtb.softlimit &&
 		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
 		    (dq->q_rtb.hardlimit &&
 		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
-			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
-					defq->rtbtimelimit);
+			dq->q_rtb.timer = ktime_get_real_seconds() +
+					defq->rtbtimelimit;
 		} else {
 			dq->q_rtb.warnings = 0;
 		}
@@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers(
 		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
 		    (!dq->q_rtb.hardlimit ||
 		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
-			d->d_rtbtimer = 0;
+			dq->q_rtb.timer = 0;
 		}
 	}
 }
@@ -546,6 +545,10 @@ xfs_dquot_from_disk(
 	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
 	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
 
+	dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer);
+	dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer);
+	dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer);
+
 	/*
 	 * Reservation counters are defined as reservation plus current usage
 	 * to avoid having to add every time.
@@ -581,6 +584,10 @@ xfs_dquot_to_disk(
 	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
 	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
 	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
+
+	ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer);
+	ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer);
+	ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer);
 }
 
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
@@ -1135,8 +1142,6 @@ static xfs_failaddr_t
 xfs_qm_dqflush_check(
 	struct xfs_dquot	*dqp)
 {
-	struct xfs_disk_dquot	*ddq = &dqp->q_core;
-
 	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
 		return __this_address;
 
@@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check(
 		return NULL;
 
 	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
-	    !ddq->d_btimer)
+	    !dqp->q_blk.timer)
 		return __this_address;
 
 	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
-	    !ddq->d_itimer)
+	    !dqp->q_ino.timer)
 		return __this_address;
 
 	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
-	    !ddq->d_rtbtimer)
+	    !dqp->q_rtb.timer)
 		return __this_address;
 
 	return NULL;
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 5840bc54b772..414bae537b1d 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -38,6 +38,13 @@ struct xfs_dquot_res {
 	xfs_qcnt_t		hardlimit;
 	xfs_qcnt_t		softlimit;
 
+	/*
+	 * For root dquots, this is the default grace period, in seconds.
+	 * Otherwise, this is when the quota grace period expires,
+	 * in seconds since the Unix epoch.
+	 */
+	time64_t		timer;
+
 	/*
 	 * For root dquots, this is the maximum number of warnings that will
 	 * be issued for this quota type.  Otherwise, this is the number of
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 4e233cfef46d..a56c6e4a5d99 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -579,7 +579,6 @@ xfs_qm_init_timelimits(
 {
 	struct xfs_quotainfo	*qinf = mp->m_quotainfo;
 	struct xfs_def_quota	*defq;
-	struct xfs_disk_dquot	*ddqp;
 	struct xfs_dquot	*dqp;
 	int			error;
 
@@ -603,19 +602,17 @@ xfs_qm_init_timelimits(
 	if (error)
 		return;
 
-	ddqp = &dqp->q_core;
-
 	/*
 	 * The warnings and timers set the grace period given to
 	 * a user or group before he or she can not perform any
 	 * more writing. If it is zero, a default is used.
 	 */
-	if (ddqp->d_btimer)
-		defq->btimelimit = be32_to_cpu(ddqp->d_btimer);
-	if (ddqp->d_itimer)
-		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
-	if (ddqp->d_rtbtimer)
-		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
+	if (dqp->q_blk.timer)
+		defq->btimelimit = dqp->q_blk.timer;
+	if (dqp->q_ino.timer)
+		defq->itimelimit = dqp->q_ino.timer;
+	if (dqp->q_rtb.timer)
+		defq->rtbtimelimit = dqp->q_rtb.timer;
 	if (dqp->q_blk.warnings)
 		defq->bwarnlimit = dqp->q_blk.warnings;
 	if (dqp->q_ino.warnings)
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 5d3bccdbd3bf..1b2b70b1660f 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -447,7 +447,6 @@ xfs_qm_scall_setqlim(
 	struct qc_dqblk		*newlim)
 {
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
-	struct xfs_disk_dquot	*ddq;
 	struct xfs_dquot	*dqp;
 	struct xfs_trans	*tp;
 	struct xfs_def_quota	*defq;
@@ -488,7 +487,6 @@ xfs_qm_scall_setqlim(
 
 	xfs_dqlock(dqp);
 	xfs_trans_dqjoin(tp, dqp);
-	ddq = &dqp->q_core;
 
 	/*
 	 * Make sure that hardlimits are >= soft limits before changing.
@@ -573,11 +571,11 @@ xfs_qm_scall_setqlim(
 	 * the soft limit.
 	 */
 	if (newlim->d_fieldmask & QC_SPC_TIMER)
-		ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer);
+		dqp->q_blk.timer = newlim->d_spc_timer;
 	if (newlim->d_fieldmask & QC_INO_TIMER)
-		ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer);
+		dqp->q_ino.timer = newlim->d_ino_timer;
 	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
-		ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer);
+		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
 
 	if (id == 0) {
 		if (newlim->d_fieldmask & QC_SPC_TIMER)
@@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc(
 	memset(dst, 0, sizeof(*dst));
 	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
 	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
-	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
-	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
+	dst->d_ino_hardlimit = dqp->q_ino.hardlimit;
+	dst->d_ino_softlimit = dqp->q_ino.softlimit;
 	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
 	dst->d_ino_count = dqp->q_ino.reserved;
-	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
-	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
+	dst->d_spc_timer = dqp->q_blk.timer;
+	dst->d_ino_timer = dqp->q_ino.timer;
 	dst->d_ino_warns = dqp->q_ino.warnings;
 	dst->d_spc_warns = dqp->q_blk.warnings;
 	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
 	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
 	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
-	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
+	dst->d_rt_spc_timer = dqp->q_rtb.timer;
 	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
 
 	/*
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 21ed8eda3c80..28b59a4069a3 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -591,7 +591,7 @@ xfs_trans_dqresv(
 		softlimit = dqp->q_blk.softlimit;
 		if (!softlimit)
 			softlimit = defq->bsoftlimit;
-		timer = be32_to_cpu(dqp->q_core.d_btimer);
+		timer = dqp->q_blk.timer;
 		warns = dqp->q_blk.warnings;
 		warnlimit = defq->bwarnlimit;
 		resbcountp = &dqp->q_blk.reserved;
@@ -603,7 +603,7 @@ xfs_trans_dqresv(
 		softlimit = dqp->q_rtb.softlimit;
 		if (!softlimit)
 			softlimit = defq->rtbsoftlimit;
-		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
+		timer = dqp->q_rtb.timer;
 		warns = dqp->q_rtb.warnings;
 		warnlimit = defq->rtbwarnlimit;
 		resbcountp = &dqp->q_rtb.reserved;
@@ -638,7 +638,7 @@ xfs_trans_dqresv(
 		}
 		if (ninos > 0) {
 			total_count = dqp->q_ino.reserved + ninos;
-			timer = be32_to_cpu(dqp->q_core.d_itimer);
+			timer = dqp->q_ino.timer;
 			warns = dqp->q_ino.warnings;
 			warnlimit = defq->iwarnlimit;
 			hardlimit = dqp->q_ino.hardlimit;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (9 preceding siblings ...)
  2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
                     ` (3 more replies)
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
                   ` (6 subsequent siblings)
  17 siblings, 4 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Now that we've stopped using qcore entirely, drop it from the incore
dquot.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/scrub/quota.c |    4 ----
 fs/xfs/xfs_dquot.c   |   29 +++++++++--------------------
 fs/xfs/xfs_dquot.h   |    1 -
 3 files changed, 9 insertions(+), 25 deletions(-)


diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
index 2fc2625feca0..f4aad5b00188 100644
--- a/fs/xfs/scrub/quota.c
+++ b/fs/xfs/scrub/quota.c
@@ -79,7 +79,6 @@ xchk_quota_item(
 	struct xchk_quota_info	*sqi = priv;
 	struct xfs_scrub	*sc = sqi->sc;
 	struct xfs_mount	*mp = sc->mp;
-	struct xfs_disk_dquot	*d = &dq->q_core;
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 	xfs_fileoff_t		offset;
 	xfs_ino_t		fs_icount;
@@ -98,9 +97,6 @@ xchk_quota_item(
 
 	sqi->last_id = dq->q_id;
 
-	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
-		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
-
 	/*
 	 * Warn if the hard limits are larger than the fs.
 	 * Administrators can do this, though in production this seems
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 7434ee57ec43..2d6b50760962 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -529,7 +529,6 @@ xfs_dquot_from_disk(
 	}
 
 	/* copy everything from disk dquot to the incore dquot */
-	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
 	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
 	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
 	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
@@ -568,8 +567,13 @@ xfs_dquot_to_disk(
 	struct xfs_disk_dquot	*ddqp,
 	struct xfs_dquot	*dqp)
 {
-	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
+	ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
+	ddqp->d_version = XFS_DQUOT_VERSION;
 	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
+	ddqp->d_id = cpu_to_be32(dqp->q_id);
+	ddqp->d_pad0 = 0;
+	ddqp->d_pad = 0;
+
 	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
 	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
 	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
@@ -1180,7 +1184,6 @@ xfs_qm_dqflush(
 	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
 	struct xfs_buf		*bp;
 	struct xfs_dqblk	*dqb;
-	struct xfs_disk_dquot	*ddqp;
 	xfs_failaddr_t		fa;
 	int			error;
 
@@ -1204,22 +1207,6 @@ xfs_qm_dqflush(
 	if (error)
 		goto out_abort;
 
-	/*
-	 * Calculate the location of the dquot inside the buffer.
-	 */
-	dqb = bp->b_addr + dqp->q_bufoffset;
-	ddqp = &dqb->dd_diskdq;
-
-	/* sanity check the in-core structure before we flush */
-	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
-	if (fa) {
-		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
-				dqp->q_id, fa);
-		xfs_buf_relse(bp);
-		error = -EFSCORRUPTED;
-		goto out_abort;
-	}
-
 	fa = xfs_qm_dqflush_check(dqp);
 	if (fa) {
 		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
@@ -1229,7 +1216,9 @@ xfs_qm_dqflush(
 		goto out_abort;
 	}
 
-	xfs_dquot_to_disk(ddqp, dqp);
+	/* Flush the incore dquot to the ondisk buffer. */
+	dqb = bp->b_addr + dqp->q_bufoffset;
+	xfs_dquot_to_disk(&dqb->dd_diskdq, dqp);
 
 	/*
 	 * Clear the dirty field and remember the flush lsn for later use.
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 414bae537b1d..62b0fc6e0133 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -71,7 +71,6 @@ struct xfs_dquot {
 	struct xfs_dquot_res	q_ino;	/* inodes */
 	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
 
-	struct xfs_disk_dquot	q_core;
 	struct xfs_dq_logitem	q_logitem;
 
 	xfs_qcnt_t		q_prealloc_lo_wmark;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (10 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-01  8:52   ` Chandan Babu R
                     ` (3 more replies)
  2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
                   ` (5 subsequent siblings)
  17 siblings, 4 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Now that we've split up the dquot resource fields into separate structs,
do the same for the default limits to enable further refactoring.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c       |   30 +++++++++++++++---------------
 fs/xfs/xfs_qm.c          |   36 ++++++++++++++++++------------------
 fs/xfs/xfs_qm.h          |   22 ++++++++++------------
 fs/xfs/xfs_qm_syscalls.c |   24 ++++++++++++------------
 fs/xfs/xfs_quotaops.c    |   12 ++++++------
 fs/xfs/xfs_trans_dquot.c |   18 +++++++++---------
 6 files changed, 70 insertions(+), 72 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 2d6b50760962..6975c27145fc 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits(
 	ASSERT(dq->q_id);
 	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
 
-	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
-		dq->q_blk.softlimit = defq->bsoftlimit;
+	if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) {
+		dq->q_blk.softlimit = defq->dfq_blk.softlimit;
 		prealloc = 1;
 	}
-	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
-		dq->q_blk.hardlimit = defq->bhardlimit;
+	if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) {
+		dq->q_blk.hardlimit = defq->dfq_blk.hardlimit;
 		prealloc = 1;
 	}
-	if (defq->isoftlimit && !dq->q_ino.softlimit)
-		dq->q_ino.softlimit = defq->isoftlimit;
-	if (defq->ihardlimit && !dq->q_ino.hardlimit)
-		dq->q_ino.hardlimit = defq->ihardlimit;
-	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
-		dq->q_rtb.softlimit = defq->rtbsoftlimit;
-	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
-		dq->q_rtb.hardlimit = defq->rtbhardlimit;
+	if (defq->dfq_ino.softlimit && !dq->q_ino.softlimit)
+		dq->q_ino.softlimit = defq->dfq_ino.softlimit;
+	if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit)
+		dq->q_ino.hardlimit = defq->dfq_ino.hardlimit;
+	if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit)
+		dq->q_rtb.softlimit = defq->dfq_rtb.softlimit;
+	if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit)
+		dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit;
 
 	if (prealloc)
 		xfs_dquot_set_prealloc_limits(dq);
@@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers(
 		    (dq->q_blk.hardlimit &&
 		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
 			dq->q_blk.timer = ktime_get_real_seconds() +
-					defq->btimelimit;
+					defq->dfq_blk.timelimit;
 		} else {
 			dq->q_blk.warnings = 0;
 		}
@@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers(
 		    (dq->q_ino.hardlimit &&
 		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
 			dq->q_ino.timer = ktime_get_real_seconds() +
-					defq->itimelimit;
+					defq->dfq_ino.timelimit;
 		} else {
 			dq->q_ino.warnings = 0;
 		}
@@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers(
 		    (dq->q_rtb.hardlimit &&
 		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
 			dq->q_rtb.timer = ktime_get_real_seconds() +
-					defq->rtbtimelimit;
+					defq->dfq_rtb.timelimit;
 		} else {
 			dq->q_rtb.warnings = 0;
 		}
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index a56c6e4a5d99..28326a6264a8 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -562,12 +562,12 @@ xfs_qm_set_defquota(
 	 * Timers and warnings have been already set, let's just set the
 	 * default limits for this quota type
 	 */
-	defq->bhardlimit = dqp->q_blk.hardlimit;
-	defq->bsoftlimit = dqp->q_blk.softlimit;
-	defq->ihardlimit = dqp->q_ino.hardlimit;
-	defq->isoftlimit = dqp->q_ino.softlimit;
-	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
-	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
+	defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit;
+	defq->dfq_blk.softlimit = dqp->q_blk.softlimit;
+	defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit;
+	defq->dfq_ino.softlimit = dqp->q_ino.softlimit;
+	defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit;
+	defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit;
 	xfs_qm_dqdestroy(dqp);
 }
 
@@ -584,12 +584,12 @@ xfs_qm_init_timelimits(
 
 	defq = xfs_get_defquota(qinf, type);
 
-	defq->btimelimit = XFS_QM_BTIMELIMIT;
-	defq->itimelimit = XFS_QM_ITIMELIMIT;
-	defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT;
-	defq->bwarnlimit = XFS_QM_BWARNLIMIT;
-	defq->iwarnlimit = XFS_QM_IWARNLIMIT;
-	defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
+	defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT;
+	defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT;
+	defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT;
+	defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT;
+	defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT;
+	defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT;
 
 	/*
 	 * We try to get the limits from the superuser's limits fields.
@@ -608,17 +608,17 @@ xfs_qm_init_timelimits(
 	 * more writing. If it is zero, a default is used.
 	 */
 	if (dqp->q_blk.timer)
-		defq->btimelimit = dqp->q_blk.timer;
+		defq->dfq_blk.timelimit = dqp->q_blk.timer;
 	if (dqp->q_ino.timer)
-		defq->itimelimit = dqp->q_ino.timer;
+		defq->dfq_ino.timelimit = dqp->q_ino.timer;
 	if (dqp->q_rtb.timer)
-		defq->rtbtimelimit = dqp->q_rtb.timer;
+		defq->dfq_rtb.timelimit = dqp->q_rtb.timer;
 	if (dqp->q_blk.warnings)
-		defq->bwarnlimit = dqp->q_blk.warnings;
+		defq->dfq_blk.warnlimit = dqp->q_blk.warnings;
 	if (dqp->q_ino.warnings)
-		defq->iwarnlimit = dqp->q_ino.warnings;
+		defq->dfq_ino.warnlimit = dqp->q_ino.warnings;
 	if (dqp->q_rtb.warnings)
-		defq->rtbwarnlimit = dqp->q_rtb.warnings;
+		defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings;
 
 	xfs_qm_dqdestroy(dqp);
 }
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
index 6ed4ae942603..e2f0027f0ac1 100644
--- a/fs/xfs/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -41,20 +41,18 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
  */
 #define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
 
+struct xfs_def_qres {
+	xfs_qcnt_t		hardlimit;	/* default hard limit */
+	xfs_qcnt_t		softlimit;	/* default soft limit */
+	time64_t		timelimit;	/* limit for timers */
+	xfs_qwarncnt_t		warnlimit;	/* limit for warnings */
+};
+
 /* Defaults for each quota type: time limits, warn limits, usage limits */
 struct xfs_def_quota {
-	time64_t	btimelimit;	/* limit for blks timer */
-	time64_t	itimelimit;	/* limit for inodes timer */
-	time64_t	rtbtimelimit;	/* limit for rt blks timer */
-	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
-	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
-	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
-	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
-	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
-	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
-	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
-	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
-	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
+	struct xfs_def_qres	dfq_blk;
+	struct xfs_def_qres	dfq_ino;
+	struct xfs_def_qres	dfq_rtb;
 };
 
 /*
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 1b2b70b1660f..393b88612cc8 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -502,8 +502,8 @@ xfs_qm_scall_setqlim(
 		dqp->q_blk.softlimit = soft;
 		xfs_dquot_set_prealloc_limits(dqp);
 		if (id == 0) {
-			defq->bhardlimit = hard;
-			defq->bsoftlimit = soft;
+			defq->dfq_blk.hardlimit = hard;
+			defq->dfq_blk.softlimit = soft;
 		}
 	} else {
 		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
@@ -518,8 +518,8 @@ xfs_qm_scall_setqlim(
 		dqp->q_rtb.hardlimit = hard;
 		dqp->q_rtb.softlimit = soft;
 		if (id == 0) {
-			defq->rtbhardlimit = hard;
-			defq->rtbsoftlimit = soft;
+			defq->dfq_rtb.hardlimit = hard;
+			defq->dfq_rtb.softlimit = soft;
 		}
 	} else {
 		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
@@ -535,8 +535,8 @@ xfs_qm_scall_setqlim(
 		dqp->q_ino.hardlimit = hard;
 		dqp->q_ino.softlimit = soft;
 		if (id == 0) {
-			defq->ihardlimit = hard;
-			defq->isoftlimit = soft;
+			defq->dfq_ino.hardlimit = hard;
+			defq->dfq_ino.softlimit = soft;
 		}
 	} else {
 		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
@@ -554,11 +554,11 @@ xfs_qm_scall_setqlim(
 
 	if (id == 0) {
 		if (newlim->d_fieldmask & QC_SPC_WARNS)
-			defq->bwarnlimit = newlim->d_spc_warns;
+			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
 		if (newlim->d_fieldmask & QC_INO_WARNS)
-			defq->iwarnlimit = newlim->d_ino_warns;
+			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
 		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
-			defq->rtbwarnlimit = newlim->d_rt_spc_warns;
+			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
 	}
 
 	/*
@@ -579,11 +579,11 @@ xfs_qm_scall_setqlim(
 
 	if (id == 0) {
 		if (newlim->d_fieldmask & QC_SPC_TIMER)
-			defq->btimelimit = newlim->d_spc_timer;
+			defq->dfq_blk.timelimit = newlim->d_spc_timer;
 		if (newlim->d_fieldmask & QC_INO_TIMER)
-			defq->itimelimit = newlim->d_ino_timer;
+			defq->dfq_ino.timelimit = newlim->d_ino_timer;
 		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
-			defq->rtbtimelimit = newlim->d_rt_spc_timer;
+			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
 	}
 
 	if (id != 0) {
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index bf809b77a316..c86a6fe263da 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -37,12 +37,12 @@ xfs_qm_fill_state(
 	tstate->flags |= QCI_SYSFILE;
 	tstate->blocks = ip->i_d.di_nblocks;
 	tstate->nextents = ip->i_df.if_nextents;
-	tstate->spc_timelimit = (u32)defq->btimelimit;
-	tstate->ino_timelimit = (u32)defq->itimelimit;
-	tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit;
-	tstate->spc_warnlimit = defq->bwarnlimit;
-	tstate->ino_warnlimit = defq->iwarnlimit;
-	tstate->rt_spc_warnlimit = defq->rtbwarnlimit;
+	tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit;
+	tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit;
+	tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit;
+	tstate->spc_warnlimit = defq->dfq_blk.warnlimit;
+	tstate->ino_warnlimit = defq->dfq_ino.warnlimit;
+	tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit;
 	if (tempqip)
 		xfs_irele(ip);
 }
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 28b59a4069a3..392e51baad6f 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -587,25 +587,25 @@ xfs_trans_dqresv(
 	if (flags & XFS_TRANS_DQ_RES_BLKS) {
 		hardlimit = dqp->q_blk.hardlimit;
 		if (!hardlimit)
-			hardlimit = defq->bhardlimit;
+			hardlimit = defq->dfq_blk.hardlimit;
 		softlimit = dqp->q_blk.softlimit;
 		if (!softlimit)
-			softlimit = defq->bsoftlimit;
+			softlimit = defq->dfq_blk.softlimit;
 		timer = dqp->q_blk.timer;
 		warns = dqp->q_blk.warnings;
-		warnlimit = defq->bwarnlimit;
+		warnlimit = defq->dfq_blk.warnlimit;
 		resbcountp = &dqp->q_blk.reserved;
 	} else {
 		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
 		hardlimit = dqp->q_rtb.hardlimit;
 		if (!hardlimit)
-			hardlimit = defq->rtbhardlimit;
+			hardlimit = defq->dfq_rtb.hardlimit;
 		softlimit = dqp->q_rtb.softlimit;
 		if (!softlimit)
-			softlimit = defq->rtbsoftlimit;
+			softlimit = defq->dfq_rtb.softlimit;
 		timer = dqp->q_rtb.timer;
 		warns = dqp->q_rtb.warnings;
-		warnlimit = defq->rtbwarnlimit;
+		warnlimit = defq->dfq_rtb.warnlimit;
 		resbcountp = &dqp->q_rtb.reserved;
 	}
 
@@ -640,13 +640,13 @@ xfs_trans_dqresv(
 			total_count = dqp->q_ino.reserved + ninos;
 			timer = dqp->q_ino.timer;
 			warns = dqp->q_ino.warnings;
-			warnlimit = defq->iwarnlimit;
+			warnlimit = defq->dfq_ino.warnlimit;
 			hardlimit = dqp->q_ino.hardlimit;
 			if (!hardlimit)
-				hardlimit = defq->ihardlimit;
+				hardlimit = defq->dfq_ino.hardlimit;
 			softlimit = dqp->q_ino.softlimit;
 			if (!softlimit)
-				softlimit = defq->isoftlimit;
+				softlimit = defq->dfq_ino.softlimit;
 
 			if (hardlimit && total_count > hardlimit) {
 				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (11 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-01  8:53   ` Christoph Hellwig
                     ` (2 more replies)
  2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
                   ` (4 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

struct xfs_dquot already has a pointer to the xfs mount, so remove the
redundant parameter from xfs_qm_adjust_dq*.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c       |    4 ++--
 fs/xfs/xfs_dquot.h       |    6 ++----
 fs/xfs/xfs_qm.c          |    4 ++--
 fs/xfs/xfs_qm_syscalls.c |    2 +-
 fs/xfs/xfs_trans_dquot.c |    4 ++--
 5 files changed, 9 insertions(+), 11 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 6975c27145fc..35a113d1b42b 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -66,9 +66,9 @@ xfs_qm_dqdestroy(
  */
 void
 xfs_qm_adjust_dqlimits(
-	struct xfs_mount	*mp,
 	struct xfs_dquot	*dq)
 {
+	struct xfs_mount	*mp = dq->q_mount;
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
 	struct xfs_def_quota	*defq;
 	int			prealloc = 0;
@@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits(
  */
 void
 xfs_qm_adjust_dqtimers(
-	struct xfs_mount	*mp,
 	struct xfs_dquot	*dq)
 {
+	struct xfs_mount	*mp = dq->q_mount;
 	struct xfs_quotainfo	*qi = mp->m_quotainfo;
 	struct xfs_def_quota	*defq;
 
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 62b0fc6e0133..e37b4bebc1ea 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
 void		xfs_qm_dqdestroy(struct xfs_dquot *dqp);
 int		xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
 void		xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
-void		xfs_qm_adjust_dqtimers(struct xfs_mount *mp,
-						struct xfs_dquot *d);
-void		xfs_qm_adjust_dqlimits(struct xfs_mount *mp,
-						struct xfs_dquot *d);
+void		xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
+void		xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
 xfs_dqid_t	xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type);
 int		xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
 					uint type, bool can_alloc,
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 28326a6264a8..30deb6cf6a7a 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust(
 	 * There are no timers for the default values set in the root dquot.
 	 */
 	if (dqp->q_id) {
-		xfs_qm_adjust_dqlimits(mp, dqp);
-		xfs_qm_adjust_dqtimers(mp, dqp);
+		xfs_qm_adjust_dqlimits(dqp);
+		xfs_qm_adjust_dqtimers(dqp);
 	}
 
 	dqp->dq_flags |= XFS_DQ_DIRTY;
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 393b88612cc8..5423e02f9837 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -594,7 +594,7 @@ xfs_qm_scall_setqlim(
 		 * is on or off. We don't really want to bother with iterating
 		 * over all ondisk dquots and turning the timers on/off.
 		 */
-		xfs_qm_adjust_dqtimers(mp, dqp);
+		xfs_qm_adjust_dqtimers(dqp);
 	}
 	dqp->dq_flags |= XFS_DQ_DIRTY;
 	xfs_trans_log_dquot(tp, dqp);
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 392e51baad6f..2712814d696d 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas(
 			 * Start/reset the timer(s) if needed.
 			 */
 			if (dqp->q_id) {
-				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
-				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
+				xfs_qm_adjust_dqlimits(dqp);
+				xfs_qm_adjust_dqtimers(dqp);
 			}
 
 			dqp->dq_flags |= XFS_DQ_DIRTY;


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 14/18] xfs: refactor quota exceeded test
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (12 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
                     ` (2 more replies)
  2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
                   ` (3 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Refactor the open-coded test for whether or not we're over quota.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
 1 file changed, 30 insertions(+), 65 deletions(-)


diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 35a113d1b42b..ef34c82c28a0 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
 		xfs_dquot_set_prealloc_limits(dq);
 }
 
+/*
+ * Determine if this quota counter is over either limit and set the quota
+ * timers as appropriate.
+ */
+static inline void
+xfs_qm_adjust_res_timer(
+	struct xfs_dquot_res	*res,
+	struct xfs_def_qres	*dres)
+{
+	bool			over;
+
+#ifdef DEBUG
+	if (res->hardlimit)
+		ASSERT(res->softlimit <= res->hardlimit);
+#endif
+
+	over = (res->softlimit && res->count > res->softlimit) ||
+	       (res->hardlimit && res->count > res->hardlimit);
+
+	if (over && res->timer == 0)
+		res->timer = ktime_get_real_seconds() + dres->timelimit;
+	else if (!over && res->timer != 0)
+		res->timer = 0;
+	else if (!over && res->timer == 0)
+		res->warnings = 0;
+}
+
 /*
  * Check the limits and timers of a dquot and start or reset timers
  * if necessary.
@@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers(
 	ASSERT(dq->q_id);
 	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
 
-#ifdef DEBUG
-	if (dq->q_blk.hardlimit)
-		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
-	if (dq->q_ino.hardlimit)
-		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
-	if (dq->q_rtb.hardlimit)
-		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
-#endif
-
-	if (!dq->q_blk.timer) {
-		if ((dq->q_blk.softlimit &&
-		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
-		    (dq->q_blk.hardlimit &&
-		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
-			dq->q_blk.timer = ktime_get_real_seconds() +
-					defq->dfq_blk.timelimit;
-		} else {
-			dq->q_blk.warnings = 0;
-		}
-	} else {
-		if ((!dq->q_blk.softlimit ||
-		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
-		    (!dq->q_blk.hardlimit ||
-		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
-			dq->q_blk.timer = 0;
-		}
-	}
-
-	if (!dq->q_ino.timer) {
-		if ((dq->q_ino.softlimit &&
-		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
-		    (dq->q_ino.hardlimit &&
-		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
-			dq->q_ino.timer = ktime_get_real_seconds() +
-					defq->dfq_ino.timelimit;
-		} else {
-			dq->q_ino.warnings = 0;
-		}
-	} else {
-		if ((!dq->q_ino.softlimit ||
-		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
-		    (!dq->q_ino.hardlimit ||
-		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
-			dq->q_ino.timer = 0;
-		}
-	}
-
-	if (!dq->q_rtb.timer) {
-		if ((dq->q_rtb.softlimit &&
-		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
-		    (dq->q_rtb.hardlimit &&
-		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
-			dq->q_rtb.timer = ktime_get_real_seconds() +
-					defq->dfq_rtb.timelimit;
-		} else {
-			dq->q_rtb.warnings = 0;
-		}
-	} else {
-		if ((!dq->q_rtb.softlimit ||
-		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
-		    (!dq->q_rtb.hardlimit ||
-		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
-			dq->q_rtb.timer = 0;
-		}
-	}
+	xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk);
+	xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino);
+	xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb);
 }
 
 /*


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (13 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
                     ` (2 more replies)
  2020-06-30 15:43 ` [PATCH 16/18] xfs: refactor xfs_trans_dqresv Darrick J. Wong
                   ` (2 subsequent siblings)
  17 siblings, 3 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Now that we can pass around quota resource and limit structures, clean
up the open-coded field setting in xfs_qm_scall_setqlim.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_qm_syscalls.c |  164 ++++++++++++++++++++++++++--------------------
 1 file changed, 93 insertions(+), 71 deletions(-)


diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 5423e02f9837..5044c333af5c 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -436,6 +436,58 @@ xfs_qm_scall_quotaon(
 #define XFS_QC_MASK \
 	(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
 
+/*
+ * Adjust limits of this quota, and the defaults if passed in.  Returns true
+ * if the new limits made sense and were applied, false otherwise.
+ */
+static inline bool
+xfs_setqlim_limits(
+	struct xfs_mount	*mp,
+	struct xfs_dquot_res	*res,
+	struct xfs_def_qres	*dres,
+	xfs_qcnt_t		hard,
+	xfs_qcnt_t		soft,
+	const char		*tag)
+{
+	/* The hard limit can't be less than the soft limit. */
+	if (hard != 0 && hard < soft) {
+		xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag,
+				soft);
+		return false;
+	}
+
+	res->hardlimit = hard;
+	res->softlimit = soft;
+	if (dres) {
+		dres->hardlimit = hard;
+		dres->softlimit = soft;
+	}
+
+	return true;
+}
+
+static inline void
+xfs_setqlim_warns(
+	struct xfs_dquot_res	*res,
+	struct xfs_def_qres	*dres,
+	int			warns)
+{
+	res->warnings = warns;
+	if (dres)
+		dres->warnlimit = warns;
+}
+
+static inline void
+xfs_setqlim_timer(
+	struct xfs_dquot_res	*res,
+	struct xfs_def_qres	*dres,
+	s64			timer)
+{
+	res->timer = timer;
+	if (dres)
+		dres->timelimit = timer;
+}
+
 /*
  * Adjust quota limits, and start/stop timers accordingly.
  */
@@ -450,6 +502,8 @@ xfs_qm_scall_setqlim(
 	struct xfs_dquot	*dqp;
 	struct xfs_trans	*tp;
 	struct xfs_def_quota	*defq;
+	struct xfs_dquot_res	*res;
+	struct xfs_def_qres	*dres;
 	int			error;
 	xfs_qcnt_t		hard, soft;
 
@@ -489,102 +543,70 @@ xfs_qm_scall_setqlim(
 	xfs_trans_dqjoin(tp, dqp);
 
 	/*
+	 * Update quota limits, warnings, and timers, and the defaults
+	 * if we're touching id == 0.
+	 *
 	 * Make sure that hardlimits are >= soft limits before changing.
+	 *
+	 * Update warnings counter(s) if requested.
+	 *
+	 * Timelimits for the super user set the relative time the other users
+	 * can be over quota for this file system. If it is zero a default is
+	 * used.  Ditto for the default soft and hard limit values (already
+	 * done, above), and for warnings.
+	 *
+	 * For other IDs, userspace can bump out the grace period if over
+	 * the soft limit.
 	 */
+
+	/* Blocks on the data device. */
 	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
 			dqp->q_blk.hardlimit;
 	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
 			dqp->q_blk.softlimit;
-	if (hard == 0 || hard >= soft) {
-		dqp->q_blk.hardlimit = hard;
-		dqp->q_blk.softlimit = soft;
+	res = &dqp->q_blk;
+	dres = id == 0 ? &defq->dfq_blk : NULL;
+
+	if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk"))
 		xfs_dquot_set_prealloc_limits(dqp);
-		if (id == 0) {
-			defq->dfq_blk.hardlimit = hard;
-			defq->dfq_blk.softlimit = soft;
-		}
-	} else {
-		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
-	}
+	if (newlim->d_fieldmask & QC_SPC_WARNS)
+		xfs_setqlim_warns(res, dres, newlim->d_spc_warns);
+	if (newlim->d_fieldmask & QC_SPC_TIMER)
+		xfs_setqlim_timer(res, dres, newlim->d_spc_timer);
+
+	/* Blocks on the realtime device. */
 	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
 			dqp->q_rtb.hardlimit;
 	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
 		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
 			dqp->q_rtb.softlimit;
-	if (hard == 0 || hard >= soft) {
-		dqp->q_rtb.hardlimit = hard;
-		dqp->q_rtb.softlimit = soft;
-		if (id == 0) {
-			defq->dfq_rtb.hardlimit = hard;
-			defq->dfq_rtb.softlimit = soft;
-		}
-	} else {
-		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
-	}
+	res = &dqp->q_rtb;
+	dres = id == 0 ? &defq->dfq_rtb : NULL;
 
+	xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb");
+	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
+		xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns);
+	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
+		xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer);
+
+	/* Inodes */
 	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
 		(xfs_qcnt_t) newlim->d_ino_hardlimit :
 			dqp->q_ino.hardlimit;
 	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
 		(xfs_qcnt_t) newlim->d_ino_softlimit :
 			dqp->q_ino.softlimit;
-	if (hard == 0 || hard >= soft) {
-		dqp->q_ino.hardlimit = hard;
-		dqp->q_ino.softlimit = soft;
-		if (id == 0) {
-			defq->dfq_ino.hardlimit = hard;
-			defq->dfq_ino.softlimit = soft;
-		}
-	} else {
-		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
-	}
+	res = &dqp->q_ino;
+	dres = id == 0 ? &defq->dfq_ino : NULL;
 
-	/*
-	 * Update warnings counter(s) if requested
-	 */
-	if (newlim->d_fieldmask & QC_SPC_WARNS)
-		dqp->q_blk.warnings = newlim->d_spc_warns;
+	xfs_setqlim_limits(mp, res, dres, hard, soft, "ino");
 	if (newlim->d_fieldmask & QC_INO_WARNS)
-		dqp->q_ino.warnings = newlim->d_ino_warns;
-	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
-		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
-
-	if (id == 0) {
-		if (newlim->d_fieldmask & QC_SPC_WARNS)
-			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
-		if (newlim->d_fieldmask & QC_INO_WARNS)
-			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
-		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
-			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
-	}
-
-	/*
-	 * Timelimits for the super user set the relative time the other users
-	 * can be over quota for this file system. If it is zero a default is
-	 * used.  Ditto for the default soft and hard limit values (already
-	 * done, above), and for warnings.
-	 *
-	 * For other IDs, userspace can bump out the grace period if over
-	 * the soft limit.
-	 */
-	if (newlim->d_fieldmask & QC_SPC_TIMER)
-		dqp->q_blk.timer = newlim->d_spc_timer;
+		xfs_setqlim_warns(res, dres, newlim->d_ino_warns);
 	if (newlim->d_fieldmask & QC_INO_TIMER)
-		dqp->q_ino.timer = newlim->d_ino_timer;
-	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
-		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
-
-	if (id == 0) {
-		if (newlim->d_fieldmask & QC_SPC_TIMER)
-			defq->dfq_blk.timelimit = newlim->d_spc_timer;
-		if (newlim->d_fieldmask & QC_INO_TIMER)
-			defq->dfq_ino.timelimit = newlim->d_ino_timer;
-		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
-			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
-	}
+		xfs_setqlim_timer(res, dres, newlim->d_ino_timer);
 
 	if (id != 0) {
 		/*


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 16/18] xfs: refactor xfs_trans_dqresv
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (14 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-03  4:11   ` Allison Collins
  2020-07-03 13:00   ` Chandan Babu R
  2020-06-30 15:43 ` [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas Darrick J. Wong
  2020-06-30 15:43 ` [PATCH 18/18] xfs: add more dquot tracepoints Darrick J. Wong
  17 siblings, 2 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Now that we've refactored the resource usage and limits into
per-resource structures, we can refactor some of the open-coded
reservation limit checking in xfs_trans_dqresv.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_trans_dquot.c |  153 +++++++++++++++++++++++-----------------------
 1 file changed, 78 insertions(+), 75 deletions(-)


diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 2712814d696d..30a011dc9828 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -554,6 +554,58 @@ xfs_quota_warn(
 			   mp->m_super->s_dev, type);
 }
 
+/*
+ * Decide if we can make an additional reservation against a quota resource.
+ * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
+ *
+ * Note that we assume that the numeric difference between the inode and block
+ * warning codes will always be 3 since it's userspace ABI now, and will never
+ * decrease the quota reservation, so the *BELOW messages are irrelevant.
+ */
+static inline int
+xfs_dqresv_check(
+	struct xfs_dquot_res	*res,
+	struct xfs_def_qres	*dres,
+	int64_t			delta,
+	bool			*fatal)
+{
+	xfs_qcnt_t		hardlimit = res->hardlimit;
+	xfs_qcnt_t		softlimit = res->softlimit;
+	xfs_qcnt_t		total_count = res->reserved + delta;
+
+	BUILD_BUG_ON(QUOTA_NL_BHARDWARN     != QUOTA_NL_IHARDWARN + 3);
+	BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
+	BUILD_BUG_ON(QUOTA_NL_BSOFTWARN     != QUOTA_NL_ISOFTWARN + 3);
+
+	*fatal = false;
+	if (delta <= 0)
+		return QUOTA_NL_NOWARN;
+
+	if (!hardlimit)
+		hardlimit = dres->hardlimit;
+	if (!softlimit)
+		softlimit = dres->softlimit;
+
+	if (hardlimit && total_count > hardlimit) {
+		*fatal = true;
+		return QUOTA_NL_IHARDWARN;
+	}
+
+	if (softlimit && total_count > softlimit) {
+		time64_t	now = ktime_get_real_seconds();
+
+		if ((res->timer != 0 && now > res->timer) ||
+		    (res->warnings != 0 && res->warnings >= dres->warnlimit)) {
+			*fatal = true;
+			return QUOTA_NL_ISOFTLONGWARN;
+		}
+
+		return QUOTA_NL_ISOFTWARN;
+	}
+
+	return QUOTA_NL_NOWARN;
+}
+
 /*
  * This reserves disk blocks and inodes against a dquot.
  * Flags indicate if the dquot is to be locked here and also
@@ -569,99 +621,51 @@ xfs_trans_dqresv(
 	long			ninos,
 	uint			flags)
 {
-	xfs_qcnt_t		hardlimit;
-	xfs_qcnt_t		softlimit;
-	time64_t		timer;
-	xfs_qwarncnt_t		warns;
-	xfs_qwarncnt_t		warnlimit;
-	xfs_qcnt_t		total_count;
-	xfs_qcnt_t		*resbcountp;
 	struct xfs_quotainfo	*q = mp->m_quotainfo;
 	struct xfs_def_quota	*defq;
-
+	struct xfs_dquot_res	*blkres;
+	struct xfs_def_qres	*def_blkres;
 
 	xfs_dqlock(dqp);
 
 	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
 
 	if (flags & XFS_TRANS_DQ_RES_BLKS) {
-		hardlimit = dqp->q_blk.hardlimit;
-		if (!hardlimit)
-			hardlimit = defq->dfq_blk.hardlimit;
-		softlimit = dqp->q_blk.softlimit;
-		if (!softlimit)
-			softlimit = defq->dfq_blk.softlimit;
-		timer = dqp->q_blk.timer;
-		warns = dqp->q_blk.warnings;
-		warnlimit = defq->dfq_blk.warnlimit;
-		resbcountp = &dqp->q_blk.reserved;
+		blkres = &dqp->q_blk;
+		def_blkres = &defq->dfq_blk;
 	} else {
-		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
-		hardlimit = dqp->q_rtb.hardlimit;
-		if (!hardlimit)
-			hardlimit = defq->dfq_rtb.hardlimit;
-		softlimit = dqp->q_rtb.softlimit;
-		if (!softlimit)
-			softlimit = defq->dfq_rtb.softlimit;
-		timer = dqp->q_rtb.timer;
-		warns = dqp->q_rtb.warnings;
-		warnlimit = defq->dfq_rtb.warnlimit;
-		resbcountp = &dqp->q_rtb.reserved;
+		blkres = &dqp->q_rtb;
+		def_blkres = &defq->dfq_rtb;
 	}
 
 	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
 	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
 	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
 	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
-		if (nblks > 0) {
+		int		quota_nl;
+		bool		fatal;
+
+		/*
+		 * dquot is locked already. See if we'd go over the hardlimit
+		 * or exceed the timelimit if we'd reserve resources.
+		 */
+		quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal);
+		if (quota_nl != QUOTA_NL_NOWARN) {
 			/*
-			 * dquot is locked already. See if we'd go over the
-			 * hardlimit or exceed the timelimit if we allocate
-			 * nblks.
+			 * Quota block warning codes are 3 more than the inode
+			 * codes, which we check above.
 			 */
-			total_count = *resbcountp + nblks;
-			if (hardlimit && total_count > hardlimit) {
-				xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
+			xfs_quota_warn(mp, dqp, quota_nl + 3);
+			if (fatal)
 				goto error_return;
-			}
-			if (softlimit && total_count > softlimit) {
-				if ((timer != 0 &&
-				     ktime_get_real_seconds() > timer) ||
-				    (warns != 0 && warns >= warnlimit)) {
-					xfs_quota_warn(mp, dqp,
-						       QUOTA_NL_BSOFTLONGWARN);
-					goto error_return;
-				}
-
-				xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
-			}
 		}
-		if (ninos > 0) {
-			total_count = dqp->q_ino.reserved + ninos;
-			timer = dqp->q_ino.timer;
-			warns = dqp->q_ino.warnings;
-			warnlimit = defq->dfq_ino.warnlimit;
-			hardlimit = dqp->q_ino.hardlimit;
-			if (!hardlimit)
-				hardlimit = defq->dfq_ino.hardlimit;
-			softlimit = dqp->q_ino.softlimit;
-			if (!softlimit)
-				softlimit = defq->dfq_ino.softlimit;
 
-			if (hardlimit && total_count > hardlimit) {
-				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
+		quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos,
+				&fatal);
+		if (quota_nl != QUOTA_NL_NOWARN) {
+			xfs_quota_warn(mp, dqp, quota_nl);
+			if (fatal)
 				goto error_return;
-			}
-			if (softlimit && total_count > softlimit) {
-				if  ((timer != 0 &&
-				      ktime_get_real_seconds() > timer) ||
-				     (warns != 0 && warns >= warnlimit)) {
-					xfs_quota_warn(mp, dqp,
-						       QUOTA_NL_ISOFTLONGWARN);
-					goto error_return;
-				}
-				xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
-			}
 		}
 	}
 
@@ -669,9 +673,8 @@ xfs_trans_dqresv(
 	 * Change the reservation, but not the actual usage.
 	 * Note that q_blk.reserved = q_blk.count + resv
 	 */
-	(*resbcountp) += (xfs_qcnt_t)nblks;
-	if (ninos != 0)
-		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
+	blkres->reserved += (xfs_qcnt_t)nblks;
+	dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
 
 	/*
 	 * note the reservation amt in the trans struct too,


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (15 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 16/18] xfs: refactor xfs_trans_dqresv Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-04 20:41   ` Allison Collins
  2020-07-06 13:40   ` Chandan Babu R
  2020-06-30 15:43 ` [PATCH 18/18] xfs: add more dquot tracepoints Darrick J. Wong
  17 siblings, 2 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Hoist the code that adjusts the incore quota reservation count
adjustments into a separate function, both to reduce the level of
indentation and also to reduce the amount of open-coded logic.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_trans_dquot.c |  103 +++++++++++++++++++++-------------------------
 1 file changed, 46 insertions(+), 57 deletions(-)


diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 30a011dc9828..701923ea6c04 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin(
 	}
 }
 
+/* Apply dqtrx changes to the quota reservation counters. */
+static inline void
+xfs_apply_quota_reservation_deltas(
+	struct xfs_dquot_res	*res,
+	uint64_t		reserved,
+	int64_t			res_used,
+	int64_t			count_delta)
+{
+	if (reserved != 0) {
+		/*
+		 * Subtle math here: If reserved > res_used (the normal case),
+		 * we're simply subtracting the unused transaction quota
+		 * reservation from the dquot reservation.
+		 *
+		 * If, however, res_used > reserved, then we have allocated
+		 * more quota blocks than were reserved for the transaction.
+		 * We must add that excess to the dquot reservation since it
+		 * tracks (usage + resv) and by definition we didn't reserve
+		 * that excess.
+		 */
+		res->reserved -= abs(reserved - res_used);
+	} else if (count_delta != 0) {
+		/*
+		 * These blks were never reserved, either inside a transaction
+		 * or outside one (in a delayed allocation). Also, this isn't
+		 * always a negative number since we sometimes deliberately
+		 * skip quota reservations.
+		 */
+		res->reserved += count_delta;
+	}
+}
 
 /*
  * Called by xfs_trans_commit() and similar in spirit to
@@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas(
 		xfs_trans_dqlockedjoin(tp, qa);
 
 		for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
+			uint64_t	blk_res_used;
+
 			qtrx = &qa[i];
 			/*
 			 * The array of dquots is filled
@@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas(
 			 * In case of delayed allocations, there's no
 			 * reservation that a transaction structure knows of.
 			 */
-			if (qtrx->qt_blk_res != 0) {
-				uint64_t	blk_res_used = 0;
+			blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
+			xfs_apply_quota_reservation_deltas(&dqp->q_blk,
+					qtrx->qt_blk_res, blk_res_used,
+					qtrx->qt_bcount_delta);
 
-				if (qtrx->qt_bcount_delta > 0)
-					blk_res_used = qtrx->qt_bcount_delta;
-
-				if (qtrx->qt_blk_res != blk_res_used) {
-					if (qtrx->qt_blk_res > blk_res_used)
-						dqp->q_blk.reserved -= (xfs_qcnt_t)
-							(qtrx->qt_blk_res -
-							 blk_res_used);
-					else
-						dqp->q_blk.reserved -= (xfs_qcnt_t)
-							(blk_res_used -
-							 qtrx->qt_blk_res);
-				}
-			} else {
-				/*
-				 * These blks were never reserved, either inside
-				 * a transaction or outside one (in a delayed
-				 * allocation). Also, this isn't always a
-				 * negative number since we sometimes
-				 * deliberately skip quota reservations.
-				 */
-				if (qtrx->qt_bcount_delta) {
-					dqp->q_blk.reserved +=
-					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
-				}
-			}
 			/*
 			 * Adjust the RT reservation.
 			 */
-			if (qtrx->qt_rtblk_res != 0) {
-				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
-					if (qtrx->qt_rtblk_res >
-					    qtrx->qt_rtblk_res_used)
-					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
-						       (qtrx->qt_rtblk_res -
-							qtrx->qt_rtblk_res_used);
-					else
-					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
-						       (qtrx->qt_rtblk_res_used -
-							qtrx->qt_rtblk_res);
-				}
-			} else {
-				if (qtrx->qt_rtbcount_delta)
-					dqp->q_rtb.reserved +=
-					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
-			}
+			xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
+					qtrx->qt_rtblk_res,
+					qtrx->qt_rtblk_res_used,
+					qtrx->qt_rtbcount_delta);
 
 			/*
 			 * Adjust the inode reservation.
 			 */
-			if (qtrx->qt_ino_res != 0) {
-				ASSERT(qtrx->qt_ino_res >=
-				       qtrx->qt_ino_res_used);
-				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
-					dqp->q_ino.reserved -= (xfs_qcnt_t)
-						(qtrx->qt_ino_res -
-						 qtrx->qt_ino_res_used);
-			} else {
-				if (qtrx->qt_icount_delta)
-					dqp->q_ino.reserved +=
-					    (xfs_qcnt_t)qtrx->qt_icount_delta;
-			}
+			ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
+			xfs_apply_quota_reservation_deltas(&dqp->q_ino,
+					qtrx->qt_ino_res,
+					qtrx->qt_ino_res_used,
+					qtrx->qt_icount_delta);
 
 			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
 			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 18/18] xfs: add more dquot tracepoints
  2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
                   ` (16 preceding siblings ...)
  2020-06-30 15:43 ` [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas Darrick J. Wong
@ 2020-06-30 15:43 ` Darrick J. Wong
  2020-07-04 20:41   ` Allison Collins
  2020-07-06 13:42   ` Chandan Babu R
  17 siblings, 2 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-06-30 15:43 UTC (permalink / raw)
  To: darrick.wong; +Cc: linux-xfs

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

Add all the xfs_dquot fields to the tracepoint for that type; add a new
tracepoint type for the qtrx structure (dquot transaction deltas); and
use our new tracepoints.  This makes it easier for the author to trace
changes to dquot counters for debugging.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_trace.h       |  140 +++++++++++++++++++++++++++++++++++++++++++++-
 fs/xfs/xfs_trans_dquot.c |   21 +++++++
 2 files changed, 159 insertions(+), 2 deletions(-)


diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 851f97dfe9e3..35b9dfd3984f 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -36,6 +36,7 @@ struct xfs_owner_info;
 struct xfs_trans_res;
 struct xfs_inobt_rec_incore;
 union xfs_btree_ptr;
+struct xfs_dqtrx;
 
 #define XFS_ATTR_FILTER_FLAGS \
 	{ XFS_ATTR_ROOT,	"ROOT" }, \
@@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
 		__field(unsigned, flags)
 		__field(unsigned, nrefs)
 		__field(unsigned long long, res_bcount)
+		__field(unsigned long long, res_rtbcount)
+		__field(unsigned long long, res_icount)
+
 		__field(unsigned long long, bcount)
+		__field(unsigned long long, rtbcount)
 		__field(unsigned long long, icount)
+
 		__field(unsigned long long, blk_hardlimit)
 		__field(unsigned long long, blk_softlimit)
+		__field(unsigned long long, rtb_hardlimit)
+		__field(unsigned long long, rtb_softlimit)
 		__field(unsigned long long, ino_hardlimit)
 		__field(unsigned long long, ino_softlimit)
-	), \
+	),
 	TP_fast_assign(
 		__entry->dev = dqp->q_mount->m_super->s_dev;
 		__entry->id = dqp->q_id;
 		__entry->flags = dqp->dq_flags;
 		__entry->nrefs = dqp->q_nrefs;
+
 		__entry->res_bcount = dqp->q_blk.reserved;
+		__entry->res_rtbcount = dqp->q_rtb.reserved;
+		__entry->res_icount = dqp->q_ino.reserved;
+
 		__entry->bcount = dqp->q_blk.count;
+		__entry->rtbcount = dqp->q_rtb.count;
 		__entry->icount = dqp->q_ino.count;
+
 		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
 		__entry->blk_softlimit = dqp->q_blk.softlimit;
+		__entry->rtb_hardlimit = dqp->q_rtb.hardlimit;
+		__entry->rtb_softlimit = dqp->q_rtb.softlimit;
 		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
 		__entry->ino_softlimit = dqp->q_ino.softlimit;
 	),
-	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
+	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u "
+		  "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx "
 		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
+		  "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx "
 		  "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->id,
 		  __print_flags(__entry->flags, "|", XFS_DQ_FLAGS),
 		  __entry->nrefs,
 		  __entry->res_bcount,
+		  __entry->res_rtbcount,
+		  __entry->res_icount,
 		  __entry->bcount,
 		  __entry->blk_hardlimit,
 		  __entry->blk_softlimit,
+		  __entry->rtbcount,
+		  __entry->rtb_hardlimit,
+		  __entry->rtb_softlimit,
 		  __entry->icount,
 		  __entry->ino_hardlimit,
 		  __entry->ino_softlimit)
@@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele);
 DEFINE_DQUOT_EVENT(xfs_dqflush);
 DEFINE_DQUOT_EVENT(xfs_dqflush_force);
 DEFINE_DQUOT_EVENT(xfs_dqflush_done);
+DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before);
+DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after);
+
+#define XFS_QMOPT_FLAGS \
+	{ XFS_QMOPT_UQUOTA,		"UQUOTA" }, \
+	{ XFS_QMOPT_PQUOTA,		"PQUOTA" }, \
+	{ XFS_QMOPT_FORCE_RES,		"FORCE_RES" }, \
+	{ XFS_QMOPT_SBVERSION,		"SBVERSION" }, \
+	{ XFS_QMOPT_GQUOTA,		"GQUOTA" }, \
+	{ XFS_QMOPT_INHERIT,		"INHERIT" }, \
+	{ XFS_QMOPT_RES_REGBLKS,	"RES_REGBLKS" }, \
+	{ XFS_QMOPT_RES_RTBLKS,		"RES_RTBLKS" }, \
+	{ XFS_QMOPT_BCOUNT,		"BCOUNT" }, \
+	{ XFS_QMOPT_ICOUNT,		"ICOUNT" }, \
+	{ XFS_QMOPT_RTBCOUNT,		"RTBCOUNT" }, \
+	{ XFS_QMOPT_DELBCOUNT,		"DELBCOUNT" }, \
+	{ XFS_QMOPT_DELRTBCOUNT,	"DELRTBCOUNT" }, \
+	{ XFS_QMOPT_RES_INOS,		"RES_INOS" }
+
+TRACE_EVENT(xfs_trans_mod_dquot,
+	TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp,
+		 unsigned int field, int64_t delta),
+	TP_ARGS(tp, dqp, field, delta),
+	TP_STRUCT__entry(
+		__field(dev_t, dev)
+		__field(unsigned int, dqflags)
+		__field(unsigned int, dqid)
+		__field(unsigned int, field)
+		__field(int64_t, delta)
+	),
+	TP_fast_assign(
+		__entry->dev = tp->t_mountp->m_super->s_dev;
+		__entry->dqflags = dqp->dq_flags;
+		__entry->dqid = dqp->q_id;
+		__entry->field = field;
+		__entry->delta = delta;
+	),
+	TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		   __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
+		  __entry->dqid,
+		   __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS),
+		  __entry->delta)
+);
+
+DECLARE_EVENT_CLASS(xfs_dqtrx_class,
+	TP_PROTO(struct xfs_dqtrx *qtrx),
+	TP_ARGS(qtrx),
+	TP_STRUCT__entry(
+		__field(dev_t, dev)
+		__field(unsigned int, dqflags)
+		__field(u32, dqid)
+
+		__field(uint64_t, blk_res)
+		__field(int64_t,  bcount_delta)
+		__field(int64_t,  delbcnt_delta)
+
+		__field(uint64_t, rtblk_res)
+		__field(uint64_t, rtblk_res_used)
+		__field(int64_t,  rtbcount_delta)
+		__field(int64_t,  delrtb_delta)
+
+		__field(uint64_t, ino_res)
+		__field(uint64_t, ino_res_used)
+		__field(int64_t,  icount_delta)
+	),
+	TP_fast_assign(
+		__entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev;
+		__entry->dqflags = qtrx->qt_dquot->dq_flags;
+		__entry->dqid = qtrx->qt_dquot->q_id;
+
+		__entry->blk_res = qtrx->qt_blk_res;
+		__entry->bcount_delta = qtrx->qt_bcount_delta;
+		__entry->delbcnt_delta = qtrx->qt_delbcnt_delta;
+
+		__entry->rtblk_res = qtrx->qt_rtblk_res;
+		__entry->rtblk_res_used = qtrx->qt_rtblk_res_used;
+		__entry->rtbcount_delta = qtrx->qt_rtbcount_delta;
+		__entry->delrtb_delta = qtrx->qt_delrtb_delta;
+
+		__entry->ino_res = qtrx->qt_ino_res;
+		__entry->ino_res_used = qtrx->qt_ino_res_used;
+		__entry->icount_delta = qtrx->qt_icount_delta;
+	),
+	TP_printk("dev %d:%d dquot %s id 0x%x "
+		  "blk_res %llu bcount_delta %lld delbcnt_delta %lld "
+		  "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld "
+		  "ino_res %llu ino_res_used %llu icount_delta %lld",
+		MAJOR(__entry->dev), MINOR(__entry->dev),
+		__print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
+		__entry->dqid,
+
+		__entry->blk_res,
+		__entry->bcount_delta,
+		__entry->delbcnt_delta,
+
+		__entry->rtblk_res,
+		__entry->rtblk_res_used,
+		__entry->rtbcount_delta,
+		__entry->delrtb_delta,
+
+		__entry->ino_res,
+		__entry->ino_res_used,
+		__entry->icount_delta)
+)
+
+#define DEFINE_DQTRX_EVENT(name) \
+DEFINE_EVENT(xfs_dqtrx_class, name, \
+	TP_PROTO(struct xfs_dqtrx *qtrx), \
+	TP_ARGS(qtrx))
+DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas);
+DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before);
+DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after);
 
 DECLARE_EVENT_CLASS(xfs_loggrant_class,
 	TP_PROTO(struct xlog *log, struct xlog_ticket *tic),
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 701923ea6c04..5689d9f1b748 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -15,6 +15,7 @@
 #include "xfs_trans_priv.h"
 #include "xfs_quota.h"
 #include "xfs_qm.h"
+#include "xfs_trace.h"
 
 STATIC void	xfs_trans_alloc_dqinfo(xfs_trans_t *);
 
@@ -203,6 +204,11 @@ xfs_trans_mod_dquot(
 	if (qtrx->qt_dquot == NULL)
 		qtrx->qt_dquot = dqp;
 
+	if (delta) {
+		trace_xfs_trans_mod_dquot_before(qtrx);
+		trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
+	}
+
 	switch (field) {
 
 		/*
@@ -266,6 +272,10 @@ xfs_trans_mod_dquot(
 	      default:
 		ASSERT(0);
 	}
+
+	if (delta)
+		trace_xfs_trans_mod_dquot_after(qtrx);
+
 	tp->t_flags |= XFS_TRANS_DQ_DIRTY;
 }
 
@@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas(
 				qtrx->qt_delbcnt_delta;
 			totalrtbdelta = qtrx->qt_rtbcount_delta +
 				qtrx->qt_delrtb_delta;
+
+			if (totalbdelta != 0 || totalrtbdelta != 0 ||
+			    qtrx->qt_icount_delta != 0) {
+				trace_xfs_trans_apply_dquot_deltas_before(dqp);
+				trace_xfs_trans_apply_dquot_deltas(qtrx);
+			}
+
 #ifdef DEBUG
 			if (totalbdelta < 0)
 				ASSERT(dqp->q_blk.count >= -totalbdelta);
@@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas(
 			if (totalrtbdelta)
 				dqp->q_rtb.count += totalrtbdelta;
 
+			if (totalbdelta != 0 || totalrtbdelta != 0 ||
+			    qtrx->qt_icount_delta != 0)
+				trace_xfs_trans_apply_dquot_deltas_after(dqp);
+
 			/*
 			 * Get any default limits in use.
 			 * Start/reset the timer(s) if needed.


^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
@ 2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:32   ` Chandan Babu R
  2020-07-01  8:33   ` Christoph Hellwig
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-06-30 21:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:41 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> can't lock the dquot buf to flush the dquot.  This prevents the AIL from
> blocking on the dquot, but it also forgets to clear the FREEING flag on
> its way out.  A subsequent purge attempt will see the FREEING flag is
> set and bail out, which leads to dqpurge_all failing to purge all the
> dquots.  This causes unmounts and quotaoff operations to hang.
> 
> Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_qm.c |    1 +
>   1 file changed, 1 insertion(+)
> 
> 
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index d6cd83317344..938023dd8ce5 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -148,6 +148,7 @@ xfs_qm_dqpurge(
>   			error = xfs_bwrite(bp);
>   			xfs_buf_relse(bp);
>   		} else if (error == -EAGAIN) {
> +			dqp->dq_flags &= ~XFS_DQ_FREEING;
>   			goto out_unlock;
>   		}
>   		xfs_dqflock(dqp);
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 02/18] xfs: fix inode quota reservation checks
  2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
@ 2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:34   ` Christoph Hellwig
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-06-30 21:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> xfs_trans_dqresv is the function that we use to make reservations
> against resource quotas.  Each resource contains two counters: the
> q_core counter, which tracks resources allocated on disk; and the dquot
> reservation counter, which tracks how much of that resource has either
> been allocated or reserved by threads that are working on metadata
> updates.
> 
> For disk blocks, we compare the proposed reservation counter against the
> hard and soft limits to decide if we're going to fail the operation.
> However, for inodes we inexplicably compare against the q_core counter,
> not the incore reservation count.
> 
> Since the q_core counter is always lower than the reservation count and
> we unlock the dquot between reservation and transaction commit, this
> means that multiple threads can reserve the last inode count before we
> hit the hard limit, and when they commit, we'll be well over the hard
> limit.
> 
> Fix this by checking against the incore inode reservation counter, since
> we would appear to maintain that correctly (and that's what we report in
> GETQUOTA).
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Ok, makes sense
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_trans_dquot.c |    2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index c0f73b82c055..ed0ce8b301b4 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -647,7 +647,7 @@ xfs_trans_dqresv(
>   			}
>   		}
>   		if (ninos > 0) {
> -			total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
> +			total_count = dqp->q_res_icount + ninos;
>   			timer = be32_to_cpu(dqp->q_core.d_itimer);
>   			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>   			warnlimit = defq->iwarnlimit;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
@ 2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:33   ` Chandan Babu R
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-06-30 21:35 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
>   1 file changed, 20 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
>   }
>   
>   /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
>   xfs_dquot_from_disk(
>   	struct xfs_dquot	*dqp,
>   	struct xfs_buf		*bp)
>   {
>   	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
>   
> +	/*
> +	 * The only field the verifier didn't check was the quota type flag, so
> +	 * do that here.
> +	 */
> +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> +	    dqp->q_core.d_id != ddqp->d_id) {
> +		xfs_alert(bp->b_mount,
> +			  "Metadata corruption detected at %pS, quota %u",
> +			  __this_address, be32_to_cpu(dqp->q_core.d_id));
> +		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
> +		return -EFSCORRUPTED;
> +	}
> +
>   	/* copy everything from disk dquot to the incore dquot */
>   	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
>   
> @@ -544,6 +558,7 @@ xfs_dquot_from_disk(
>   
>   	/* initialize the dquot speculative prealloc thresholds */
>   	xfs_dquot_set_prealloc_limits(dqp);
> +	return 0;
>   }
>   
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -617,9 +632,11 @@ xfs_qm_dqread(
>   	 * further.
>   	 */
>   	ASSERT(xfs_buf_islocked(bp));
> -	xfs_dquot_from_disk(dqp, bp);
> -
> +	error = xfs_dquot_from_disk(dqp, bp);
>   	xfs_buf_relse(bp);
> +	if (error)
> +		goto err;
> +
>   	*dqpp = dqp;
>   	return error;
>   
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
@ 2020-07-01  8:32   ` Chandan Babu R
  2020-07-01  8:33   ` Christoph Hellwig
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:32 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:11:56 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> can't lock the dquot buf to flush the dquot.  This prevents the AIL from
> blocking on the dquot, but it also forgets to clear the FREEING flag on
> its way out.  A subsequent purge attempt will see the FREEING flag is
> set and bail out, which leads to dqpurge_all failing to purge all the
> dquots.  This causes unmounts and quotaoff operations to hang.
>

xfs_qm_dqpurge() checks for the presence of XFS_DQ_FREEING. If it is set, it
indicates that another task is freeing this dquot.

A failed read operation could return -EAGAIN and hence xfs_qm_dqpurge()
returning without clearing XFS_DQ_FREEING would mean that future invocations
of this function would turn out to be a nop and hence the corresponding dquot
would linger around forever. Hence the fix is correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_qm.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> 
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index d6cd83317344..938023dd8ce5 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -148,6 +148,7 @@ xfs_qm_dqpurge(
>  			error = xfs_bwrite(bp);
>  			xfs_buf_relse(bp);
>  		} else if (error == -EAGAIN) {
> +			dqp->dq_flags &= ~XFS_DQ_FREEING;
>  			goto out_unlock;
>  		}
>  		xfs_dqflock(dqp);
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 02/18] xfs: fix inode quota reservation checks
  2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:34   ` Christoph Hellwig
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:02 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> xfs_trans_dqresv is the function that we use to make reservations
> against resource quotas.  Each resource contains two counters: the
> q_core counter, which tracks resources allocated on disk; and the dquot
> reservation counter, which tracks how much of that resource has either
> been allocated or reserved by threads that are working on metadata
> updates.
> 
> For disk blocks, we compare the proposed reservation counter against the
> hard and soft limits to decide if we're going to fail the operation.
> However, for inodes we inexplicably compare against the q_core counter,
> not the incore reservation count.
> 
> Since the q_core counter is always lower than the reservation count and
> we unlock the dquot between reservation and transaction commit, this
> means that multiple threads can reserve the last inode count before we
> hit the hard limit, and when they commit, we'll be well over the hard
> limit.
> 
> Fix this by checking against the incore inode reservation counter, since
> we would appear to maintain that correctly (and that's what we report in
> GETQUOTA).
>

As mentioned above, q_core.d_icount's value can be less than what has been
reserved by various running tasks. Hence deriving new reservation count from
q_core.d_icount is incorrect.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_trans_dquot.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index c0f73b82c055..ed0ce8b301b4 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -647,7 +647,7 @@ xfs_trans_dqresv(
>  			}
>  		}
>  		if (ninos > 0) {
> -			total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
> +			total_count = dqp->q_res_icount + ninos;
>  			timer = be32_to_cpu(dqp->q_core.d_itimer);
>  			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>  			warnlimit = defq->iwarnlimit;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:42   ` Christoph Hellwig
  2020-07-01 22:41   ` Dave Chinner
  3 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:09 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
>

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
>  }
>  
>  /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
>  xfs_dquot_from_disk(
>  	struct xfs_dquot	*dqp,
>  	struct xfs_buf		*bp)
>  {
>  	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
>  
> +	/*
> +	 * The only field the verifier didn't check was the quota type flag, so
> +	 * do that here.
> +	 */
> +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> +	    dqp->q_core.d_id != ddqp->d_id) {
> +		xfs_alert(bp->b_mount,
> +			  "Metadata corruption detected at %pS, quota %u",
> +			  __this_address, be32_to_cpu(dqp->q_core.d_id));
> +		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
> +		return -EFSCORRUPTED;
> +	}
> +
>  	/* copy everything from disk dquot to the incore dquot */
>  	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
>  
> @@ -544,6 +558,7 @@ xfs_dquot_from_disk(
>  
>  	/* initialize the dquot speculative prealloc thresholds */
>  	xfs_dquot_set_prealloc_limits(dqp);
> +	return 0;
>  }
>  
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -617,9 +632,11 @@ xfs_qm_dqread(
>  	 * further.
>  	 */
>  	ASSERT(xfs_buf_islocked(bp));
> -	xfs_dquot_from_disk(dqp, bp);
> -
> +	error = xfs_dquot_from_disk(dqp, bp);
>  	xfs_buf_relse(bp);
> +	if (error)
> +		goto err;
> +
>  	*dqpp = dqp;
>  	return error;
>  
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 05/18] xfs: stop using q_core.d_id in the quota code
  2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:48   ` Christoph Hellwig
  2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:23 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add a dquot id field to the incore dquot, and use that instead of the
> one in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> We also rearrange the start of xfs_dquot to remove padding holes, saving
> 8 bytes.

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/scrub/quota.c     |   19 ++++++++++++-------
>  fs/xfs/xfs_dquot.c       |   25 +++++++++++--------------
>  fs/xfs/xfs_dquot.h       |    5 +++--
>  fs/xfs/xfs_dquot_item.c  |    2 +-
>  fs/xfs/xfs_qm.c          |   22 ++++++++++------------
>  fs/xfs/xfs_qm_syscalls.c |    4 ++--
>  fs/xfs/xfs_trace.h       |    2 +-
>  fs/xfs/xfs_trans_dquot.c |    8 +++-----
>  8 files changed, 43 insertions(+), 44 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 710659d3fa28..9a271f115882 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -92,7 +92,6 @@ xchk_quota_item(
>  	unsigned long long	icount;
>  	unsigned long long	rcount;
>  	xfs_ino_t		fs_icount;
> -	xfs_dqid_t		id = be32_to_cpu(d->d_id);
>  	int			error = 0;
>  
>  	if (xchk_should_terminate(sc, &error))
> @@ -102,11 +101,11 @@ xchk_quota_item(
>  	 * Except for the root dquot, the actual dquot we got must either have
>  	 * the same or higher id as we saw before.
>  	 */
> -	offset = id / qi->qi_dqperchunk;
> -	if (id && id <= sqi->last_id)
> +	offset = dq->q_id / qi->qi_dqperchunk;
> +	if (dq->q_id && dq->q_id <= sqi->last_id)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> -	sqi->last_id = id;
> +	sqi->last_id = dq->q_id;
>  
>  	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> @@ -171,13 +170,19 @@ xchk_quota_item(
>  	 * lower limit than the actual usage.  However, we flag it for
>  	 * admin review.
>  	 */
> -	if (id != 0 && bhard != 0 && bcount > bhard)
> +	if (dq->q_id == 0)
> +		goto out;
> +
> +	if (bhard != 0 && bcount > bhard)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (id != 0 && ihard != 0 && icount > ihard)
> +
> +	if (ihard != 0 && icount > ihard)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (id != 0 && rhard != 0 && rcount > rhard)
> +
> +	if (rhard != 0 && rcount > rhard)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
> +out:
>  	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
>  		return -EFSCORRUPTED;
>  
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 59d1bce34a98..76b35888e726 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits(
>  	struct xfs_def_quota	*defq;
>  	int			prealloc = 0;
>  
> -	ASSERT(d->d_id);
> +	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>  
>  	if (defq->bsoftlimit && !d->d_blk_softlimit) {
> @@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers(
>  	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_def_quota	*defq;
>  
> -	ASSERT(d->d_id);
> +	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>  
>  #ifdef DEBUG
> @@ -365,7 +365,7 @@ xfs_dquot_disk_alloc(
>  	 * Make a chunk of dquots out of this buffer and log
>  	 * the entire thing.
>  	 */
> -	xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
> +	xfs_qm_init_dquot_blk(tp, mp, dqp->q_id,
>  			      dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
>  	xfs_buf_set_ref(bp, XFS_DQUOT_REF);
>  
> @@ -478,7 +478,7 @@ xfs_dquot_alloc(
>  	dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0);
>  
>  	dqp->dq_flags = type;
> -	dqp->q_core.d_id = cpu_to_be32(id);
> +	dqp->q_id = id;
>  	dqp->q_mount = mp;
>  	INIT_LIST_HEAD(&dqp->q_lru);
>  	mutex_init(&dqp->q_qlock);
> @@ -537,10 +537,10 @@ xfs_dquot_from_disk(
>  	 */
>  	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
>  	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> -	    dqp->q_core.d_id != ddqp->d_id) {
> +	    dqp->q_id != be32_to_cpu(ddqp->d_id)) {
>  		xfs_alert(bp->b_mount,
>  			  "Metadata corruption detected at %pS, quota %u",
> -			  __this_address, be32_to_cpu(dqp->q_core.d_id));
> +			  __this_address, dqp->q_id);
>  		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
>  		return -EFSCORRUPTED;
>  	}
> @@ -1177,11 +1177,10 @@ xfs_qm_dqflush(
>  	ddqp = &dqb->dd_diskdq;
>  
>  	/* sanity check the in-core structure before we flush */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id),
> -			      0);
> +	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				be32_to_cpu(dqp->q_core.d_id), fa);
> +				dqp->q_id, fa);
>  		xfs_buf_relse(bp);
>  		error = -EFSCORRUPTED;
>  		goto out_abort;
> @@ -1190,7 +1189,7 @@ xfs_qm_dqflush(
>  	fa = xfs_qm_dqflush_check(dqp);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				be32_to_cpu(dqp->q_core.d_id), fa);
> +				dqp->q_id, fa);
>  		xfs_buf_relse(bp);
>  		error = -EFSCORRUPTED;
>  		goto out_abort;
> @@ -1263,8 +1262,7 @@ xfs_dqlock2(
>  {
>  	if (d1 && d2) {
>  		ASSERT(d1 != d2);
> -		if (be32_to_cpu(d1->q_core.d_id) >
> -		    be32_to_cpu(d2->q_core.d_id)) {
> +		if (d1->q_id > d2->q_id) {
>  			mutex_lock(&d2->q_qlock);
>  			mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
>  		} else {
> @@ -1332,9 +1330,8 @@ xfs_qm_dqiterate(
>  			return error;
>  
>  		error = iter_fn(dq, dqtype, priv);
> -		id = be32_to_cpu(dq->q_core.d_id);
> +		id = dq->q_id + 1;
>  		xfs_qm_dqput(dq);
> -		id++;
>  	} while (error == 0 && id != 0);
>  
>  	return error;
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 1b1a4261a580..5ea1f1515979 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -31,12 +31,13 @@ enum {
>   * The incore dquot structure
>   */
>  struct xfs_dquot {
> -	uint			dq_flags;
>  	struct list_head	q_lru;
>  	struct xfs_mount	*q_mount;
> +	xfs_dqid_t		q_id;
> +	uint			dq_flags;
>  	uint			q_nrefs;
> -	xfs_daddr_t		q_blkno;
>  	int			q_bufoffset;
> +	xfs_daddr_t		q_blkno;
>  	xfs_fileoff_t		q_fileoffset;
>  
>  	struct xfs_disk_dquot	q_core;
> diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
> index ff0ab65cf413..378d919997f1 100644
> --- a/fs/xfs/xfs_dquot_item.c
> +++ b/fs/xfs/xfs_dquot_item.c
> @@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format(
>  	qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
>  	qlf->qlf_type = XFS_LI_DQUOT;
>  	qlf->qlf_size = 2;
> -	qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id);
> +	qlf->qlf_id = qlip->qli_dquot->q_id;
>  	qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
>  	qlf->qlf_len = 1;
>  	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 632025c2f00b..95e51186bd57 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -79,7 +79,7 @@ xfs_qm_dquot_walk(
>  		for (i = 0; i < nr_found; i++) {
>  			struct xfs_dquot *dqp = batch[i];
>  
> -			next_index = be32_to_cpu(dqp->q_core.d_id) + 1;
> +			next_index = dqp->q_id + 1;
>  
>  			error = execute(batch[i], data);
>  			if (error == -EAGAIN) {
> @@ -161,8 +161,7 @@ xfs_qm_dqpurge(
>  	xfs_dqfunlock(dqp);
>  	xfs_dqunlock(dqp);
>  
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
> -			  be32_to_cpu(dqp->q_core.d_id));
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
>  	qi->qi_dquots--;
>  
>  	/*
> @@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust(
>  	 *
>  	 * There are no timers for the default values set in the root dquot.
>  	 */
> -	if (dqp->q_core.d_id) {
> +	if (dqp->q_id) {
>  		xfs_qm_adjust_dqlimits(mp, dqp);
>  		xfs_qm_adjust_dqtimers(mp, dqp);
>  	}
> @@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one(
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  
>  	mutex_lock(&qi->qi_tree_lock);
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
> -			  be32_to_cpu(dqp->q_core.d_id));
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
>  
>  	qi->qi_dquots--;
>  	mutex_unlock(&qi->qi_tree_lock);
> @@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve(
>  			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
>  
>  	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
> -	    i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) {
> +	    i_uid_read(VFS_I(ip)) != udqp->q_id) {
>  		udq_delblks = udqp;
>  		/*
>  		 * If there are delayed allocation blocks, then we have to
> @@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve(
>  		}
>  	}
>  	if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
> -	    i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) {
> +	    i_gid_read(VFS_I(ip)) != gdqp->q_id) {
>  		gdq_delblks = gdqp;
>  		if (delblks) {
>  			ASSERT(ip->i_gdquot);
> @@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve(
>  	}
>  
>  	if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
> -	    ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) {
> +	    ip->i_d.di_projid != pdqp->q_id) {
>  		pdq_delblks = pdqp;
>  		if (delblks) {
>  			ASSERT(ip->i_pdquot);
> @@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach(
>  
>  	if (udqp && XFS_IS_UQUOTA_ON(mp)) {
>  		ASSERT(ip->i_udquot == NULL);
> -		ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id));
> +		ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id);
>  
>  		ip->i_udquot = xfs_qm_dqhold(udqp);
>  		xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
>  	}
>  	if (gdqp && XFS_IS_GQUOTA_ON(mp)) {
>  		ASSERT(ip->i_gdquot == NULL);
> -		ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id));
> +		ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id);
>  
>  		ip->i_gdquot = xfs_qm_dqhold(gdqp);
>  		xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
>  	}
>  	if (pdqp && XFS_IS_PQUOTA_ON(mp)) {
>  		ASSERT(ip->i_pdquot == NULL);
> -		ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id));
> +		ASSERT(ip->i_d.di_projid == pdqp->q_id);
>  
>  		ip->i_pdquot = xfs_qm_dqhold(pdqp);
>  		xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 8cbb65f01bf1..90a11e7daf92 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc(
>  	if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) ||
>  	     (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) ||
>  	     (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) &&
> -	    dqp->q_core.d_id != 0) {
> +	    dqp->q_id != 0) {
>  		if ((dst->d_space > dst->d_spc_softlimit) &&
>  		    (dst->d_spc_softlimit > 0)) {
>  			ASSERT(dst->d_spc_timer != 0);
> @@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next(
>  		return error;
>  
>  	/* Fill in the ID we actually read from disk */
> -	*id = be32_to_cpu(dqp->q_core.d_id);
> +	*id = dqp->q_id;
>  
>  	xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
>  
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 2c5df8315351..78d9dbc7614d 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>  	), \
>  	TP_fast_assign(
>  		__entry->dev = dqp->q_mount->m_super->s_dev;
> -		__entry->id = be32_to_cpu(dqp->q_core.d_id);
> +		__entry->id = dqp->q_id;
>  		__entry->flags = dqp->dq_flags;
>  		__entry->nrefs = dqp->q_nrefs;
>  		__entry->res_bcount = dqp->q_res_bcount;
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index ed0ce8b301b4..a2656ec6ea76 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas(
>  			 * Get any default limits in use.
>  			 * Start/reset the timer(s) if needed.
>  			 */
> -			if (d->d_id) {
> +			if (dqp->q_id) {
>  				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
>  				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
>  			}
> @@ -558,8 +558,7 @@ xfs_quota_warn(
>  	else
>  		qtype = GRPQUOTA;
>  
> -	quota_send_warning(make_kqid(&init_user_ns, qtype,
> -				     be32_to_cpu(dqp->q_core.d_id)),
> +	quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
>  			   mp->m_super->s_dev, type);
>  }
>  
> @@ -618,8 +617,7 @@ xfs_trans_dqresv(
>  		resbcountp = &dqp->q_res_rtbcount;
>  	}
>  
> -	if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
> -	    dqp->q_core.d_id &&
> +	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
>  	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
>  	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
>  	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 06/18] xfs: use a per-resource struct for incore dquot data
  2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:49   ` Christoph Hellwig
  2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:29 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce a new struct xfs_dquot_res that we'll use to track all the
> incore data for a particular resource type (block, inode, rt block).
> This will help us (once we've eliminated q_core) to declutter quota
> functions that currently open-code field access or pass around fields
> around explicitly.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |    6 +++---
>  fs/xfs/xfs_dquot.h       |   18 +++++++++++-------
>  fs/xfs/xfs_iomap.c       |    6 +++---
>  fs/xfs/xfs_qm.c          |    6 +++---
>  fs/xfs/xfs_qm_bhv.c      |    8 ++++----
>  fs/xfs/xfs_qm_syscalls.c |    6 +++---
>  fs/xfs/xfs_trace.h       |    2 +-
>  fs/xfs/xfs_trans_dquot.c |   42 +++++++++++++++++++++---------------------
>  8 files changed, 49 insertions(+), 45 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 76b35888e726..03624a8f0566 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -552,9 +552,9 @@ xfs_dquot_from_disk(
>  	 * Reservation counters are defined as reservation plus current usage
>  	 * to avoid having to add every time.
>  	 */
> -	dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount);
> -	dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
> -	dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);
> +	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
> +	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
> +	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
>  
>  	/* initialize the dquot speculative prealloc thresholds */
>  	xfs_dquot_set_prealloc_limits(dqp);
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 5ea1f1515979..cb20df1e774f 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -27,6 +27,11 @@ enum {
>  	XFS_QLOWSP_MAX
>  };
>  
> +struct xfs_dquot_res {
> +	/* Total resources allocated and reserved. */
> +	xfs_qcnt_t		reserved;
> +};
> +
>  /*
>   * The incore dquot structure
>   */
> @@ -40,14 +45,13 @@ struct xfs_dquot {
>  	xfs_daddr_t		q_blkno;
>  	xfs_fileoff_t		q_fileoffset;
>  
> +	struct xfs_dquot_res	q_blk;	/* regular blocks */
> +	struct xfs_dquot_res	q_ino;	/* inodes */
> +	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
> +
>  	struct xfs_disk_dquot	q_core;
>  	struct xfs_dq_logitem	q_logitem;
> -	/* total regular nblks used+reserved */
> -	xfs_qcnt_t		q_res_bcount;
> -	/* total inos allocd+reserved */
> -	xfs_qcnt_t		q_res_icount;
> -	/* total realtime blks used+reserved */
> -	xfs_qcnt_t		q_res_rtbcount;
> +
>  	xfs_qcnt_t		q_prealloc_lo_wmark;
>  	xfs_qcnt_t		q_prealloc_hi_wmark;
>  	int64_t			q_low_space[XFS_QLOWSP_MAX];
> @@ -138,7 +142,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>  {
>  	int64_t freesp;
>  
> -	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_res_bcount;
> +	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
>  	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
>  		return true;
>  
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index b9a8c3798e08..f60a6e44363b 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -307,7 +307,7 @@ xfs_quota_need_throttle(
>  		return false;
>  
>  	/* under the lo watermark, no throttle */
> -	if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark)
> +	if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark)
>  		return false;
>  
>  	return true;
> @@ -326,13 +326,13 @@ xfs_quota_calc_throttle(
>  	struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
>  
>  	/* no dq, or over hi wmark, squash the prealloc completely */
> -	if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
> +	if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) {
>  		*qblocks = 0;
>  		*qfreesp = 0;
>  		return;
>  	}
>  
> -	freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount;
> +	freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved;
>  	if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
>  		shift = 2;
>  		if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 95e51186bd57..6ce3a4402041 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust(
>  	 * resource usage.
>  	 */
>  	be64_add_cpu(&dqp->q_core.d_icount, 1);
> -	dqp->q_res_icount++;
> +	dqp->q_ino.reserved++;
>  	if (nblks) {
>  		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
> -		dqp->q_res_bcount += nblks;
> +		dqp->q_blk.reserved += nblks;
>  	}
>  	if (rtblks) {
>  		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
> -		dqp->q_res_rtbcount += rtblks;
> +		dqp->q_rtb.reserved += rtblks;
>  	}
>  
>  	/*
> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index fc2fa418919f..94b2b4b0fc17 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot(
>  	if (limit && statp->f_blocks > limit) {
>  		statp->f_blocks = limit;
>  		statp->f_bfree = statp->f_bavail =
> -			(statp->f_blocks > dqp->q_res_bcount) ?
> -			 (statp->f_blocks - dqp->q_res_bcount) : 0;
> +			(statp->f_blocks > dqp->q_blk.reserved) ?
> +			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
>  	}
>  
>  	limit = dqp->q_core.d_ino_softlimit ?
> @@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot(
>  	if (limit && statp->f_files > limit) {
>  		statp->f_files = limit;
>  		statp->f_ffree =
> -			(statp->f_files > dqp->q_res_icount) ?
> -			 (statp->f_files - dqp->q_res_icount) : 0;
> +			(statp->f_files > dqp->q_ino.reserved) ?
> +			 (statp->f_files - dqp->q_ino.reserved) : 0;
>  	}
>  }
>  
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 90a11e7daf92..56fe80395679 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc(
>  		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
>  	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
>  	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> -	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount);
> -	dst->d_ino_count = dqp->q_res_icount;
> +	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
> +	dst->d_ino_count = dqp->q_ino.reserved;
>  	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
>  	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
>  	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
> @@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc(
>  		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
>  	dst->d_rt_spc_softlimit =
>  		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
> -	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount);
> +	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>  	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>  	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
>  
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 78d9dbc7614d..71567ed367f2 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>  		__entry->id = dqp->q_id;
>  		__entry->flags = dqp->dq_flags;
>  		__entry->nrefs = dqp->q_nrefs;
> -		__entry->res_bcount = dqp->q_res_bcount;
> +		__entry->res_bcount = dqp->q_blk.reserved;
>  		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
>  		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
>  		__entry->blk_hardlimit =
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index a2656ec6ea76..469bf7946d3d 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas(
>  
>  				if (qtrx->qt_blk_res != blk_res_used) {
>  					if (qtrx->qt_blk_res > blk_res_used)
> -						dqp->q_res_bcount -= (xfs_qcnt_t)
> +						dqp->q_blk.reserved -= (xfs_qcnt_t)
>  							(qtrx->qt_blk_res -
>  							 blk_res_used);
>  					else
> -						dqp->q_res_bcount -= (xfs_qcnt_t)
> +						dqp->q_blk.reserved -= (xfs_qcnt_t)
>  							(blk_res_used -
>  							 qtrx->qt_blk_res);
>  				}
> @@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas(
>  				 * deliberately skip quota reservations.
>  				 */
>  				if (qtrx->qt_bcount_delta) {
> -					dqp->q_res_bcount +=
> +					dqp->q_blk.reserved +=
>  					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
>  				}
>  			}
> @@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas(
>  				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
>  					if (qtrx->qt_rtblk_res >
>  					    qtrx->qt_rtblk_res_used)
> -					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
> +					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
>  						       (qtrx->qt_rtblk_res -
>  							qtrx->qt_rtblk_res_used);
>  					else
> -					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
> +					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
>  						       (qtrx->qt_rtblk_res_used -
>  							qtrx->qt_rtblk_res);
>  				}
>  			} else {
>  				if (qtrx->qt_rtbcount_delta)
> -					dqp->q_res_rtbcount +=
> +					dqp->q_rtb.reserved +=
>  					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
>  			}
>  
> @@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas(
>  				ASSERT(qtrx->qt_ino_res >=
>  				       qtrx->qt_ino_res_used);
>  				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
> -					dqp->q_res_icount -= (xfs_qcnt_t)
> +					dqp->q_ino.reserved -= (xfs_qcnt_t)
>  						(qtrx->qt_ino_res -
>  						 qtrx->qt_ino_res_used);
>  			} else {
>  				if (qtrx->qt_icount_delta)
> -					dqp->q_res_icount +=
> +					dqp->q_ino.reserved +=
>  					    (xfs_qcnt_t)qtrx->qt_icount_delta;
>  			}
>  
> -			ASSERT(dqp->q_res_bcount >=
> +			ASSERT(dqp->q_blk.reserved >=
>  				be64_to_cpu(dqp->q_core.d_bcount));
> -			ASSERT(dqp->q_res_icount >=
> +			ASSERT(dqp->q_ino.reserved >=
>  				be64_to_cpu(dqp->q_core.d_icount));
> -			ASSERT(dqp->q_res_rtbcount >=
> +			ASSERT(dqp->q_rtb.reserved >=
>  				be64_to_cpu(dqp->q_core.d_rtbcount));
>  		}
>  	}
> @@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots(
>  			if (qtrx->qt_blk_res) {
>  				xfs_dqlock(dqp);
>  				locked = true;
> -				dqp->q_res_bcount -=
> +				dqp->q_blk.reserved -=
>  					(xfs_qcnt_t)qtrx->qt_blk_res;
>  			}
>  			if (qtrx->qt_ino_res) {
> @@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots(
>  					xfs_dqlock(dqp);
>  					locked = true;
>  				}
> -				dqp->q_res_icount -=
> +				dqp->q_ino.reserved -=
>  					(xfs_qcnt_t)qtrx->qt_ino_res;
>  			}
>  
> @@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots(
>  					xfs_dqlock(dqp);
>  					locked = true;
>  				}
> -				dqp->q_res_rtbcount -=
> +				dqp->q_rtb.reserved -=
>  					(xfs_qcnt_t)qtrx->qt_rtblk_res;
>  			}
>  			if (locked)
> @@ -602,7 +602,7 @@ xfs_trans_dqresv(
>  		timer = be32_to_cpu(dqp->q_core.d_btimer);
>  		warns = be16_to_cpu(dqp->q_core.d_bwarns);
>  		warnlimit = defq->bwarnlimit;
> -		resbcountp = &dqp->q_res_bcount;
> +		resbcountp = &dqp->q_blk.reserved;
>  	} else {
>  		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
>  		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
> @@ -614,7 +614,7 @@ xfs_trans_dqresv(
>  		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>  		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
>  		warnlimit = defq->rtbwarnlimit;
> -		resbcountp = &dqp->q_res_rtbcount;
> +		resbcountp = &dqp->q_rtb.reserved;
>  	}
>  
>  	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
> @@ -675,11 +675,11 @@ xfs_trans_dqresv(
>  
>  	/*
>  	 * Change the reservation, but not the actual usage.
> -	 * Note that q_res_bcount = q_core.d_bcount + resv
> +	 * Note that q_blk.reserved = q_core.d_bcount + resv
>  	 */
>  	(*resbcountp) += (xfs_qcnt_t)nblks;
>  	if (ninos != 0)
> -		dqp->q_res_icount += (xfs_qcnt_t)ninos;
> +		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
>  
>  	/*
>  	 * note the reservation amt in the trans struct too,
> @@ -700,9 +700,9 @@ xfs_trans_dqresv(
>  					    XFS_TRANS_DQ_RES_INOS,
>  					    ninos);
>  	}
> -	ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
> -	ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
> -	ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
> +	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
> +	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
> +	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
>  
>  	xfs_dqunlock(dqp);
>  	return 0;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:50   ` Christoph Hellwig
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:36 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add limits fields in the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/scrub/quota.c     |   36 ++++--------
>  fs/xfs/xfs_dquot.c       |  136 ++++++++++++++++++++++++++--------------------
>  fs/xfs/xfs_dquot.h       |    6 ++
>  fs/xfs/xfs_qm.c          |   14 ++---
>  fs/xfs/xfs_qm.h          |   12 ++--
>  fs/xfs/xfs_qm_bhv.c      |   12 ++--
>  fs/xfs/xfs_qm_syscalls.c |   40 ++++++--------
>  fs/xfs/xfs_trace.h       |   12 +---
>  fs/xfs/xfs_trans_dquot.c |   12 ++--
>  9 files changed, 139 insertions(+), 141 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 9a271f115882..1a1c6996fc69 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -82,12 +82,6 @@ xchk_quota_item(
>  	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  	xfs_fileoff_t		offset;
> -	unsigned long long	bsoft;
> -	unsigned long long	isoft;
> -	unsigned long long	rsoft;
> -	unsigned long long	bhard;
> -	unsigned long long	ihard;
> -	unsigned long long	rhard;
>  	unsigned long long	bcount;
>  	unsigned long long	icount;
>  	unsigned long long	rcount;
> @@ -110,15 +104,6 @@ xchk_quota_item(
>  	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> -	/* Check the limits. */
> -	bhard = be64_to_cpu(d->d_blk_hardlimit);
> -	ihard = be64_to_cpu(d->d_ino_hardlimit);
> -	rhard = be64_to_cpu(d->d_rtb_hardlimit);
> -
> -	bsoft = be64_to_cpu(d->d_blk_softlimit);
> -	isoft = be64_to_cpu(d->d_ino_softlimit);
> -	rsoft = be64_to_cpu(d->d_rtb_softlimit);
> -
>  	/*
>  	 * Warn if the hard limits are larger than the fs.
>  	 * Administrators can do this, though in production this seems
> @@ -127,19 +112,19 @@ xchk_quota_item(
>  	 * Complain about corruption if the soft limit is greater than
>  	 * the hard limit.
>  	 */
> -	if (bhard > mp->m_sb.sb_dblocks)
> +	if (dq->q_blk.hardlimit > mp->m_sb.sb_dblocks)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (bsoft > bhard)
> +	if (dq->q_blk.softlimit > dq->q_blk.hardlimit)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> -	if (ihard > M_IGEO(mp)->maxicount)
> +	if (dq->q_ino.hardlimit > M_IGEO(mp)->maxicount)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (isoft > ihard)
> +	if (dq->q_ino.softlimit > dq->q_ino.hardlimit)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> -	if (rhard > mp->m_sb.sb_rblocks)
> +	if (dq->q_rtb.hardlimit > mp->m_sb.sb_rblocks)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (rsoft > rhard)
> +	if (dq->q_rtb.softlimit > dq->q_rtb.hardlimit)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
>  	/* Check the resource counts. */
> @@ -173,13 +158,16 @@ xchk_quota_item(
>  	if (dq->q_id == 0)
>  		goto out;
>  
> -	if (bhard != 0 && bcount > bhard)
> +	if (dq->q_blk.hardlimit != 0 &&
> +	    bcount > dq->q_blk.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
> -	if (ihard != 0 && icount > ihard)
> +	if (dq->q_ino.hardlimit != 0 &&
> +	    icount > dq->q_ino.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
> -	if (rhard != 0 && rcount > rhard)
> +	if (dq->q_rtb.hardlimit != 0 &&
> +	    rcount > dq->q_rtb.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
>  out:
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 03624a8f0566..63f744bcbc90 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -70,29 +70,28 @@ xfs_qm_adjust_dqlimits(
>  	struct xfs_dquot	*dq)
>  {
>  	struct xfs_quotainfo	*q = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_def_quota	*defq;
>  	int			prealloc = 0;
>  
>  	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>  
> -	if (defq->bsoftlimit && !d->d_blk_softlimit) {
> -		d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
> +	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> +		dq->q_blk.softlimit = defq->bsoftlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->bhardlimit && !d->d_blk_hardlimit) {
> -		d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
> +	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> +		dq->q_blk.hardlimit = defq->bhardlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->isoftlimit && !d->d_ino_softlimit)
> -		d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
> -	if (defq->ihardlimit && !d->d_ino_hardlimit)
> -		d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
> -	if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
> -		d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
> -	if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
> -		d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
> +	if (defq->isoftlimit && !dq->q_ino.softlimit)
> +		dq->q_ino.softlimit = defq->isoftlimit;
> +	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> +		dq->q_ino.hardlimit = defq->ihardlimit;
> +	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> +		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> +	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> +		dq->q_rtb.hardlimit = defq->rtbhardlimit;
>  
>  	if (prealloc)
>  		xfs_dquot_set_prealloc_limits(dq);
> @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
>  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>  
>  #ifdef DEBUG
> -	if (d->d_blk_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> -		       be64_to_cpu(d->d_blk_hardlimit));
> -	if (d->d_ino_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> -		       be64_to_cpu(d->d_ino_hardlimit));
> -	if (d->d_rtb_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> -		       be64_to_cpu(d->d_rtb_hardlimit));
> +	if (dq->q_blk.hardlimit)
> +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> +	if (dq->q_ino.hardlimit)
> +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> +	if (dq->q_rtb.hardlimit)
> +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
>  #endif
>  
>  	if (!d->d_btimer) {
> -		if ((d->d_blk_softlimit &&
> -		     (be64_to_cpu(d->d_bcount) >
> -		      be64_to_cpu(d->d_blk_softlimit))) ||
> -		    (d->d_blk_hardlimit &&
> -		     (be64_to_cpu(d->d_bcount) >
> -		      be64_to_cpu(d->d_blk_hardlimit)))) {
> +		if ((dq->q_blk.softlimit &&
> +		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
> +		    (dq->q_blk.hardlimit &&
> +		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
>  			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->btimelimit);
>  		} else {
>  			d->d_bwarns = 0;
>  		}
>  	} else {
> -		if ((!d->d_blk_softlimit ||
> -		     (be64_to_cpu(d->d_bcount) <=
> -		      be64_to_cpu(d->d_blk_softlimit))) &&
> -		    (!d->d_blk_hardlimit ||
> -		    (be64_to_cpu(d->d_bcount) <=
> -		     be64_to_cpu(d->d_blk_hardlimit)))) {
> +		if ((!dq->q_blk.softlimit ||
> +		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
> +		    (!dq->q_blk.hardlimit ||
> +		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
>  			d->d_btimer = 0;
>  		}
>  	}
>  
>  	if (!d->d_itimer) {
> -		if ((d->d_ino_softlimit &&
> -		     (be64_to_cpu(d->d_icount) >
> -		      be64_to_cpu(d->d_ino_softlimit))) ||
> -		    (d->d_ino_hardlimit &&
> -		     (be64_to_cpu(d->d_icount) >
> -		      be64_to_cpu(d->d_ino_hardlimit)))) {
> +		if ((dq->q_ino.softlimit &&
> +		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
> +		    (dq->q_ino.hardlimit &&
> +		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
>  			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->itimelimit);
>  		} else {
>  			d->d_iwarns = 0;
>  		}
>  	} else {
> -		if ((!d->d_ino_softlimit ||
> -		     (be64_to_cpu(d->d_icount) <=
> -		      be64_to_cpu(d->d_ino_softlimit)))  &&
> -		    (!d->d_ino_hardlimit ||
> -		     (be64_to_cpu(d->d_icount) <=
> -		      be64_to_cpu(d->d_ino_hardlimit)))) {
> +		if ((!dq->q_ino.softlimit ||
> +		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
> +		    (!dq->q_ino.hardlimit ||
> +		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
>  			d->d_itimer = 0;
>  		}
>  	}
>  
>  	if (!d->d_rtbtimer) {
> -		if ((d->d_rtb_softlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) >
> -		      be64_to_cpu(d->d_rtb_softlimit))) ||
> -		    (d->d_rtb_hardlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) >
> -		      be64_to_cpu(d->d_rtb_hardlimit)))) {
> +		if ((dq->q_rtb.softlimit &&
> +		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
> +		    (dq->q_rtb.hardlimit &&
> +		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
>  			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->rtbtimelimit);
>  		} else {
>  			d->d_rtbwarns = 0;
>  		}
>  	} else {
> -		if ((!d->d_rtb_softlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <=
> -		      be64_to_cpu(d->d_rtb_softlimit))) &&
> -		    (!d->d_rtb_hardlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <=
> -		      be64_to_cpu(d->d_rtb_hardlimit)))) {
> +		if ((!dq->q_rtb.softlimit ||
> +		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
> +		    (!dq->q_rtb.hardlimit ||
> +		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
>  			d->d_rtbtimer = 0;
>  		}
>  	}
> @@ -290,8 +274,8 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
>  {
>  	uint64_t space;
>  
> -	dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> -	dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
> +	dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit;
> +	dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit;
>  	if (!dqp->q_prealloc_lo_wmark) {
>  		dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
>  		do_div(dqp->q_prealloc_lo_wmark, 100);
> @@ -547,6 +531,12 @@ xfs_dquot_from_disk(
>  
>  	/* copy everything from disk dquot to the incore dquot */
>  	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
> +	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
> +	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
> +	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> +	dqp->q_ino.softlimit = be64_to_cpu(ddqp->d_ino_softlimit);
> +	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
> +	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
>  
>  	/*
>  	 * Reservation counters are defined as reservation plus current usage
> @@ -569,6 +559,12 @@ xfs_dquot_to_disk(
>  {
>  	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
>  	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
> +	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
> +	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
> +	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
> +	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
> +	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
>  }
>  
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1123,9 +1119,29 @@ static xfs_failaddr_t
>  xfs_qm_dqflush_check(
>  	struct xfs_dquot	*dqp)
>  {
> +	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> +
>  	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
>  		return __this_address;
>  
> +	if (dqp->q_id == 0)
> +		return NULL;
> +
> +	if (dqp->q_blk.softlimit &&
> +	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> +	    !ddq->d_btimer)
> +		return __this_address;
> +
> +	if (dqp->q_ino.softlimit &&
> +	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> +	    !ddq->d_itimer)
> +		return __this_address;
> +
> +	if (dqp->q_rtb.softlimit &&
> +	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> +	    !ddq->d_rtbtimer)
> +		return __this_address;
> +
>  	return NULL;
>  }
>  
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index cb20df1e774f..edb49788c476 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -30,6 +30,10 @@ enum {
>  struct xfs_dquot_res {
>  	/* Total resources allocated and reserved. */
>  	xfs_qcnt_t		reserved;
> +
> +	/* Absolute and preferred limits. */
> +	xfs_qcnt_t		hardlimit;
> +	xfs_qcnt_t		softlimit;
>  };
>  
>  /*
> @@ -142,7 +146,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>  {
>  	int64_t freesp;
>  
> -	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
> +	freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
>  	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
>  		return true;
>  
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 6ce3a4402041..54fc3aac1a68 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -550,26 +550,24 @@ xfs_qm_set_defquota(
>  {
>  	struct xfs_dquot	*dqp;
>  	struct xfs_def_quota	*defq;
> -	struct xfs_disk_dquot	*ddqp;
>  	int			error;
>  
>  	error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
>  	if (error)
>  		return;
>  
> -	ddqp = &dqp->q_core;
>  	defq = xfs_get_defquota(qinf, xfs_dquot_type(dqp));
>  
>  	/*
>  	 * Timers and warnings have been already set, let's just set the
>  	 * default limits for this quota type
>  	 */
> -	defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
> -	defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
> -	defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> -	defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
> -	defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
> -	defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
> +	defq->bhardlimit = dqp->q_blk.hardlimit;
> +	defq->bsoftlimit = dqp->q_blk.softlimit;
> +	defq->ihardlimit = dqp->q_ino.hardlimit;
> +	defq->isoftlimit = dqp->q_ino.softlimit;
> +	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
> +	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
>  	xfs_qm_dqdestroy(dqp);
>  }
>  
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 43b4650cdcdf..84cb8af468b7 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -20,12 +20,12 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>  #define XFS_DQITER_MAP_SIZE	10
>  
>  #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
> -	!dqp->q_core.d_blk_hardlimit && \
> -	!dqp->q_core.d_blk_softlimit && \
> -	!dqp->q_core.d_rtb_hardlimit && \
> -	!dqp->q_core.d_rtb_softlimit && \
> -	!dqp->q_core.d_ino_hardlimit && \
> -	!dqp->q_core.d_ino_softlimit && \
> +	!dqp->q_blk.hardlimit && \
> +	!dqp->q_blk.softlimit && \
> +	!dqp->q_rtb.hardlimit && \
> +	!dqp->q_rtb.softlimit && \
> +	!dqp->q_ino.hardlimit && \
> +	!dqp->q_ino.softlimit && \
>  	!dqp->q_core.d_bcount && \
>  	!dqp->q_core.d_rtbcount && \
>  	!dqp->q_core.d_icount)
> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index 94b2b4b0fc17..0993217e5ac8 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot(
>  {
>  	uint64_t		limit;
>  
> -	limit = dqp->q_core.d_blk_softlimit ?
> -		be64_to_cpu(dqp->q_core.d_blk_softlimit) :
> -		be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> +	limit = dqp->q_blk.softlimit ?
> +		dqp->q_blk.softlimit :
> +		dqp->q_blk.hardlimit;
>  	if (limit && statp->f_blocks > limit) {
>  		statp->f_blocks = limit;
>  		statp->f_bfree = statp->f_bavail =
> @@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot(
>  			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
>  	}
>  
> -	limit = dqp->q_core.d_ino_softlimit ?
> -		be64_to_cpu(dqp->q_core.d_ino_softlimit) :
> -		be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> +	limit = dqp->q_ino.softlimit ?
> +		dqp->q_ino.softlimit :
> +		dqp->q_ino.hardlimit;
>  	if (limit && statp->f_files > limit) {
>  		statp->f_files = limit;
>  		statp->f_ffree =
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 56fe80395679..ab596d389e3e 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -495,13 +495,13 @@ xfs_qm_scall_setqlim(
>  	 */
>  	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
> -			be64_to_cpu(ddq->d_blk_hardlimit);
> +			dqp->q_blk.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
> -			be64_to_cpu(ddq->d_blk_softlimit);
> +			dqp->q_blk.softlimit;
>  	if (hard == 0 || hard >= soft) {
> -		ddq->d_blk_hardlimit = cpu_to_be64(hard);
> -		ddq->d_blk_softlimit = cpu_to_be64(soft);
> +		dqp->q_blk.hardlimit = hard;
> +		dqp->q_blk.softlimit = soft;
>  		xfs_dquot_set_prealloc_limits(dqp);
>  		if (id == 0) {
>  			defq->bhardlimit = hard;
> @@ -512,13 +512,13 @@ xfs_qm_scall_setqlim(
>  	}
>  	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
> -			be64_to_cpu(ddq->d_rtb_hardlimit);
> +			dqp->q_rtb.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
> -			be64_to_cpu(ddq->d_rtb_softlimit);
> +			dqp->q_rtb.softlimit;
>  	if (hard == 0 || hard >= soft) {
> -		ddq->d_rtb_hardlimit = cpu_to_be64(hard);
> -		ddq->d_rtb_softlimit = cpu_to_be64(soft);
> +		dqp->q_rtb.hardlimit = hard;
> +		dqp->q_rtb.softlimit = soft;
>  		if (id == 0) {
>  			defq->rtbhardlimit = hard;
>  			defq->rtbsoftlimit = soft;
> @@ -529,13 +529,13 @@ xfs_qm_scall_setqlim(
>  
>  	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
>  		(xfs_qcnt_t) newlim->d_ino_hardlimit :
> -			be64_to_cpu(ddq->d_ino_hardlimit);
> +			dqp->q_ino.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
>  		(xfs_qcnt_t) newlim->d_ino_softlimit :
> -			be64_to_cpu(ddq->d_ino_softlimit);
> +			dqp->q_ino.softlimit;
>  	if (hard == 0 || hard >= soft) {
> -		ddq->d_ino_hardlimit = cpu_to_be64(hard);
> -		ddq->d_ino_softlimit = cpu_to_be64(soft);
> +		dqp->q_ino.hardlimit = hard;
> +		dqp->q_ino.softlimit = soft;
>  		if (id == 0) {
>  			defq->ihardlimit = hard;
>  			defq->isoftlimit = soft;
> @@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc(
>  	struct qc_dqblk		*dst)
>  {
>  	memset(dst, 0, sizeof(*dst));
> -	dst->d_spc_hardlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
> -	dst->d_spc_softlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
> +	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
> +	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
>  	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
>  	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
>  	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
> @@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc(
>  	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
>  	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
>  	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
> -	dst->d_rt_spc_hardlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
> -	dst->d_rt_spc_softlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
> +	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
> +	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>  	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>  	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>  	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> @@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc(
>  		    (dst->d_spc_softlimit > 0)) {
>  			ASSERT(dst->d_spc_timer != 0);
>  		}
> -		if ((dst->d_ino_count > dst->d_ino_softlimit) &&
> -		    (dst->d_ino_softlimit > 0)) {
> +		if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
> +		    (dqp->q_ino.softlimit > 0)) {
>  			ASSERT(dst->d_ino_timer != 0);
>  		}
>  	}
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 71567ed367f2..7f744a37dc0e 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>  		__entry->res_bcount = dqp->q_blk.reserved;
>  		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
>  		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
> -		__entry->blk_hardlimit =
> -			be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> -		__entry->blk_softlimit =
> -			be64_to_cpu(dqp->q_core.d_blk_softlimit);
> -		__entry->ino_hardlimit =
> -			be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> -		__entry->ino_softlimit =
> -			be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
> +		__entry->blk_softlimit = dqp->q_blk.softlimit;
> +		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
> +		__entry->ino_softlimit = dqp->q_ino.softlimit;
>  	),
>  	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
>  		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 469bf7946d3d..7a3d64eb9fbf 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -593,10 +593,10 @@ xfs_trans_dqresv(
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
>  
>  	if (flags & XFS_TRANS_DQ_RES_BLKS) {
> -		hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> +		hardlimit = dqp->q_blk.hardlimit;
>  		if (!hardlimit)
>  			hardlimit = defq->bhardlimit;
> -		softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
> +		softlimit = dqp->q_blk.softlimit;
>  		if (!softlimit)
>  			softlimit = defq->bsoftlimit;
>  		timer = be32_to_cpu(dqp->q_core.d_btimer);
> @@ -605,10 +605,10 @@ xfs_trans_dqresv(
>  		resbcountp = &dqp->q_blk.reserved;
>  	} else {
>  		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
> -		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
> +		hardlimit = dqp->q_rtb.hardlimit;
>  		if (!hardlimit)
>  			hardlimit = defq->rtbhardlimit;
> -		softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
> +		softlimit = dqp->q_rtb.softlimit;
>  		if (!softlimit)
>  			softlimit = defq->rtbsoftlimit;
>  		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> @@ -649,10 +649,10 @@ xfs_trans_dqresv(
>  			timer = be32_to_cpu(dqp->q_core.d_itimer);
>  			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>  			warnlimit = defq->iwarnlimit;
> -			hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> +			hardlimit = dqp->q_ino.hardlimit;
>  			if (!hardlimit)
>  				hardlimit = defq->ihardlimit;
> -			softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +			softlimit = dqp->q_ino.softlimit;
>  			if (!softlimit)
>  				softlimit = defq->isoftlimit;
>  
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 08/18] xfs: stop using q_core counters in the quota code
  2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:42 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add counter fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/scrub/quota.c     |   18 ++++++------------
>  fs/xfs/xfs_dquot.c       |   47 +++++++++++++++++++++++++---------------------
>  fs/xfs/xfs_dquot.h       |    3 +++
>  fs/xfs/xfs_qm.c          |    6 +++---
>  fs/xfs/xfs_qm.h          |    6 +++---
>  fs/xfs/xfs_trace.h       |    4 ++--
>  fs/xfs/xfs_trans_dquot.c |   36 ++++++++++++++---------------------
>  7 files changed, 57 insertions(+), 63 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 1a1c6996fc69..2fc2625feca0 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -82,9 +82,6 @@ xchk_quota_item(
>  	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  	xfs_fileoff_t		offset;
> -	unsigned long long	bcount;
> -	unsigned long long	icount;
> -	unsigned long long	rcount;
>  	xfs_ino_t		fs_icount;
>  	int			error = 0;
>  
> @@ -128,9 +125,6 @@ xchk_quota_item(
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
>  	/* Check the resource counts. */
> -	bcount = be64_to_cpu(d->d_bcount);
> -	icount = be64_to_cpu(d->d_icount);
> -	rcount = be64_to_cpu(d->d_rtbcount);
>  	fs_icount = percpu_counter_sum(&mp->m_icount);
>  
>  	/*
> @@ -139,15 +133,15 @@ xchk_quota_item(
>  	 * if there are no quota limits.
>  	 */
>  	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
> -		if (mp->m_sb.sb_dblocks < bcount)
> +		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
>  			xchk_fblock_set_warning(sc, XFS_DATA_FORK,
>  					offset);
>  	} else {
> -		if (mp->m_sb.sb_dblocks < bcount)
> +		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
>  			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
>  					offset);
>  	}
> -	if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks)
> +	if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks)
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
>  	/*
> @@ -159,15 +153,15 @@ xchk_quota_item(
>  		goto out;
>  
>  	if (dq->q_blk.hardlimit != 0 &&
> -	    bcount > dq->q_blk.hardlimit)
> +	    dq->q_blk.count > dq->q_blk.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
>  	if (dq->q_ino.hardlimit != 0 &&
> -	    icount > dq->q_ino.hardlimit)
> +	    dq->q_ino.count > dq->q_ino.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
>  	if (dq->q_rtb.hardlimit != 0 &&
> -	    rcount > dq->q_rtb.hardlimit)
> +	    dq->q_rtb.count > dq->q_rtb.hardlimit)
>  		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>  
>  out:
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 63f744bcbc90..02eae8c2ba1b 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers(
>  
>  	if (!d->d_btimer) {
>  		if ((dq->q_blk.softlimit &&
> -		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
> +		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
>  		    (dq->q_blk.hardlimit &&
> -		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
> +		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
>  			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->btimelimit);
>  		} else {
> @@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers(
>  		}
>  	} else {
>  		if ((!dq->q_blk.softlimit ||
> -		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
> +		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
>  		    (!dq->q_blk.hardlimit ||
> -		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
> +		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
>  			d->d_btimer = 0;
>  		}
>  	}
>  
>  	if (!d->d_itimer) {
>  		if ((dq->q_ino.softlimit &&
> -		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
> +		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
>  		    (dq->q_ino.hardlimit &&
> -		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
> +		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
>  			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->itimelimit);
>  		} else {
> @@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers(
>  		}
>  	} else {
>  		if ((!dq->q_ino.softlimit ||
> -		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
> +		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
>  		    (!dq->q_ino.hardlimit ||
> -		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
> +		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
>  			d->d_itimer = 0;
>  		}
>  	}
>  
>  	if (!d->d_rtbtimer) {
>  		if ((dq->q_rtb.softlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
> +		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
>  		    (dq->q_rtb.hardlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
> +		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
>  			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->rtbtimelimit);
>  		} else {
> @@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers(
>  		}
>  	} else {
>  		if ((!dq->q_rtb.softlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
> +		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
>  		    (!dq->q_rtb.hardlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
> +		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
>  			d->d_rtbtimer = 0;
>  		}
>  	}
> @@ -538,13 +538,17 @@ xfs_dquot_from_disk(
>  	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
>  	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
>  
> +	dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount);
> +	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
> +	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
> +
>  	/*
>  	 * Reservation counters are defined as reservation plus current usage
>  	 * to avoid having to add every time.
>  	 */
> -	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
> -	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
> -	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
> +	dqp->q_blk.reserved = dqp->q_blk.count;
> +	dqp->q_ino.reserved = dqp->q_ino.count;
> +	dqp->q_rtb.reserved = dqp->q_rtb.count;
>  
>  	/* initialize the dquot speculative prealloc thresholds */
>  	xfs_dquot_set_prealloc_limits(dqp);
> @@ -565,6 +569,10 @@ xfs_dquot_to_disk(
>  	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
>  	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
>  	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
> +
> +	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
> +	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
> +	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
>  }
>  
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check(
>  	if (dqp->q_id == 0)
>  		return NULL;
>  
> -	if (dqp->q_blk.softlimit &&
> -	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> +	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
>  	    !ddq->d_btimer)
>  		return __this_address;
>  
> -	if (dqp->q_ino.softlimit &&
> -	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> +	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
>  	    !ddq->d_itimer)
>  		return __this_address;
>  
> -	if (dqp->q_rtb.softlimit &&
> -	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> +	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
>  	    !ddq->d_rtbtimer)
>  		return __this_address;
>  
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index edb49788c476..23e05b0d7567 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -31,6 +31,9 @@ struct xfs_dquot_res {
>  	/* Total resources allocated and reserved. */
>  	xfs_qcnt_t		reserved;
>  
> +	/* Total resources allocated. */
> +	xfs_qcnt_t		count;
> +
>  	/* Absolute and preferred limits. */
>  	xfs_qcnt_t		hardlimit;
>  	xfs_qcnt_t		softlimit;
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 54fc3aac1a68..b47bba204240 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust(
>  	 * Adjust the inode count and the block count to reflect this inode's
>  	 * resource usage.
>  	 */
> -	be64_add_cpu(&dqp->q_core.d_icount, 1);
> +	dqp->q_ino.count++;
>  	dqp->q_ino.reserved++;
>  	if (nblks) {
> -		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
> +		dqp->q_blk.count += nblks;
>  		dqp->q_blk.reserved += nblks;
>  	}
>  	if (rtblks) {
> -		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
> +		dqp->q_rtb.count += rtblks;
>  		dqp->q_rtb.reserved += rtblks;
>  	}
>  
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 84cb8af468b7..6ed4ae942603 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -26,9 +26,9 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>  	!dqp->q_rtb.softlimit && \
>  	!dqp->q_ino.hardlimit && \
>  	!dqp->q_ino.softlimit && \
> -	!dqp->q_core.d_bcount && \
> -	!dqp->q_core.d_rtbcount && \
> -	!dqp->q_core.d_icount)
> +	!dqp->q_blk.count && \
> +	!dqp->q_rtb.count && \
> +	!dqp->q_ino.count)
>  
>  /*
>   * This defines the unit of allocation of dquots.
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 7f744a37dc0e..851f97dfe9e3 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>  		__entry->flags = dqp->dq_flags;
>  		__entry->nrefs = dqp->q_nrefs;
>  		__entry->res_bcount = dqp->q_blk.reserved;
> -		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
> -		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
> +		__entry->bcount = dqp->q_blk.count;
> +		__entry->icount = dqp->q_ino.count;
>  		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
>  		__entry->blk_softlimit = dqp->q_blk.softlimit;
>  		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 7a3d64eb9fbf..b36d747989a7 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas(
>  	int			i, j;
>  	struct xfs_dquot	*dqp;
>  	struct xfs_dqtrx	*qtrx, *qa;
> -	struct xfs_disk_dquot	*d;
>  	int64_t			totalbdelta;
>  	int64_t			totalrtbdelta;
>  
> @@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas(
>  			/*
>  			 * adjust the actual number of blocks used
>  			 */
> -			d = &dqp->q_core;
>  
>  			/*
>  			 * The issue here is - sometimes we don't make a blkquota
> @@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas(
>  				qtrx->qt_delrtb_delta;
>  #ifdef DEBUG
>  			if (totalbdelta < 0)
> -				ASSERT(be64_to_cpu(d->d_bcount) >=
> -				       -totalbdelta);
> +				ASSERT(dqp->q_blk.count >= -totalbdelta);
>  
>  			if (totalrtbdelta < 0)
> -				ASSERT(be64_to_cpu(d->d_rtbcount) >=
> -				       -totalrtbdelta);
> +				ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
>  
>  			if (qtrx->qt_icount_delta < 0)
> -				ASSERT(be64_to_cpu(d->d_icount) >=
> -				       -qtrx->qt_icount_delta);
> +				ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
>  #endif
>  			if (totalbdelta)
> -				be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
> +				dqp->q_blk.count += totalbdelta;
>  
>  			if (qtrx->qt_icount_delta)
> -				be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
> +				dqp->q_ino.count += qtrx->qt_icount_delta;
>  
>  			if (totalrtbdelta)
> -				be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
> +				dqp->q_rtb.count += totalrtbdelta;
>  
>  			/*
>  			 * Get any default limits in use.
> @@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas(
>  					    (xfs_qcnt_t)qtrx->qt_icount_delta;
>  			}
>  
> -			ASSERT(dqp->q_blk.reserved >=
> -				be64_to_cpu(dqp->q_core.d_bcount));
> -			ASSERT(dqp->q_ino.reserved >=
> -				be64_to_cpu(dqp->q_core.d_icount));
> -			ASSERT(dqp->q_rtb.reserved >=
> -				be64_to_cpu(dqp->q_core.d_rtbcount));
> +			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
> +			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
> +			ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
>  		}
>  	}
>  }
> @@ -645,7 +637,7 @@ xfs_trans_dqresv(
>  			}
>  		}
>  		if (ninos > 0) {
> -			total_count = dqp->q_res_icount + ninos;
> +			total_count = dqp->q_ino.reserved + ninos;
>  			timer = be32_to_cpu(dqp->q_core.d_itimer);
>  			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>  			warnlimit = defq->iwarnlimit;
> @@ -675,7 +667,7 @@ xfs_trans_dqresv(
>  
>  	/*
>  	 * Change the reservation, but not the actual usage.
> -	 * Note that q_blk.reserved = q_core.d_bcount + resv
> +	 * Note that q_blk.reserved = q_blk.count + resv
>  	 */
>  	(*resbcountp) += (xfs_qcnt_t)nblks;
>  	if (ninos != 0)
> @@ -700,9 +692,9 @@ xfs_trans_dqresv(
>  					    XFS_TRANS_DQ_RES_INOS,
>  					    ninos);
>  	}
> -	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
> -	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
> -	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
> +	ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
> +	ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
> +	ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
>  
>  	xfs_dqunlock(dqp);
>  	return 0;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 09/18] xfs: stop using q_core warning counters in the quota code
  2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
@ 2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:48 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add warning counter fields to the incore dquot, and use that instead of
> the ones in qcore.  This eliminates a bunch of endian conversions and
> will eventually allow us to remove qcore entirely.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |   14 +++++++++++---
>  fs/xfs/xfs_dquot.h       |    8 ++++++++
>  fs/xfs/xfs_qm.c          |   12 ++++++------
>  fs/xfs/xfs_qm_syscalls.c |   12 ++++++------
>  fs/xfs/xfs_trans_dquot.c |    6 +++---
>  5 files changed, 34 insertions(+), 18 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 02eae8c2ba1b..a1edb49ceda5 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers(
>  			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->btimelimit);
>  		} else {
> -			d->d_bwarns = 0;
> +			dq->q_blk.warnings = 0;
>  		}
>  	} else {
>  		if ((!dq->q_blk.softlimit ||
> @@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers(
>  			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->itimelimit);
>  		} else {
> -			d->d_iwarns = 0;
> +			dq->q_ino.warnings = 0;
>  		}
>  	} else {
>  		if ((!dq->q_ino.softlimit ||
> @@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers(
>  			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>  					defq->rtbtimelimit);
>  		} else {
> -			d->d_rtbwarns = 0;
> +			dq->q_rtb.warnings = 0;
>  		}
>  	} else {
>  		if ((!dq->q_rtb.softlimit ||
> @@ -542,6 +542,10 @@ xfs_dquot_from_disk(
>  	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
>  	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
>  
> +	dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns);
> +	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
> +	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
> +
>  	/*
>  	 * Reservation counters are defined as reservation plus current usage
>  	 * to avoid having to add every time.
> @@ -573,6 +577,10 @@ xfs_dquot_to_disk(
>  	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
>  	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
>  	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
> +
> +	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
> +	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
> +	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
>  }
>  
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 23e05b0d7567..5840bc54b772 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -37,6 +37,14 @@ struct xfs_dquot_res {
>  	/* Absolute and preferred limits. */
>  	xfs_qcnt_t		hardlimit;
>  	xfs_qcnt_t		softlimit;
> +
> +	/*
> +	 * For root dquots, this is the maximum number of warnings that will
> +	 * be issued for this quota type.  Otherwise, this is the number of
> +	 * warnings issued against this quota.  Note that none of this is
> +	 * implemented.
> +	 */
> +	xfs_qwarncnt_t		warnings;
>  };
>  
>  /*
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index b47bba204240..4e233cfef46d 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -616,12 +616,12 @@ xfs_qm_init_timelimits(
>  		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
>  	if (ddqp->d_rtbtimer)
>  		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
> -	if (ddqp->d_bwarns)
> -		defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns);
> -	if (ddqp->d_iwarns)
> -		defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns);
> -	if (ddqp->d_rtbwarns)
> -		defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns);
> +	if (dqp->q_blk.warnings)
> +		defq->bwarnlimit = dqp->q_blk.warnings;
> +	if (dqp->q_ino.warnings)
> +		defq->iwarnlimit = dqp->q_ino.warnings;
> +	if (dqp->q_rtb.warnings)
> +		defq->rtbwarnlimit = dqp->q_rtb.warnings;
>  
>  	xfs_qm_dqdestroy(dqp);
>  }
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index ab596d389e3e..5d3bccdbd3bf 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -548,11 +548,11 @@ xfs_qm_scall_setqlim(
>  	 * Update warnings counter(s) if requested
>  	 */
>  	if (newlim->d_fieldmask & QC_SPC_WARNS)
> -		ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns);
> +		dqp->q_blk.warnings = newlim->d_spc_warns;
>  	if (newlim->d_fieldmask & QC_INO_WARNS)
> -		ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns);
> +		dqp->q_ino.warnings = newlim->d_ino_warns;
>  	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -		ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns);
> +		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
>  
>  	if (id == 0) {
>  		if (newlim->d_fieldmask & QC_SPC_WARNS)
> @@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc(
>  	dst->d_ino_count = dqp->q_ino.reserved;
>  	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
>  	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
> -	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
> -	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
> +	dst->d_ino_warns = dqp->q_ino.warnings;
> +	dst->d_spc_warns = dqp->q_blk.warnings;
>  	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
>  	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>  	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>  	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> -	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> +	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
>  
>  	/*
>  	 * Internally, we don't reset all the timers when quota enforcement
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index b36d747989a7..21ed8eda3c80 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -592,7 +592,7 @@ xfs_trans_dqresv(
>  		if (!softlimit)
>  			softlimit = defq->bsoftlimit;
>  		timer = be32_to_cpu(dqp->q_core.d_btimer);
> -		warns = be16_to_cpu(dqp->q_core.d_bwarns);
> +		warns = dqp->q_blk.warnings;
>  		warnlimit = defq->bwarnlimit;
>  		resbcountp = &dqp->q_blk.reserved;
>  	} else {
> @@ -604,7 +604,7 @@ xfs_trans_dqresv(
>  		if (!softlimit)
>  			softlimit = defq->rtbsoftlimit;
>  		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> -		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> +		warns = dqp->q_rtb.warnings;
>  		warnlimit = defq->rtbwarnlimit;
>  		resbcountp = &dqp->q_rtb.reserved;
>  	}
> @@ -639,7 +639,7 @@ xfs_trans_dqresv(
>  		if (ninos > 0) {
>  			total_count = dqp->q_ino.reserved + ninos;
>  			timer = be32_to_cpu(dqp->q_core.d_itimer);
> -			warns = be16_to_cpu(dqp->q_core.d_iwarns);
> +			warns = dqp->q_ino.warnings;
>  			warnlimit = defq->iwarnlimit;
>  			hardlimit = dqp->q_ino.hardlimit;
>  			if (!hardlimit)
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush
  2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:32   ` Chandan Babu R
@ 2020-07-01  8:33   ` Christoph Hellwig
  2020-07-01 22:42     ` Dave Chinner
  2 siblings, 1 reply; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:33 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:41:56AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> can't lock the dquot buf to flush the dquot.  This prevents the AIL from
> blocking on the dquot, but it also forgets to clear the FREEING flag on
> its way out.  A subsequent purge attempt will see the FREEING flag is
> set and bail out, which leads to dqpurge_all failing to purge all the
> dquots.  This causes unmounts and quotaoff operations to hang.
> 
> Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks like Dave submitted this as a separate fix just after you..

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 10/18] xfs: stop using q_core timers in the quota code
  2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
@ 2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:34 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:54 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add timers fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |   41 +++++++++++++++++++++++------------------
>  fs/xfs/xfs_dquot.h       |    7 +++++++
>  fs/xfs/xfs_qm.c          |   15 ++++++---------
>  fs/xfs/xfs_qm_syscalls.c |   18 ++++++++----------
>  fs/xfs/xfs_trans_dquot.c |    6 +++---
>  5 files changed, 47 insertions(+), 40 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index a1edb49ceda5..7434ee57ec43 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers(
>  	struct xfs_dquot	*dq)
>  {
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_def_quota	*defq;
>  
>  	ASSERT(dq->q_id);
> @@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers(
>  		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
>  #endif
>  
> -	if (!d->d_btimer) {
> +	if (!dq->q_blk.timer) {
>  		if ((dq->q_blk.softlimit &&
>  		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
>  		    (dq->q_blk.hardlimit &&
>  		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
> -			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->btimelimit);
> +			dq->q_blk.timer = ktime_get_real_seconds() +
> +					defq->btimelimit;
>  		} else {
>  			dq->q_blk.warnings = 0;
>  		}
> @@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers(
>  		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
>  		    (!dq->q_blk.hardlimit ||
>  		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
> -			d->d_btimer = 0;
> +			dq->q_blk.timer = 0;
>  		}
>  	}
>  
> -	if (!d->d_itimer) {
> +	if (!dq->q_ino.timer) {
>  		if ((dq->q_ino.softlimit &&
>  		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
>  		    (dq->q_ino.hardlimit &&
>  		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
> -			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->itimelimit);
> +			dq->q_ino.timer = ktime_get_real_seconds() +
> +					defq->itimelimit;
>  		} else {
>  			dq->q_ino.warnings = 0;
>  		}
> @@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers(
>  		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
>  		    (!dq->q_ino.hardlimit ||
>  		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
> -			d->d_itimer = 0;
> +			dq->q_ino.timer = 0;
>  		}
>  	}
>  
> -	if (!d->d_rtbtimer) {
> +	if (!dq->q_rtb.timer) {
>  		if ((dq->q_rtb.softlimit &&
>  		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
>  		    (dq->q_rtb.hardlimit &&
>  		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
> -			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->rtbtimelimit);
> +			dq->q_rtb.timer = ktime_get_real_seconds() +
> +					defq->rtbtimelimit;
>  		} else {
>  			dq->q_rtb.warnings = 0;
>  		}
> @@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers(
>  		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
>  		    (!dq->q_rtb.hardlimit ||
>  		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
> -			d->d_rtbtimer = 0;
> +			dq->q_rtb.timer = 0;
>  		}
>  	}
>  }
> @@ -546,6 +545,10 @@ xfs_dquot_from_disk(
>  	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
>  	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
>  
> +	dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer);
> +	dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer);
> +	dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer);
> +
>  	/*
>  	 * Reservation counters are defined as reservation plus current usage
>  	 * to avoid having to add every time.
> @@ -581,6 +584,10 @@ xfs_dquot_to_disk(
>  	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
>  	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
>  	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
> +
> +	ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer);
> +	ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer);
> +	ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer);
>  }
>  
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1135,8 +1142,6 @@ static xfs_failaddr_t
>  xfs_qm_dqflush_check(
>  	struct xfs_dquot	*dqp)
>  {
> -	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> -
>  	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
>  		return __this_address;
>  
> @@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check(
>  		return NULL;
>  
>  	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
> -	    !ddq->d_btimer)
> +	    !dqp->q_blk.timer)
>  		return __this_address;
>  
>  	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
> -	    !ddq->d_itimer)
> +	    !dqp->q_ino.timer)
>  		return __this_address;
>  
>  	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
> -	    !ddq->d_rtbtimer)
> +	    !dqp->q_rtb.timer)
>  		return __this_address;
>  
>  	return NULL;
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 5840bc54b772..414bae537b1d 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -38,6 +38,13 @@ struct xfs_dquot_res {
>  	xfs_qcnt_t		hardlimit;
>  	xfs_qcnt_t		softlimit;
>  
> +	/*
> +	 * For root dquots, this is the default grace period, in seconds.
> +	 * Otherwise, this is when the quota grace period expires,
> +	 * in seconds since the Unix epoch.
> +	 */
> +	time64_t		timer;
> +
>  	/*
>  	 * For root dquots, this is the maximum number of warnings that will
>  	 * be issued for this quota type.  Otherwise, this is the number of
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 4e233cfef46d..a56c6e4a5d99 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -579,7 +579,6 @@ xfs_qm_init_timelimits(
>  {
>  	struct xfs_quotainfo	*qinf = mp->m_quotainfo;
>  	struct xfs_def_quota	*defq;
> -	struct xfs_disk_dquot	*ddqp;
>  	struct xfs_dquot	*dqp;
>  	int			error;
>  
> @@ -603,19 +602,17 @@ xfs_qm_init_timelimits(
>  	if (error)
>  		return;
>  
> -	ddqp = &dqp->q_core;
> -
>  	/*
>  	 * The warnings and timers set the grace period given to
>  	 * a user or group before he or she can not perform any
>  	 * more writing. If it is zero, a default is used.
>  	 */
> -	if (ddqp->d_btimer)
> -		defq->btimelimit = be32_to_cpu(ddqp->d_btimer);
> -	if (ddqp->d_itimer)
> -		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
> -	if (ddqp->d_rtbtimer)
> -		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
> +	if (dqp->q_blk.timer)
> +		defq->btimelimit = dqp->q_blk.timer;
> +	if (dqp->q_ino.timer)
> +		defq->itimelimit = dqp->q_ino.timer;
> +	if (dqp->q_rtb.timer)
> +		defq->rtbtimelimit = dqp->q_rtb.timer;
>  	if (dqp->q_blk.warnings)
>  		defq->bwarnlimit = dqp->q_blk.warnings;
>  	if (dqp->q_ino.warnings)
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 5d3bccdbd3bf..1b2b70b1660f 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -447,7 +447,6 @@ xfs_qm_scall_setqlim(
>  	struct qc_dqblk		*newlim)
>  {
>  	struct xfs_quotainfo	*q = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*ddq;
>  	struct xfs_dquot	*dqp;
>  	struct xfs_trans	*tp;
>  	struct xfs_def_quota	*defq;
> @@ -488,7 +487,6 @@ xfs_qm_scall_setqlim(
>  
>  	xfs_dqlock(dqp);
>  	xfs_trans_dqjoin(tp, dqp);
> -	ddq = &dqp->q_core;
>  
>  	/*
>  	 * Make sure that hardlimits are >= soft limits before changing.
> @@ -573,11 +571,11 @@ xfs_qm_scall_setqlim(
>  	 * the soft limit.
>  	 */
>  	if (newlim->d_fieldmask & QC_SPC_TIMER)
> -		ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer);
> +		dqp->q_blk.timer = newlim->d_spc_timer;
>  	if (newlim->d_fieldmask & QC_INO_TIMER)
> -		ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer);
> +		dqp->q_ino.timer = newlim->d_ino_timer;
>  	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -		ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer);
> +		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
>  
>  	if (id == 0) {
>  		if (newlim->d_fieldmask & QC_SPC_TIMER)
> @@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc(
>  	memset(dst, 0, sizeof(*dst));
>  	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
>  	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
> -	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> -	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +	dst->d_ino_hardlimit = dqp->q_ino.hardlimit;
> +	dst->d_ino_softlimit = dqp->q_ino.softlimit;
>  	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
>  	dst->d_ino_count = dqp->q_ino.reserved;
> -	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
> -	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
> +	dst->d_spc_timer = dqp->q_blk.timer;
> +	dst->d_ino_timer = dqp->q_ino.timer;
>  	dst->d_ino_warns = dqp->q_ino.warnings;
>  	dst->d_spc_warns = dqp->q_blk.warnings;
>  	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
>  	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>  	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
> -	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> +	dst->d_rt_spc_timer = dqp->q_rtb.timer;
>  	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
>  
>  	/*
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 21ed8eda3c80..28b59a4069a3 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -591,7 +591,7 @@ xfs_trans_dqresv(
>  		softlimit = dqp->q_blk.softlimit;
>  		if (!softlimit)
>  			softlimit = defq->bsoftlimit;
> -		timer = be32_to_cpu(dqp->q_core.d_btimer);
> +		timer = dqp->q_blk.timer;
>  		warns = dqp->q_blk.warnings;
>  		warnlimit = defq->bwarnlimit;
>  		resbcountp = &dqp->q_blk.reserved;
> @@ -603,7 +603,7 @@ xfs_trans_dqresv(
>  		softlimit = dqp->q_rtb.softlimit;
>  		if (!softlimit)
>  			softlimit = defq->rtbsoftlimit;
> -		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> +		timer = dqp->q_rtb.timer;
>  		warns = dqp->q_rtb.warnings;
>  		warnlimit = defq->rtbwarnlimit;
>  		resbcountp = &dqp->q_rtb.reserved;
> @@ -638,7 +638,7 @@ xfs_trans_dqresv(
>  		}
>  		if (ninos > 0) {
>  			total_count = dqp->q_ino.reserved + ninos;
> -			timer = be32_to_cpu(dqp->q_core.d_itimer);
> +			timer = dqp->q_ino.timer;
>  			warns = dqp->q_ino.warnings;
>  			warnlimit = defq->iwarnlimit;
>  			hardlimit = dqp->q_ino.hardlimit;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
@ 2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:52   ` Christoph Hellwig
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:34 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:01 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've stopped using qcore entirely, drop it from the incore
> dquot.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/scrub/quota.c |    4 ----
>  fs/xfs/xfs_dquot.c   |   29 +++++++++--------------------
>  fs/xfs/xfs_dquot.h   |    1 -
>  3 files changed, 9 insertions(+), 25 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 2fc2625feca0..f4aad5b00188 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -79,7 +79,6 @@ xchk_quota_item(
>  	struct xchk_quota_info	*sqi = priv;
>  	struct xfs_scrub	*sc = sqi->sc;
>  	struct xfs_mount	*mp = sc->mp;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  	xfs_fileoff_t		offset;
>  	xfs_ino_t		fs_icount;
> @@ -98,9 +97,6 @@ xchk_quota_item(
>  
>  	sqi->last_id = dq->q_id;
>  
> -	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
> -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> -
>  	/*
>  	 * Warn if the hard limits are larger than the fs.
>  	 * Administrators can do this, though in production this seems
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 7434ee57ec43..2d6b50760962 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -529,7 +529,6 @@ xfs_dquot_from_disk(
>  	}
>  
>  	/* copy everything from disk dquot to the incore dquot */
> -	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
>  	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
>  	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
>  	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> @@ -568,8 +567,13 @@ xfs_dquot_to_disk(
>  	struct xfs_disk_dquot	*ddqp,
>  	struct xfs_dquot	*dqp)
>  {
> -	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
> +	ddqp->d_version = XFS_DQUOT_VERSION;
>  	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +	ddqp->d_id = cpu_to_be32(dqp->q_id);
> +	ddqp->d_pad0 = 0;
> +	ddqp->d_pad = 0;
> +
>  	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
>  	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
>  	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
> @@ -1180,7 +1184,6 @@ xfs_qm_dqflush(
>  	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
>  	struct xfs_buf		*bp;
>  	struct xfs_dqblk	*dqb;
> -	struct xfs_disk_dquot	*ddqp;
>  	xfs_failaddr_t		fa;
>  	int			error;
>  
> @@ -1204,22 +1207,6 @@ xfs_qm_dqflush(
>  	if (error)
>  		goto out_abort;
>  
> -	/*
> -	 * Calculate the location of the dquot inside the buffer.
> -	 */
> -	dqb = bp->b_addr + dqp->q_bufoffset;
> -	ddqp = &dqb->dd_diskdq;
> -
> -	/* sanity check the in-core structure before we flush */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
> -	if (fa) {
> -		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				dqp->q_id, fa);
> -		xfs_buf_relse(bp);
> -		error = -EFSCORRUPTED;
> -		goto out_abort;
> -	}
> -
>  	fa = xfs_qm_dqflush_check(dqp);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> @@ -1229,7 +1216,9 @@ xfs_qm_dqflush(
>  		goto out_abort;
>  	}
>  
> -	xfs_dquot_to_disk(ddqp, dqp);
> +	/* Flush the incore dquot to the ondisk buffer. */
> +	dqb = bp->b_addr + dqp->q_bufoffset;
> +	xfs_dquot_to_disk(&dqb->dd_diskdq, dqp);
>  
>  	/*
>  	 * Clear the dirty field and remember the flush lsn for later use.
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 414bae537b1d..62b0fc6e0133 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -71,7 +71,6 @@ struct xfs_dquot {
>  	struct xfs_dquot_res	q_ino;	/* inodes */
>  	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
>  
> -	struct xfs_disk_dquot	q_core;
>  	struct xfs_dq_logitem	q_logitem;
>  
>  	xfs_qcnt_t		q_prealloc_lo_wmark;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
@ 2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:47   ` Christoph Hellwig
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:34 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:12:16 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Use the incore dq_flags to figure out the dquot type.  This is the first
> step towards removing xfs_disk_dquot from the incore dquot.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
>  fs/xfs/scrub/quota.c           |    4 ----
>  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
>  fs/xfs/xfs_dquot.h             |    2 ++
>  fs/xfs/xfs_dquot_item.c        |    6 ++++--
>  fs/xfs/xfs_qm.c                |    4 ++--
>  fs/xfs/xfs_qm.h                |    2 +-
>  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
>  8 files changed, 45 insertions(+), 17 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> index 56d9dd787e7b..459023b0a304 100644
> --- a/fs/xfs/libxfs/xfs_quota_defs.h
> +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
>  
>  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
>  
> +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> +
>  #define XFS_DQ_FLAGS \
>  	{ XFS_DQ_USER,		"USER" }, \
>  	{ XFS_DQ_PROJ,		"PROJ" }, \
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 905a34558361..710659d3fa28 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -108,10 +108,6 @@ xchk_quota_item(
>  
>  	sqi->last_id = id;
>  
> -	/* Did we get the dquot type we wanted? */
> -	if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
> -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> -
>  	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 46c8ca83c04d..59d1bce34a98 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -561,6 +561,16 @@ xfs_dquot_from_disk(
>  	return 0;
>  }
>  
> +/* Copy the in-core quota fields into the on-disk buffer. */
> +void
> +xfs_dquot_to_disk(
> +	struct xfs_disk_dquot	*ddqp,
> +	struct xfs_dquot	*dqp)
> +{
> +	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +}
> +
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
>  static int
>  xfs_qm_dqread_alloc(
> @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done(
>  	xfs_dqfunlock(dqp);
>  }
>  
> +/* Check incore dquot for errors before we flush. */
> +static xfs_failaddr_t
> +xfs_qm_dqflush_check(
> +	struct xfs_dquot	*dqp)
> +{
> +	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> +		return __this_address;
> +
> +	return NULL;
> +}
> +
>  /*
>   * Write a modified dquot to disk.
>   * The dquot must be locked and the flush lock too taken by caller.
> @@ -1166,8 +1187,16 @@ xfs_qm_dqflush(
>  		goto out_abort;
>  	}
>  
> -	/* This is the only portion of data that needs to persist */
> -	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	fa = xfs_qm_dqflush_check(dqp);
> +	if (fa) {
> +		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> +				be32_to_cpu(dqp->q_core.d_id), fa);
> +		xfs_buf_relse(bp);
> +		error = -EFSCORRUPTED;
> +		goto out_abort;
> +	}
> +
> +	xfs_dquot_to_disk(ddqp, dqp);
>  
>  	/*
>  	 * Clear the dirty field and remember the flush lsn for later use.
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 71e36c85e20b..1b1a4261a580 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>  	return false;
>  }
>  
> +void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
> +
>  #define XFS_DQ_IS_LOCKED(dqp)	(mutex_is_locked(&((dqp)->q_qlock)))
>  #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
>  #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
> diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
> index 349c92d26570..ff0ab65cf413 100644
> --- a/fs/xfs/xfs_dquot_item.c
> +++ b/fs/xfs/xfs_dquot_item.c
> @@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format(
>  	struct xfs_log_item	*lip,
>  	struct xfs_log_vec	*lv)
>  {
> +	struct xfs_disk_dquot	ddq;
>  	struct xfs_dq_logitem	*qlip = DQUOT_ITEM(lip);
>  	struct xfs_log_iovec	*vecp = NULL;
>  	struct xfs_dq_logformat	*qlf;
> @@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format(
>  	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
>  	xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
>  
> -	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
> -			&qlip->qli_dquot->q_core,
> +	xfs_dquot_to_disk(&ddq, qlip->qli_dquot);
> +
> +	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq,
>  			sizeof(struct xfs_disk_dquot));
>  }
>  
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 938023dd8ce5..632025c2f00b 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -161,7 +161,7 @@ xfs_qm_dqpurge(
>  	xfs_dqfunlock(dqp);
>  	xfs_dqunlock(dqp);
>  
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
>  			  be32_to_cpu(dqp->q_core.d_id));
>  	qi->qi_dquots--;
>  
> @@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one(
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  
>  	mutex_lock(&qi->qi_tree_lock);
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
>  			  be32_to_cpu(dqp->q_core.d_id));
>  
>  	qi->qi_dquots--;
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 7b0e771fcbce..43b4650cdcdf 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -85,7 +85,7 @@ xfs_dquot_tree(
>  	struct xfs_quotainfo	*qi,
>  	int			type)
>  {
> -	switch (type) {
> +	switch (type & XFS_DQ_ALLTYPES) {
>  	case XFS_DQ_USER:
>  		return &qi->qi_uquota_tree;
>  	case XFS_DQ_GROUP:
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 7effd7a28136..8cbb65f01bf1 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc(
>  	 * gets turned off. No need to confuse the user level code,
>  	 * so return zeroes in that case.
>  	 */
> -	if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_USER) ||
> -	    (!XFS_IS_GQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_GROUP) ||
> -	    (!XFS_IS_PQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_PROJ)) {
> +	if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) ||
> +	    (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) ||
> +	    (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) {
>  		dst->d_spc_timer = 0;
>  		dst->d_ino_timer = 0;
>  		dst->d_rt_spc_timer = 0;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 02/18] xfs: fix inode quota reservation checks
  2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:34   ` Christoph Hellwig
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:34 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
  2020-06-30 21:35   ` Allison Collins
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:42   ` Christoph Hellwig
  2020-07-01 18:25     ` Darrick J. Wong
  2020-07-01 22:41   ` Dave Chinner
  3 siblings, 1 reply; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:42 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
>  }
>  
>  /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
>  xfs_dquot_from_disk(
>  	struct xfs_dquot	*dqp,
>  	struct xfs_buf		*bp)
>  {
>  	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
>  
> +	/*
> +	 * The only field the verifier didn't check was the quota type flag, so
> +	 * do that here.
> +	 */
> +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> +	    dqp->q_core.d_id != ddqp->d_id) {

The comment looks a little weird, as this also checks d_id.  Also
xfs_dquot_verify verifies d_flags against generally bogus value, it
just doesn't check that it matches the type we are looking for.
Last but not least dqp->dq_flags only contains the type at this
point.

So what about something like:

	/*
	 * Ensure we got the type and ID we were looking for.  Everything else
	 * we checked by the verifier.
	 */
	if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
	    ddqp->d_id != dqp->q_core.d_id)


^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
@ 2020-07-01  8:47   ` Christoph Hellwig
  2020-07-01 19:02     ` Darrick J. Wong
  2020-07-01 20:15   ` Allison Collins
  2020-07-01 22:50   ` Dave Chinner
  3 siblings, 1 reply; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:47 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

>  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
>  
> +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> +

I really wonder if we should split the on-disk type and the in-core
flags properly instead.

That is propagate the u8 flags from the on-disk field directly,
and use a separate field for the in-memory flags dirty and freeing
flags, as that this kind of mixing up is bound to eventually create
problems.

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 05/18] xfs: stop using q_core.d_id in the quota code
  2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:48   ` Christoph Hellwig
  2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:48 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:23AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add a dquot id field to the incore dquot, and use that instead of the
> one in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> We also rearrange the start of xfs_dquot to remove padding holes, saving
> 8 bytes.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 06/18] xfs: use a per-resource struct for incore dquot data
  2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:49   ` Christoph Hellwig
  2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:49 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:29AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce a new struct xfs_dquot_res that we'll use to track all the
> incore data for a particular resource type (block, inode, rt block).
> This will help us (once we've eliminated q_core) to declutter quota
> functions that currently open-code field access or pass around fields
> around explicitly.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:50   ` Christoph Hellwig
  2020-07-01 20:16   ` Allison Collins
  2020-07-01 23:01   ` Dave Chinner
  3 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add limits fields in the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 08/18] xfs: stop using q_core counters in the quota code
  2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:42AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add counter fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 09/18] xfs: stop using q_core warning counters in the quota code
  2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
@ 2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:48AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add warning counter fields to the incore dquot, and use that instead of
> the ones in qcore.  This eliminates a bunch of endian conversions and
> will eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 10/18] xfs: stop using q_core timers in the quota code
  2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
@ 2020-07-01  8:51   ` Christoph Hellwig
  2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:54AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add timers fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
@ 2020-07-01  8:52   ` Christoph Hellwig
  2020-07-01 23:07   ` Dave Chinner
  2020-07-02  2:06   ` Allison Collins
  3 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've stopped using qcore entirely, drop it from the incore
> dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
@ 2020-07-01  8:52   ` Chandan Babu R
  2020-07-01  8:53   ` Christoph Hellwig
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:07 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've split up the dquot resource fields into separate structs,
> do the same for the default limits to enable further refactoring.
>

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |   30 +++++++++++++++---------------
>  fs/xfs/xfs_qm.c          |   36 ++++++++++++++++++------------------
>  fs/xfs/xfs_qm.h          |   22 ++++++++++------------
>  fs/xfs/xfs_qm_syscalls.c |   24 ++++++++++++------------
>  fs/xfs/xfs_quotaops.c    |   12 ++++++------
>  fs/xfs/xfs_trans_dquot.c |   18 +++++++++---------
>  6 files changed, 70 insertions(+), 72 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 2d6b50760962..6975c27145fc 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits(
>  	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>  
> -	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> -		dq->q_blk.softlimit = defq->bsoftlimit;
> +	if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) {
> +		dq->q_blk.softlimit = defq->dfq_blk.softlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> -		dq->q_blk.hardlimit = defq->bhardlimit;
> +	if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) {
> +		dq->q_blk.hardlimit = defq->dfq_blk.hardlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->isoftlimit && !dq->q_ino.softlimit)
> -		dq->q_ino.softlimit = defq->isoftlimit;
> -	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> -		dq->q_ino.hardlimit = defq->ihardlimit;
> -	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> -		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> -	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> -		dq->q_rtb.hardlimit = defq->rtbhardlimit;
> +	if (defq->dfq_ino.softlimit && !dq->q_ino.softlimit)
> +		dq->q_ino.softlimit = defq->dfq_ino.softlimit;
> +	if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit)
> +		dq->q_ino.hardlimit = defq->dfq_ino.hardlimit;
> +	if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit)
> +		dq->q_rtb.softlimit = defq->dfq_rtb.softlimit;
> +	if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit)
> +		dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit;
>  
>  	if (prealloc)
>  		xfs_dquot_set_prealloc_limits(dq);
> @@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers(
>  		    (dq->q_blk.hardlimit &&
>  		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
>  			dq->q_blk.timer = ktime_get_real_seconds() +
> -					defq->btimelimit;
> +					defq->dfq_blk.timelimit;
>  		} else {
>  			dq->q_blk.warnings = 0;
>  		}
> @@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers(
>  		    (dq->q_ino.hardlimit &&
>  		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
>  			dq->q_ino.timer = ktime_get_real_seconds() +
> -					defq->itimelimit;
> +					defq->dfq_ino.timelimit;
>  		} else {
>  			dq->q_ino.warnings = 0;
>  		}
> @@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers(
>  		    (dq->q_rtb.hardlimit &&
>  		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
>  			dq->q_rtb.timer = ktime_get_real_seconds() +
> -					defq->rtbtimelimit;
> +					defq->dfq_rtb.timelimit;
>  		} else {
>  			dq->q_rtb.warnings = 0;
>  		}
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index a56c6e4a5d99..28326a6264a8 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -562,12 +562,12 @@ xfs_qm_set_defquota(
>  	 * Timers and warnings have been already set, let's just set the
>  	 * default limits for this quota type
>  	 */
> -	defq->bhardlimit = dqp->q_blk.hardlimit;
> -	defq->bsoftlimit = dqp->q_blk.softlimit;
> -	defq->ihardlimit = dqp->q_ino.hardlimit;
> -	defq->isoftlimit = dqp->q_ino.softlimit;
> -	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
> -	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
> +	defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit;
> +	defq->dfq_blk.softlimit = dqp->q_blk.softlimit;
> +	defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit;
> +	defq->dfq_ino.softlimit = dqp->q_ino.softlimit;
> +	defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit;
> +	defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit;
>  	xfs_qm_dqdestroy(dqp);
>  }
>  
> @@ -584,12 +584,12 @@ xfs_qm_init_timelimits(
>  
>  	defq = xfs_get_defquota(qinf, type);
>  
> -	defq->btimelimit = XFS_QM_BTIMELIMIT;
> -	defq->itimelimit = XFS_QM_ITIMELIMIT;
> -	defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT;
> -	defq->bwarnlimit = XFS_QM_BWARNLIMIT;
> -	defq->iwarnlimit = XFS_QM_IWARNLIMIT;
> -	defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
> +	defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT;
> +	defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT;
> +	defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT;
> +	defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT;
> +	defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT;
> +	defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT;
>  
>  	/*
>  	 * We try to get the limits from the superuser's limits fields.
> @@ -608,17 +608,17 @@ xfs_qm_init_timelimits(
>  	 * more writing. If it is zero, a default is used.
>  	 */
>  	if (dqp->q_blk.timer)
> -		defq->btimelimit = dqp->q_blk.timer;
> +		defq->dfq_blk.timelimit = dqp->q_blk.timer;
>  	if (dqp->q_ino.timer)
> -		defq->itimelimit = dqp->q_ino.timer;
> +		defq->dfq_ino.timelimit = dqp->q_ino.timer;
>  	if (dqp->q_rtb.timer)
> -		defq->rtbtimelimit = dqp->q_rtb.timer;
> +		defq->dfq_rtb.timelimit = dqp->q_rtb.timer;
>  	if (dqp->q_blk.warnings)
> -		defq->bwarnlimit = dqp->q_blk.warnings;
> +		defq->dfq_blk.warnlimit = dqp->q_blk.warnings;
>  	if (dqp->q_ino.warnings)
> -		defq->iwarnlimit = dqp->q_ino.warnings;
> +		defq->dfq_ino.warnlimit = dqp->q_ino.warnings;
>  	if (dqp->q_rtb.warnings)
> -		defq->rtbwarnlimit = dqp->q_rtb.warnings;
> +		defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings;
>  
>  	xfs_qm_dqdestroy(dqp);
>  }
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 6ed4ae942603..e2f0027f0ac1 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -41,20 +41,18 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>   */
>  #define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
>  
> +struct xfs_def_qres {
> +	xfs_qcnt_t		hardlimit;	/* default hard limit */
> +	xfs_qcnt_t		softlimit;	/* default soft limit */
> +	time64_t		timelimit;	/* limit for timers */
> +	xfs_qwarncnt_t		warnlimit;	/* limit for warnings */
> +};
> +
>  /* Defaults for each quota type: time limits, warn limits, usage limits */
>  struct xfs_def_quota {
> -	time64_t	btimelimit;	/* limit for blks timer */
> -	time64_t	itimelimit;	/* limit for inodes timer */
> -	time64_t	rtbtimelimit;	/* limit for rt blks timer */
> -	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
> -	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
> -	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
> -	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
> -	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
> -	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
> -	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
> -	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
> -	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
> +	struct xfs_def_qres	dfq_blk;
> +	struct xfs_def_qres	dfq_ino;
> +	struct xfs_def_qres	dfq_rtb;
>  };
>  
>  /*
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 1b2b70b1660f..393b88612cc8 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim(
>  		dqp->q_blk.softlimit = soft;
>  		xfs_dquot_set_prealloc_limits(dqp);
>  		if (id == 0) {
> -			defq->bhardlimit = hard;
> -			defq->bsoftlimit = soft;
> +			defq->dfq_blk.hardlimit = hard;
> +			defq->dfq_blk.softlimit = soft;
>  		}
>  	} else {
>  		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
> @@ -518,8 +518,8 @@ xfs_qm_scall_setqlim(
>  		dqp->q_rtb.hardlimit = hard;
>  		dqp->q_rtb.softlimit = soft;
>  		if (id == 0) {
> -			defq->rtbhardlimit = hard;
> -			defq->rtbsoftlimit = soft;
> +			defq->dfq_rtb.hardlimit = hard;
> +			defq->dfq_rtb.softlimit = soft;
>  		}
>  	} else {
>  		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
> @@ -535,8 +535,8 @@ xfs_qm_scall_setqlim(
>  		dqp->q_ino.hardlimit = hard;
>  		dqp->q_ino.softlimit = soft;
>  		if (id == 0) {
> -			defq->ihardlimit = hard;
> -			defq->isoftlimit = soft;
> +			defq->dfq_ino.hardlimit = hard;
> +			defq->dfq_ino.softlimit = soft;
>  		}
>  	} else {
>  		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
> @@ -554,11 +554,11 @@ xfs_qm_scall_setqlim(
>  
>  	if (id == 0) {
>  		if (newlim->d_fieldmask & QC_SPC_WARNS)
> -			defq->bwarnlimit = newlim->d_spc_warns;
> +			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
>  		if (newlim->d_fieldmask & QC_INO_WARNS)
> -			defq->iwarnlimit = newlim->d_ino_warns;
> +			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
>  		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -			defq->rtbwarnlimit = newlim->d_rt_spc_warns;
> +			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
>  	}
>  
>  	/*
> @@ -579,11 +579,11 @@ xfs_qm_scall_setqlim(
>  
>  	if (id == 0) {
>  		if (newlim->d_fieldmask & QC_SPC_TIMER)
> -			defq->btimelimit = newlim->d_spc_timer;
> +			defq->dfq_blk.timelimit = newlim->d_spc_timer;
>  		if (newlim->d_fieldmask & QC_INO_TIMER)
> -			defq->itimelimit = newlim->d_ino_timer;
> +			defq->dfq_ino.timelimit = newlim->d_ino_timer;
>  		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -			defq->rtbtimelimit = newlim->d_rt_spc_timer;
> +			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
>  	}
>  
>  	if (id != 0) {
> diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
> index bf809b77a316..c86a6fe263da 100644
> --- a/fs/xfs/xfs_quotaops.c
> +++ b/fs/xfs/xfs_quotaops.c
> @@ -37,12 +37,12 @@ xfs_qm_fill_state(
>  	tstate->flags |= QCI_SYSFILE;
>  	tstate->blocks = ip->i_d.di_nblocks;
>  	tstate->nextents = ip->i_df.if_nextents;
> -	tstate->spc_timelimit = (u32)defq->btimelimit;
> -	tstate->ino_timelimit = (u32)defq->itimelimit;
> -	tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit;
> -	tstate->spc_warnlimit = defq->bwarnlimit;
> -	tstate->ino_warnlimit = defq->iwarnlimit;
> -	tstate->rt_spc_warnlimit = defq->rtbwarnlimit;
> +	tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit;
> +	tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit;
> +	tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit;
> +	tstate->spc_warnlimit = defq->dfq_blk.warnlimit;
> +	tstate->ino_warnlimit = defq->dfq_ino.warnlimit;
> +	tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit;
>  	if (tempqip)
>  		xfs_irele(ip);
>  }
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 28b59a4069a3..392e51baad6f 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -587,25 +587,25 @@ xfs_trans_dqresv(
>  	if (flags & XFS_TRANS_DQ_RES_BLKS) {
>  		hardlimit = dqp->q_blk.hardlimit;
>  		if (!hardlimit)
> -			hardlimit = defq->bhardlimit;
> +			hardlimit = defq->dfq_blk.hardlimit;
>  		softlimit = dqp->q_blk.softlimit;
>  		if (!softlimit)
> -			softlimit = defq->bsoftlimit;
> +			softlimit = defq->dfq_blk.softlimit;
>  		timer = dqp->q_blk.timer;
>  		warns = dqp->q_blk.warnings;
> -		warnlimit = defq->bwarnlimit;
> +		warnlimit = defq->dfq_blk.warnlimit;
>  		resbcountp = &dqp->q_blk.reserved;
>  	} else {
>  		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
>  		hardlimit = dqp->q_rtb.hardlimit;
>  		if (!hardlimit)
> -			hardlimit = defq->rtbhardlimit;
> +			hardlimit = defq->dfq_rtb.hardlimit;
>  		softlimit = dqp->q_rtb.softlimit;
>  		if (!softlimit)
> -			softlimit = defq->rtbsoftlimit;
> +			softlimit = defq->dfq_rtb.softlimit;
>  		timer = dqp->q_rtb.timer;
>  		warns = dqp->q_rtb.warnings;
> -		warnlimit = defq->rtbwarnlimit;
> +		warnlimit = defq->dfq_rtb.warnlimit;
>  		resbcountp = &dqp->q_rtb.reserved;
>  	}
>  
> @@ -640,13 +640,13 @@ xfs_trans_dqresv(
>  			total_count = dqp->q_ino.reserved + ninos;
>  			timer = dqp->q_ino.timer;
>  			warns = dqp->q_ino.warnings;
> -			warnlimit = defq->iwarnlimit;
> +			warnlimit = defq->dfq_ino.warnlimit;
>  			hardlimit = dqp->q_ino.hardlimit;
>  			if (!hardlimit)
> -				hardlimit = defq->ihardlimit;
> +				hardlimit = defq->dfq_ino.hardlimit;
>  			softlimit = dqp->q_ino.softlimit;
>  			if (!softlimit)
> -				softlimit = defq->isoftlimit;
> +				softlimit = defq->dfq_ino.softlimit;
>  
>  			if (hardlimit && total_count > hardlimit) {
>  				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
  2020-07-01  8:52   ` Chandan Babu R
@ 2020-07-01  8:53   ` Christoph Hellwig
  2020-07-01 23:30   ` Dave Chinner
  2020-07-02  2:06   ` Allison Collins
  3 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:53 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've split up the dquot resource fields into separate structs,
> do the same for the default limits to enable further refactoring.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions
  2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
@ 2020-07-01  8:53   ` Christoph Hellwig
  2020-07-01  8:58   ` Chandan Babu R
  2020-07-02  2:06   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:53 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:13AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> struct xfs_dquot already has a pointer to the xfs mount, so remove the
> redundant parameter from xfs_qm_adjust_dq*.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
@ 2020-07-01  8:56   ` Christoph Hellwig
  2020-07-01 17:51     ` Darrick J. Wong
  2020-07-01 10:19   ` Chandan Babu R
  2020-07-02 18:57   ` Allison Collins
  2 siblings, 1 reply; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:56 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor the open-coded test for whether or not we're over quota.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
>  1 file changed, 30 insertions(+), 65 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 35a113d1b42b..ef34c82c28a0 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
>  		xfs_dquot_set_prealloc_limits(dq);
>  }
>  
> +/*
> + * Determine if this quota counter is over either limit and set the quota
> + * timers as appropriate.
> + */
> +static inline void
> +xfs_qm_adjust_res_timer(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres)
> +{
> +	bool			over;
> +
> +#ifdef DEBUG
> +	if (res->hardlimit)
> +		ASSERT(res->softlimit <= res->hardlimit);
> +#endif

Maybe:
	ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);

> +
> +	over = (res->softlimit && res->count > res->softlimit) ||
> +	       (res->hardlimit && res->count > res->hardlimit);
> +
> +	if (over && res->timer == 0)
> +		res->timer = ktime_get_real_seconds() + dres->timelimit;
> +	else if (!over && res->timer != 0)
> +		res->timer = 0;
> +	else if (!over && res->timer == 0)
> +		res->warnings = 0;

What about:

	if ((res->softlimit && res->count > res->softlimit) ||
	    (res->hardlimit && res->count > res->hardlimit)) {
		if (res->timer == 0)	
			res->timer = ktime_get_real_seconds() + dres->timelimit;
	} else {
		if (res->timer)
			res->timer = 0;
		else
			res->warnings = 0;
	}

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim
  2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
@ 2020-07-01  8:56   ` Christoph Hellwig
  2020-07-03  4:11   ` Allison Collins
  2020-07-03 12:39   ` Chandan Babu R
  2 siblings, 0 replies; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-01  8:56 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:26AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we can pass around quota resource and limit structures, clean
> up the open-coded field setting in xfs_qm_scall_setqlim.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions
  2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
  2020-07-01  8:53   ` Christoph Hellwig
@ 2020-07-01  8:58   ` Chandan Babu R
  2020-07-02  2:06   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01  8:58 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:13 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> struct xfs_dquot already has a pointer to the xfs mount, so remove the
> redundant parameter from xfs_qm_adjust_dq*.
>

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |    4 ++--
>  fs/xfs/xfs_dquot.h       |    6 ++----
>  fs/xfs/xfs_qm.c          |    4 ++--
>  fs/xfs/xfs_qm_syscalls.c |    2 +-
>  fs/xfs/xfs_trans_dquot.c |    4 ++--
>  5 files changed, 9 insertions(+), 11 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 6975c27145fc..35a113d1b42b 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -66,9 +66,9 @@ xfs_qm_dqdestroy(
>   */
>  void
>  xfs_qm_adjust_dqlimits(
> -	struct xfs_mount	*mp,
>  	struct xfs_dquot	*dq)
>  {
> +	struct xfs_mount	*mp = dq->q_mount;
>  	struct xfs_quotainfo	*q = mp->m_quotainfo;
>  	struct xfs_def_quota	*defq;
>  	int			prealloc = 0;
> @@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits(
>   */
>  void
>  xfs_qm_adjust_dqtimers(
> -	struct xfs_mount	*mp,
>  	struct xfs_dquot	*dq)
>  {
> +	struct xfs_mount	*mp = dq->q_mount;
>  	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>  	struct xfs_def_quota	*defq;
>  
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 62b0fc6e0133..e37b4bebc1ea 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
>  void		xfs_qm_dqdestroy(struct xfs_dquot *dqp);
>  int		xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
>  void		xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
> -void		xfs_qm_adjust_dqtimers(struct xfs_mount *mp,
> -						struct xfs_dquot *d);
> -void		xfs_qm_adjust_dqlimits(struct xfs_mount *mp,
> -						struct xfs_dquot *d);
> +void		xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
> +void		xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
>  xfs_dqid_t	xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type);
>  int		xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
>  					uint type, bool can_alloc,
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 28326a6264a8..30deb6cf6a7a 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust(
>  	 * There are no timers for the default values set in the root dquot.
>  	 */
>  	if (dqp->q_id) {
> -		xfs_qm_adjust_dqlimits(mp, dqp);
> -		xfs_qm_adjust_dqtimers(mp, dqp);
> +		xfs_qm_adjust_dqlimits(dqp);
> +		xfs_qm_adjust_dqtimers(dqp);
>  	}
>  
>  	dqp->dq_flags |= XFS_DQ_DIRTY;
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 393b88612cc8..5423e02f9837 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -594,7 +594,7 @@ xfs_qm_scall_setqlim(
>  		 * is on or off. We don't really want to bother with iterating
>  		 * over all ondisk dquots and turning the timers on/off.
>  		 */
> -		xfs_qm_adjust_dqtimers(mp, dqp);
> +		xfs_qm_adjust_dqtimers(dqp);
>  	}
>  	dqp->dq_flags |= XFS_DQ_DIRTY;
>  	xfs_trans_log_dquot(tp, dqp);
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 392e51baad6f..2712814d696d 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas(
>  			 * Start/reset the timer(s) if needed.
>  			 */
>  			if (dqp->q_id) {
> -				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
> -				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
> +				xfs_qm_adjust_dqlimits(dqp);
> +				xfs_qm_adjust_dqtimers(dqp);
>  			}
>  
>  			dqp->dq_flags |= XFS_DQ_DIRTY;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
@ 2020-07-01 10:19   ` Chandan Babu R
  2020-07-02 18:57   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-01 10:19 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:20 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor the open-coded test for whether or not we're over quota.
>

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
>  1 file changed, 30 insertions(+), 65 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 35a113d1b42b..ef34c82c28a0 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
>  		xfs_dquot_set_prealloc_limits(dq);
>  }
>  
> +/*
> + * Determine if this quota counter is over either limit and set the quota
> + * timers as appropriate.
> + */
> +static inline void
> +xfs_qm_adjust_res_timer(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres)
> +{
> +	bool			over;
> +
> +#ifdef DEBUG
> +	if (res->hardlimit)
> +		ASSERT(res->softlimit <= res->hardlimit);
> +#endif
> +
> +	over = (res->softlimit && res->count > res->softlimit) ||
> +	       (res->hardlimit && res->count > res->hardlimit);
> +
> +	if (over && res->timer == 0)
> +		res->timer = ktime_get_real_seconds() + dres->timelimit;
> +	else if (!over && res->timer != 0)
> +		res->timer = 0;
> +	else if (!over && res->timer == 0)
> +		res->warnings = 0;
> +}
> +
>  /*
>   * Check the limits and timers of a dquot and start or reset timers
>   * if necessary.
> @@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers(
>  	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>  
> -#ifdef DEBUG
> -	if (dq->q_blk.hardlimit)
> -		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> -	if (dq->q_ino.hardlimit)
> -		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> -	if (dq->q_rtb.hardlimit)
> -		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
> -#endif
> -
> -	if (!dq->q_blk.timer) {
> -		if ((dq->q_blk.softlimit &&
> -		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
> -		    (dq->q_blk.hardlimit &&
> -		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
> -			dq->q_blk.timer = ktime_get_real_seconds() +
> -					defq->dfq_blk.timelimit;
> -		} else {
> -			dq->q_blk.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_blk.softlimit ||
> -		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
> -		    (!dq->q_blk.hardlimit ||
> -		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
> -			dq->q_blk.timer = 0;
> -		}
> -	}
> -
> -	if (!dq->q_ino.timer) {
> -		if ((dq->q_ino.softlimit &&
> -		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
> -		    (dq->q_ino.hardlimit &&
> -		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
> -			dq->q_ino.timer = ktime_get_real_seconds() +
> -					defq->dfq_ino.timelimit;
> -		} else {
> -			dq->q_ino.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_ino.softlimit ||
> -		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
> -		    (!dq->q_ino.hardlimit ||
> -		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
> -			dq->q_ino.timer = 0;
> -		}
> -	}
> -
> -	if (!dq->q_rtb.timer) {
> -		if ((dq->q_rtb.softlimit &&
> -		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
> -		    (dq->q_rtb.hardlimit &&
> -		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
> -			dq->q_rtb.timer = ktime_get_real_seconds() +
> -					defq->dfq_rtb.timelimit;
> -		} else {
> -			dq->q_rtb.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_rtb.softlimit ||
> -		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
> -		    (!dq->q_rtb.hardlimit ||
> -		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
> -			dq->q_rtb.timer = 0;
> -		}
> -	}
> +	xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk);
> +	xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino);
> +	xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb);
>  }
>  
>  /*
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-07-01  8:56   ` Christoph Hellwig
@ 2020-07-01 17:51     ` Darrick J. Wong
  2020-07-01 18:48       ` Eric Sandeen
  2020-07-01 23:34       ` Dave Chinner
  0 siblings, 2 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 17:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Eric Sandeen, Amir Goldstein

On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote:
> On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Refactor the open-coded test for whether or not we're over quota.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
> >  1 file changed, 30 insertions(+), 65 deletions(-)
> > 
> > 
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index 35a113d1b42b..ef34c82c28a0 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
> >  		xfs_dquot_set_prealloc_limits(dq);
> >  }
> >  
> > +/*
> > + * Determine if this quota counter is over either limit and set the quota
> > + * timers as appropriate.
> > + */
> > +static inline void
> > +xfs_qm_adjust_res_timer(
> > +	struct xfs_dquot_res	*res,
> > +	struct xfs_def_qres	*dres)
> > +{
> > +	bool			over;
> > +
> > +#ifdef DEBUG
> > +	if (res->hardlimit)
> > +		ASSERT(res->softlimit <= res->hardlimit);
> > +#endif
> 
> Maybe:
> 	ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);

Changed.

> 
> > +
> > +	over = (res->softlimit && res->count > res->softlimit) ||
> > +	       (res->hardlimit && res->count > res->hardlimit);
> > +
> > +	if (over && res->timer == 0)
> > +		res->timer = ktime_get_real_seconds() + dres->timelimit;
> > +	else if (!over && res->timer != 0)
> > +		res->timer = 0;
> > +	else if (!over && res->timer == 0)
> > +		res->warnings = 0;
> 
> What about:
> 
> 	if ((res->softlimit && res->count > res->softlimit) ||
> 	    (res->hardlimit && res->count > res->hardlimit)) {
> 		if (res->timer == 0)	
> 			res->timer = ktime_get_real_seconds() + dres->timelimit;
> 	} else {
> 		if (res->timer)
> 			res->timer = 0;
> 		else
> 			res->warnings = 0;
> 	}

I don't care either way, but the last time I sent this patch out, Eric
and Amir seemed to want a flatter if structure:

https://lore.kernel.org/linux-xfs/b979d33d-361b-88cd-699c-7e5f1c621698@sandeen.net/
https://lore.kernel.org/linux-xfs/CAOQ4uxiveTQu8_7UOvN07=P4o9hBBZTCyu4sSw5UpbrNPQL2pQ@mail.gmail.com/

Granted that was before I pulled the whole thing into a separate helper
function, so maybe the context is different here...?

--D

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-07-01  8:42   ` Christoph Hellwig
@ 2020-07-01 18:25     ` Darrick J. Wong
  2020-07-02  6:30       ` Christoph Hellwig
  0 siblings, 1 reply; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 18:25 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 09:42:08AM +0100, Christoph Hellwig wrote:
> On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > While loading dquot records off disk, make sure that the quota type
> > flags are the same between the incore dquot and the ondisk dquot.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
> >  1 file changed, 20 insertions(+), 3 deletions(-)
> > 
> > 
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index d5b7f03e93c8..46c8ca83c04d 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -524,13 +524,27 @@ xfs_dquot_alloc(
> >  }
> >  
> >  /* Copy the in-core quota fields in from the on-disk buffer. */
> > -STATIC void
> > +STATIC int
> >  xfs_dquot_from_disk(
> >  	struct xfs_dquot	*dqp,
> >  	struct xfs_buf		*bp)
> >  {
> >  	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
> >  
> > +	/*
> > +	 * The only field the verifier didn't check was the quota type flag, so
> > +	 * do that here.
> > +	 */
> > +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> > +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> > +	    dqp->q_core.d_id != ddqp->d_id) {
> 
> The comment looks a little weird, as this also checks d_id.  Also
> xfs_dquot_verify verifies d_flags against generally bogus value, it
> just doesn't check that it matches the type we are looking for.
> Last but not least dqp->dq_flags only contains the type at this
> point.
> 
> So what about something like:
> 
> 	/*
> 	 * Ensure we got the type and ID we were looking for.  Everything else
> 	 * we checked by the verifier.
> 	 */
> 	if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
> 	    ddqp->d_id != dqp->q_core.d_id)

Sounds good to me.  I'll make that change.

--D

> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-07-01 17:51     ` Darrick J. Wong
@ 2020-07-01 18:48       ` Eric Sandeen
  2020-07-01 23:34       ` Dave Chinner
  1 sibling, 0 replies; 94+ messages in thread
From: Eric Sandeen @ 2020-07-01 18:48 UTC (permalink / raw)
  To: Darrick J. Wong, Christoph Hellwig; +Cc: linux-xfs, Amir Goldstein

On 7/1/20 12:51 PM, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote:
>> On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
>>> From: Darrick J. Wong <darrick.wong@oracle.com>
>>>
>>> Refactor the open-coded test for whether or not we're over quota.
>>>
>>> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
>>> ---
>>>  fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
>>>  1 file changed, 30 insertions(+), 65 deletions(-)
>>>
>>>
>>> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
>>> index 35a113d1b42b..ef34c82c28a0 100644
>>> --- a/fs/xfs/xfs_dquot.c
>>> +++ b/fs/xfs/xfs_dquot.c
>>> @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
>>>  		xfs_dquot_set_prealloc_limits(dq);
>>>  }
>>>  
>>> +/*
>>> + * Determine if this quota counter is over either limit and set the quota
>>> + * timers as appropriate.
>>> + */
>>> +static inline void
>>> +xfs_qm_adjust_res_timer(
>>> +	struct xfs_dquot_res	*res,
>>> +	struct xfs_def_qres	*dres)
>>> +{
>>> +	bool			over;
>>> +
>>> +#ifdef DEBUG
>>> +	if (res->hardlimit)
>>> +		ASSERT(res->softlimit <= res->hardlimit);
>>> +#endif
>>
>> Maybe:
>> 	ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);
> 
> Changed.
> 
>>
>>> +
>>> +	over = (res->softlimit && res->count > res->softlimit) ||
>>> +	       (res->hardlimit && res->count > res->hardlimit);
>>> +
>>> +	if (over && res->timer == 0)
>>> +		res->timer = ktime_get_real_seconds() + dres->timelimit;
>>> +	else if (!over && res->timer != 0)
>>> +		res->timer = 0;
>>> +	else if (!over && res->timer == 0)
>>> +		res->warnings = 0;
>>
>> What about:
>>
>> 	if ((res->softlimit && res->count > res->softlimit) ||
>> 	    (res->hardlimit && res->count > res->hardlimit)) {
>> 		if (res->timer == 0)	
>> 			res->timer = ktime_get_real_seconds() + dres->timelimit;
>> 	} else {
>> 		if (res->timer)
>> 			res->timer = 0;
>> 		else
>> 			res->warnings = 0;
>> 	}
> 
> I don't care either way, but the last time I sent this patch out, Eric
> and Amir seemed to want a flatter if structure:
> 
> https://lore.kernel.org/linux-xfs/b979d33d-361b-88cd-699c-7e5f1c621698@sandeen.net/
> https://lore.kernel.org/linux-xfs/CAOQ4uxiveTQu8_7UOvN07=P4o9hBBZTCyu4sSw5UpbrNPQL2pQ@mail.gmail.com/
> 
> Granted that was before I pulled the whole thing into a separate helper
> function, so maybe the context is different here...?

I think it is different.  I'm not too hung up about either way and
can't promise to dedicate time to thinking about it soon, so -
as you wish.  :)

-Eric


^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-01  8:47   ` Christoph Hellwig
@ 2020-07-01 19:02     ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 19:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 09:47:14AM +0100, Christoph Hellwig wrote:
> >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> >  
> > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> > +
> 
> I really wonder if we should split the on-disk type and the in-core
> flags properly instead.
> 
> That is propagate the u8 flags from the on-disk field directly,
> and use a separate field for the in-memory flags dirty and freeing
> flags, as that this kind of mixing up is bound to eventually create
> problems.

I was already half-inclined to try to separate them anyway, guess I'll
add that to this series.

--D

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:47   ` Christoph Hellwig
@ 2020-07-01 20:15   ` Allison Collins
  2020-07-01 22:50   ` Dave Chinner
  3 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 20:15 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Use the incore dq_flags to figure out the dquot type.  This is the first
> step towards removing xfs_disk_dquot from the incore dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, seems reasonable
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
>   fs/xfs/scrub/quota.c           |    4 ----
>   fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
>   fs/xfs/xfs_dquot.h             |    2 ++
>   fs/xfs/xfs_dquot_item.c        |    6 ++++--
>   fs/xfs/xfs_qm.c                |    4 ++--
>   fs/xfs/xfs_qm.h                |    2 +-
>   fs/xfs/xfs_qm_syscalls.c       |    9 +++------
>   8 files changed, 45 insertions(+), 17 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> index 56d9dd787e7b..459023b0a304 100644
> --- a/fs/xfs/libxfs/xfs_quota_defs.h
> +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
>   
>   #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
>   
> +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> +
>   #define XFS_DQ_FLAGS \
>   	{ XFS_DQ_USER,		"USER" }, \
>   	{ XFS_DQ_PROJ,		"PROJ" }, \
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 905a34558361..710659d3fa28 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -108,10 +108,6 @@ xchk_quota_item(
>   
>   	sqi->last_id = id;
>   
> -	/* Did we get the dquot type we wanted? */
> -	if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
> -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> -
>   	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 46c8ca83c04d..59d1bce34a98 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -561,6 +561,16 @@ xfs_dquot_from_disk(
>   	return 0;
>   }
>   
> +/* Copy the in-core quota fields into the on-disk buffer. */
> +void
> +xfs_dquot_to_disk(
> +	struct xfs_disk_dquot	*ddqp,
> +	struct xfs_dquot	*dqp)
> +{
> +	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +}
> +
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
>   static int
>   xfs_qm_dqread_alloc(
> @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done(
>   	xfs_dqfunlock(dqp);
>   }
>   
> +/* Check incore dquot for errors before we flush. */
> +static xfs_failaddr_t
> +xfs_qm_dqflush_check(
> +	struct xfs_dquot	*dqp)
> +{
> +	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> +		return __this_address;
> +
> +	return NULL;
> +}
> +
>   /*
>    * Write a modified dquot to disk.
>    * The dquot must be locked and the flush lock too taken by caller.
> @@ -1166,8 +1187,16 @@ xfs_qm_dqflush(
>   		goto out_abort;
>   	}
>   
> -	/* This is the only portion of data that needs to persist */
> -	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	fa = xfs_qm_dqflush_check(dqp);
> +	if (fa) {
> +		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> +				be32_to_cpu(dqp->q_core.d_id), fa);
> +		xfs_buf_relse(bp);
> +		error = -EFSCORRUPTED;
> +		goto out_abort;
> +	}
> +
> +	xfs_dquot_to_disk(ddqp, dqp);
>   
>   	/*
>   	 * Clear the dirty field and remember the flush lsn for later use.
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 71e36c85e20b..1b1a4261a580 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -144,6 +144,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>   	return false;
>   }
>   
> +void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
> +
>   #define XFS_DQ_IS_LOCKED(dqp)	(mutex_is_locked(&((dqp)->q_qlock)))
>   #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
>   #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
> diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
> index 349c92d26570..ff0ab65cf413 100644
> --- a/fs/xfs/xfs_dquot_item.c
> +++ b/fs/xfs/xfs_dquot_item.c
> @@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format(
>   	struct xfs_log_item	*lip,
>   	struct xfs_log_vec	*lv)
>   {
> +	struct xfs_disk_dquot	ddq;
>   	struct xfs_dq_logitem	*qlip = DQUOT_ITEM(lip);
>   	struct xfs_log_iovec	*vecp = NULL;
>   	struct xfs_dq_logformat	*qlf;
> @@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format(
>   	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
>   	xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
>   
> -	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
> -			&qlip->qli_dquot->q_core,
> +	xfs_dquot_to_disk(&ddq, qlip->qli_dquot);
> +
> +	xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq,
>   			sizeof(struct xfs_disk_dquot));
>   }
>   
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 938023dd8ce5..632025c2f00b 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -161,7 +161,7 @@ xfs_qm_dqpurge(
>   	xfs_dqfunlock(dqp);
>   	xfs_dqunlock(dqp);
>   
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
>   			  be32_to_cpu(dqp->q_core.d_id));
>   	qi->qi_dquots--;
>   
> @@ -1598,7 +1598,7 @@ xfs_qm_dqfree_one(
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   
>   	mutex_lock(&qi->qi_tree_lock);
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->q_core.d_flags),
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
>   			  be32_to_cpu(dqp->q_core.d_id));
>   
>   	qi->qi_dquots--;
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 7b0e771fcbce..43b4650cdcdf 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -85,7 +85,7 @@ xfs_dquot_tree(
>   	struct xfs_quotainfo	*qi,
>   	int			type)
>   {
> -	switch (type) {
> +	switch (type & XFS_DQ_ALLTYPES) {
>   	case XFS_DQ_USER:
>   		return &qi->qi_uquota_tree;
>   	case XFS_DQ_GROUP:
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 7effd7a28136..8cbb65f01bf1 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -644,12 +644,9 @@ xfs_qm_scall_getquota_fill_qc(
>   	 * gets turned off. No need to confuse the user level code,
>   	 * so return zeroes in that case.
>   	 */
> -	if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_USER) ||
> -	    (!XFS_IS_GQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_GROUP) ||
> -	    (!XFS_IS_PQUOTA_ENFORCED(mp) &&
> -	     dqp->q_core.d_flags == XFS_DQ_PROJ)) {
> +	if ((!XFS_IS_UQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_USER)) ||
> +	    (!XFS_IS_GQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_GROUP)) ||
> +	    (!XFS_IS_PQUOTA_ENFORCED(mp) && (dqp->dq_flags & XFS_DQ_PROJ))) {
>   		dst->d_spc_timer = 0;
>   		dst->d_ino_timer = 0;
>   		dst->d_rt_spc_timer = 0;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 05/18] xfs: stop using q_core.d_id in the quota code
  2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:48   ` Christoph Hellwig
@ 2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 20:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add a dquot id field to the incore dquot, and use that instead of the
> one in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> We also rearrange the start of xfs_dquot to remove padding holes, saving
> 8 bytes.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok looks straight forward to me
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/scrub/quota.c     |   19 ++++++++++++-------
>   fs/xfs/xfs_dquot.c       |   25 +++++++++++--------------
>   fs/xfs/xfs_dquot.h       |    5 +++--
>   fs/xfs/xfs_dquot_item.c  |    2 +-
>   fs/xfs/xfs_qm.c          |   22 ++++++++++------------
>   fs/xfs/xfs_qm_syscalls.c |    4 ++--
>   fs/xfs/xfs_trace.h       |    2 +-
>   fs/xfs/xfs_trans_dquot.c |    8 +++-----
>   8 files changed, 43 insertions(+), 44 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 710659d3fa28..9a271f115882 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -92,7 +92,6 @@ xchk_quota_item(
>   	unsigned long long	icount;
>   	unsigned long long	rcount;
>   	xfs_ino_t		fs_icount;
> -	xfs_dqid_t		id = be32_to_cpu(d->d_id);
>   	int			error = 0;
>   
>   	if (xchk_should_terminate(sc, &error))
> @@ -102,11 +101,11 @@ xchk_quota_item(
>   	 * Except for the root dquot, the actual dquot we got must either have
>   	 * the same or higher id as we saw before.
>   	 */
> -	offset = id / qi->qi_dqperchunk;
> -	if (id && id <= sqi->last_id)
> +	offset = dq->q_id / qi->qi_dqperchunk;
> +	if (dq->q_id && dq->q_id <= sqi->last_id)
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
> -	sqi->last_id = id;
> +	sqi->last_id = dq->q_id;
>   
>   	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> @@ -171,13 +170,19 @@ xchk_quota_item(
>   	 * lower limit than the actual usage.  However, we flag it for
>   	 * admin review.
>   	 */
> -	if (id != 0 && bhard != 0 && bcount > bhard)
> +	if (dq->q_id == 0)
> +		goto out;
> +
> +	if (bhard != 0 && bcount > bhard)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (id != 0 && ihard != 0 && icount > ihard)
> +
> +	if (ihard != 0 && icount > ihard)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (id != 0 && rhard != 0 && rcount > rhard)
> +
> +	if (rhard != 0 && rcount > rhard)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
> +out:
>   	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
>   		return -EFSCORRUPTED;
>   
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 59d1bce34a98..76b35888e726 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -74,7 +74,7 @@ xfs_qm_adjust_dqlimits(
>   	struct xfs_def_quota	*defq;
>   	int			prealloc = 0;
>   
> -	ASSERT(d->d_id);
> +	ASSERT(dq->q_id);
>   	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>   
>   	if (defq->bsoftlimit && !d->d_blk_softlimit) {
> @@ -120,7 +120,7 @@ xfs_qm_adjust_dqtimers(
>   	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_def_quota	*defq;
>   
> -	ASSERT(d->d_id);
> +	ASSERT(dq->q_id);
>   	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>   
>   #ifdef DEBUG
> @@ -365,7 +365,7 @@ xfs_dquot_disk_alloc(
>   	 * Make a chunk of dquots out of this buffer and log
>   	 * the entire thing.
>   	 */
> -	xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
> +	xfs_qm_init_dquot_blk(tp, mp, dqp->q_id,
>   			      dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
>   	xfs_buf_set_ref(bp, XFS_DQUOT_REF);
>   
> @@ -478,7 +478,7 @@ xfs_dquot_alloc(
>   	dqp = kmem_zone_zalloc(xfs_qm_dqzone, 0);
>   
>   	dqp->dq_flags = type;
> -	dqp->q_core.d_id = cpu_to_be32(id);
> +	dqp->q_id = id;
>   	dqp->q_mount = mp;
>   	INIT_LIST_HEAD(&dqp->q_lru);
>   	mutex_init(&dqp->q_qlock);
> @@ -537,10 +537,10 @@ xfs_dquot_from_disk(
>   	 */
>   	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
>   	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> -	    dqp->q_core.d_id != ddqp->d_id) {
> +	    dqp->q_id != be32_to_cpu(ddqp->d_id)) {
>   		xfs_alert(bp->b_mount,
>   			  "Metadata corruption detected at %pS, quota %u",
> -			  __this_address, be32_to_cpu(dqp->q_core.d_id));
> +			  __this_address, dqp->q_id);
>   		xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
>   		return -EFSCORRUPTED;
>   	}
> @@ -1177,11 +1177,10 @@ xfs_qm_dqflush(
>   	ddqp = &dqb->dd_diskdq;
>   
>   	/* sanity check the in-core structure before we flush */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, be32_to_cpu(dqp->q_core.d_id),
> -			      0);
> +	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
>   	if (fa) {
>   		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				be32_to_cpu(dqp->q_core.d_id), fa);
> +				dqp->q_id, fa);
>   		xfs_buf_relse(bp);
>   		error = -EFSCORRUPTED;
>   		goto out_abort;
> @@ -1190,7 +1189,7 @@ xfs_qm_dqflush(
>   	fa = xfs_qm_dqflush_check(dqp);
>   	if (fa) {
>   		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				be32_to_cpu(dqp->q_core.d_id), fa);
> +				dqp->q_id, fa);
>   		xfs_buf_relse(bp);
>   		error = -EFSCORRUPTED;
>   		goto out_abort;
> @@ -1263,8 +1262,7 @@ xfs_dqlock2(
>   {
>   	if (d1 && d2) {
>   		ASSERT(d1 != d2);
> -		if (be32_to_cpu(d1->q_core.d_id) >
> -		    be32_to_cpu(d2->q_core.d_id)) {
> +		if (d1->q_id > d2->q_id) {
>   			mutex_lock(&d2->q_qlock);
>   			mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
>   		} else {
> @@ -1332,9 +1330,8 @@ xfs_qm_dqiterate(
>   			return error;
>   
>   		error = iter_fn(dq, dqtype, priv);
> -		id = be32_to_cpu(dq->q_core.d_id);
> +		id = dq->q_id + 1;
>   		xfs_qm_dqput(dq);
> -		id++;
>   	} while (error == 0 && id != 0);
>   
>   	return error;
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 1b1a4261a580..5ea1f1515979 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -31,12 +31,13 @@ enum {
>    * The incore dquot structure
>    */
>   struct xfs_dquot {
> -	uint			dq_flags;
>   	struct list_head	q_lru;
>   	struct xfs_mount	*q_mount;
> +	xfs_dqid_t		q_id;
> +	uint			dq_flags;
>   	uint			q_nrefs;
> -	xfs_daddr_t		q_blkno;
>   	int			q_bufoffset;
> +	xfs_daddr_t		q_blkno;
>   	xfs_fileoff_t		q_fileoffset;
>   
>   	struct xfs_disk_dquot	q_core;
> diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
> index ff0ab65cf413..378d919997f1 100644
> --- a/fs/xfs/xfs_dquot_item.c
> +++ b/fs/xfs/xfs_dquot_item.c
> @@ -53,7 +53,7 @@ xfs_qm_dquot_logitem_format(
>   	qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
>   	qlf->qlf_type = XFS_LI_DQUOT;
>   	qlf->qlf_size = 2;
> -	qlf->qlf_id = be32_to_cpu(qlip->qli_dquot->q_core.d_id);
> +	qlf->qlf_id = qlip->qli_dquot->q_id;
>   	qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
>   	qlf->qlf_len = 1;
>   	qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 632025c2f00b..95e51186bd57 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -79,7 +79,7 @@ xfs_qm_dquot_walk(
>   		for (i = 0; i < nr_found; i++) {
>   			struct xfs_dquot *dqp = batch[i];
>   
> -			next_index = be32_to_cpu(dqp->q_core.d_id) + 1;
> +			next_index = dqp->q_id + 1;
>   
>   			error = execute(batch[i], data);
>   			if (error == -EAGAIN) {
> @@ -161,8 +161,7 @@ xfs_qm_dqpurge(
>   	xfs_dqfunlock(dqp);
>   	xfs_dqunlock(dqp);
>   
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
> -			  be32_to_cpu(dqp->q_core.d_id));
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
>   	qi->qi_dquots--;
>   
>   	/*
> @@ -1112,7 +1111,7 @@ xfs_qm_quotacheck_dqadjust(
>   	 *
>   	 * There are no timers for the default values set in the root dquot.
>   	 */
> -	if (dqp->q_core.d_id) {
> +	if (dqp->q_id) {
>   		xfs_qm_adjust_dqlimits(mp, dqp);
>   		xfs_qm_adjust_dqtimers(mp, dqp);
>   	}
> @@ -1598,8 +1597,7 @@ xfs_qm_dqfree_one(
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   
>   	mutex_lock(&qi->qi_tree_lock);
> -	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags),
> -			  be32_to_cpu(dqp->q_core.d_id));
> +	radix_tree_delete(xfs_dquot_tree(qi, dqp->dq_flags), dqp->q_id);
>   
>   	qi->qi_dquots--;
>   	mutex_unlock(&qi->qi_tree_lock);
> @@ -1823,7 +1821,7 @@ xfs_qm_vop_chown_reserve(
>   			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
>   
>   	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
> -	    i_uid_read(VFS_I(ip)) != be32_to_cpu(udqp->q_core.d_id)) {
> +	    i_uid_read(VFS_I(ip)) != udqp->q_id) {
>   		udq_delblks = udqp;
>   		/*
>   		 * If there are delayed allocation blocks, then we have to
> @@ -1836,7 +1834,7 @@ xfs_qm_vop_chown_reserve(
>   		}
>   	}
>   	if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
> -	    i_gid_read(VFS_I(ip)) != be32_to_cpu(gdqp->q_core.d_id)) {
> +	    i_gid_read(VFS_I(ip)) != gdqp->q_id) {
>   		gdq_delblks = gdqp;
>   		if (delblks) {
>   			ASSERT(ip->i_gdquot);
> @@ -1845,7 +1843,7 @@ xfs_qm_vop_chown_reserve(
>   	}
>   
>   	if (XFS_IS_PQUOTA_ON(ip->i_mount) && pdqp &&
> -	    ip->i_d.di_projid != be32_to_cpu(pdqp->q_core.d_id)) {
> +	    ip->i_d.di_projid != pdqp->q_id) {
>   		pdq_delblks = pdqp;
>   		if (delblks) {
>   			ASSERT(ip->i_pdquot);
> @@ -1929,21 +1927,21 @@ xfs_qm_vop_create_dqattach(
>   
>   	if (udqp && XFS_IS_UQUOTA_ON(mp)) {
>   		ASSERT(ip->i_udquot == NULL);
> -		ASSERT(i_uid_read(VFS_I(ip)) == be32_to_cpu(udqp->q_core.d_id));
> +		ASSERT(i_uid_read(VFS_I(ip)) == udqp->q_id);
>   
>   		ip->i_udquot = xfs_qm_dqhold(udqp);
>   		xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
>   	}
>   	if (gdqp && XFS_IS_GQUOTA_ON(mp)) {
>   		ASSERT(ip->i_gdquot == NULL);
> -		ASSERT(i_gid_read(VFS_I(ip)) == be32_to_cpu(gdqp->q_core.d_id));
> +		ASSERT(i_gid_read(VFS_I(ip)) == gdqp->q_id);
>   
>   		ip->i_gdquot = xfs_qm_dqhold(gdqp);
>   		xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
>   	}
>   	if (pdqp && XFS_IS_PQUOTA_ON(mp)) {
>   		ASSERT(ip->i_pdquot == NULL);
> -		ASSERT(ip->i_d.di_projid == be32_to_cpu(pdqp->q_core.d_id));
> +		ASSERT(ip->i_d.di_projid == pdqp->q_id);
>   
>   		ip->i_pdquot = xfs_qm_dqhold(pdqp);
>   		xfs_trans_mod_dquot(tp, pdqp, XFS_TRANS_DQ_ICOUNT, 1);
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 8cbb65f01bf1..90a11e7daf92 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -656,7 +656,7 @@ xfs_qm_scall_getquota_fill_qc(
>   	if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) ||
>   	     (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) ||
>   	     (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) &&
> -	    dqp->q_core.d_id != 0) {
> +	    dqp->q_id != 0) {
>   		if ((dst->d_space > dst->d_spc_softlimit) &&
>   		    (dst->d_spc_softlimit > 0)) {
>   			ASSERT(dst->d_spc_timer != 0);
> @@ -723,7 +723,7 @@ xfs_qm_scall_getquota_next(
>   		return error;
>   
>   	/* Fill in the ID we actually read from disk */
> -	*id = be32_to_cpu(dqp->q_core.d_id);
> +	*id = dqp->q_id;
>   
>   	xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
>   
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 2c5df8315351..78d9dbc7614d 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -876,7 +876,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>   	), \
>   	TP_fast_assign(
>   		__entry->dev = dqp->q_mount->m_super->s_dev;
> -		__entry->id = be32_to_cpu(dqp->q_core.d_id);
> +		__entry->id = dqp->q_id;
>   		__entry->flags = dqp->dq_flags;
>   		__entry->nrefs = dqp->q_nrefs;
>   		__entry->res_bcount = dqp->q_res_bcount;
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index ed0ce8b301b4..a2656ec6ea76 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -386,7 +386,7 @@ xfs_trans_apply_dquot_deltas(
>   			 * Get any default limits in use.
>   			 * Start/reset the timer(s) if needed.
>   			 */
> -			if (d->d_id) {
> +			if (dqp->q_id) {
>   				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
>   				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
>   			}
> @@ -558,8 +558,7 @@ xfs_quota_warn(
>   	else
>   		qtype = GRPQUOTA;
>   
> -	quota_send_warning(make_kqid(&init_user_ns, qtype,
> -				     be32_to_cpu(dqp->q_core.d_id)),
> +	quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
>   			   mp->m_super->s_dev, type);
>   }
>   
> @@ -618,8 +617,7 @@ xfs_trans_dqresv(
>   		resbcountp = &dqp->q_res_rtbcount;
>   	}
>   
> -	if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
> -	    dqp->q_core.d_id &&
> +	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
>   	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
>   	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
>   	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 06/18] xfs: use a per-resource struct for incore dquot data
  2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:49   ` Christoph Hellwig
@ 2020-07-01 20:16   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 20:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce a new struct xfs_dquot_res that we'll use to track all the
> incore data for a particular resource type (block, inode, rt block).
> This will help us (once we've eliminated q_core) to declutter quota
> functions that currently open-code field access or pass around fields
> around explicitly.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Looks ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c       |    6 +++---
>   fs/xfs/xfs_dquot.h       |   18 +++++++++++-------
>   fs/xfs/xfs_iomap.c       |    6 +++---
>   fs/xfs/xfs_qm.c          |    6 +++---
>   fs/xfs/xfs_qm_bhv.c      |    8 ++++----
>   fs/xfs/xfs_qm_syscalls.c |    6 +++---
>   fs/xfs/xfs_trace.h       |    2 +-
>   fs/xfs/xfs_trans_dquot.c |   42 +++++++++++++++++++++---------------------
>   8 files changed, 49 insertions(+), 45 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 76b35888e726..03624a8f0566 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -552,9 +552,9 @@ xfs_dquot_from_disk(
>   	 * Reservation counters are defined as reservation plus current usage
>   	 * to avoid having to add every time.
>   	 */
> -	dqp->q_res_bcount = be64_to_cpu(ddqp->d_bcount);
> -	dqp->q_res_icount = be64_to_cpu(ddqp->d_icount);
> -	dqp->q_res_rtbcount = be64_to_cpu(ddqp->d_rtbcount);
> +	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
> +	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
> +	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
>   
>   	/* initialize the dquot speculative prealloc thresholds */
>   	xfs_dquot_set_prealloc_limits(dqp);
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 5ea1f1515979..cb20df1e774f 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -27,6 +27,11 @@ enum {
>   	XFS_QLOWSP_MAX
>   };
>   
> +struct xfs_dquot_res {
> +	/* Total resources allocated and reserved. */
> +	xfs_qcnt_t		reserved;
> +};
> +
>   /*
>    * The incore dquot structure
>    */
> @@ -40,14 +45,13 @@ struct xfs_dquot {
>   	xfs_daddr_t		q_blkno;
>   	xfs_fileoff_t		q_fileoffset;
>   
> +	struct xfs_dquot_res	q_blk;	/* regular blocks */
> +	struct xfs_dquot_res	q_ino;	/* inodes */
> +	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
> +
>   	struct xfs_disk_dquot	q_core;
>   	struct xfs_dq_logitem	q_logitem;
> -	/* total regular nblks used+reserved */
> -	xfs_qcnt_t		q_res_bcount;
> -	/* total inos allocd+reserved */
> -	xfs_qcnt_t		q_res_icount;
> -	/* total realtime blks used+reserved */
> -	xfs_qcnt_t		q_res_rtbcount;
> +
>   	xfs_qcnt_t		q_prealloc_lo_wmark;
>   	xfs_qcnt_t		q_prealloc_hi_wmark;
>   	int64_t			q_low_space[XFS_QLOWSP_MAX];
> @@ -138,7 +142,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>   {
>   	int64_t freesp;
>   
> -	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_res_bcount;
> +	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
>   	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
>   		return true;
>   
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index b9a8c3798e08..f60a6e44363b 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -307,7 +307,7 @@ xfs_quota_need_throttle(
>   		return false;
>   
>   	/* under the lo watermark, no throttle */
> -	if (dq->q_res_bcount + alloc_blocks < dq->q_prealloc_lo_wmark)
> +	if (dq->q_blk.reserved + alloc_blocks < dq->q_prealloc_lo_wmark)
>   		return false;
>   
>   	return true;
> @@ -326,13 +326,13 @@ xfs_quota_calc_throttle(
>   	struct xfs_dquot *dq = xfs_inode_dquot(ip, type);
>   
>   	/* no dq, or over hi wmark, squash the prealloc completely */
> -	if (!dq || dq->q_res_bcount >= dq->q_prealloc_hi_wmark) {
> +	if (!dq || dq->q_blk.reserved >= dq->q_prealloc_hi_wmark) {
>   		*qblocks = 0;
>   		*qfreesp = 0;
>   		return;
>   	}
>   
> -	freesp = dq->q_prealloc_hi_wmark - dq->q_res_bcount;
> +	freesp = dq->q_prealloc_hi_wmark - dq->q_blk.reserved;
>   	if (freesp < dq->q_low_space[XFS_QLOWSP_5_PCNT]) {
>   		shift = 2;
>   		if (freesp < dq->q_low_space[XFS_QLOWSP_3_PCNT])
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 95e51186bd57..6ce3a4402041 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1096,14 +1096,14 @@ xfs_qm_quotacheck_dqadjust(
>   	 * resource usage.
>   	 */
>   	be64_add_cpu(&dqp->q_core.d_icount, 1);
> -	dqp->q_res_icount++;
> +	dqp->q_ino.reserved++;
>   	if (nblks) {
>   		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
> -		dqp->q_res_bcount += nblks;
> +		dqp->q_blk.reserved += nblks;
>   	}
>   	if (rtblks) {
>   		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
> -		dqp->q_res_rtbcount += rtblks;
> +		dqp->q_rtb.reserved += rtblks;
>   	}
>   
>   	/*
> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index fc2fa418919f..94b2b4b0fc17 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -29,8 +29,8 @@ xfs_fill_statvfs_from_dquot(
>   	if (limit && statp->f_blocks > limit) {
>   		statp->f_blocks = limit;
>   		statp->f_bfree = statp->f_bavail =
> -			(statp->f_blocks > dqp->q_res_bcount) ?
> -			 (statp->f_blocks - dqp->q_res_bcount) : 0;
> +			(statp->f_blocks > dqp->q_blk.reserved) ?
> +			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
>   	}
>   
>   	limit = dqp->q_core.d_ino_softlimit ?
> @@ -39,8 +39,8 @@ xfs_fill_statvfs_from_dquot(
>   	if (limit && statp->f_files > limit) {
>   		statp->f_files = limit;
>   		statp->f_ffree =
> -			(statp->f_files > dqp->q_res_icount) ?
> -			 (statp->f_files - dqp->q_res_icount) : 0;
> +			(statp->f_files > dqp->q_ino.reserved) ?
> +			 (statp->f_files - dqp->q_ino.reserved) : 0;
>   	}
>   }
>   
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 90a11e7daf92..56fe80395679 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -625,8 +625,8 @@ xfs_qm_scall_getquota_fill_qc(
>   		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
>   	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
>   	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> -	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount);
> -	dst->d_ino_count = dqp->q_res_icount;
> +	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
> +	dst->d_ino_count = dqp->q_ino.reserved;
>   	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
>   	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
>   	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
> @@ -635,7 +635,7 @@ xfs_qm_scall_getquota_fill_qc(
>   		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
>   	dst->d_rt_spc_softlimit =
>   		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
> -	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount);
> +	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>   	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>   	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
>   
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 78d9dbc7614d..71567ed367f2 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -879,7 +879,7 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>   		__entry->id = dqp->q_id;
>   		__entry->flags = dqp->dq_flags;
>   		__entry->nrefs = dqp->q_nrefs;
> -		__entry->res_bcount = dqp->q_res_bcount;
> +		__entry->res_bcount = dqp->q_blk.reserved;
>   		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
>   		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
>   		__entry->blk_hardlimit =
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index a2656ec6ea76..469bf7946d3d 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -409,11 +409,11 @@ xfs_trans_apply_dquot_deltas(
>   
>   				if (qtrx->qt_blk_res != blk_res_used) {
>   					if (qtrx->qt_blk_res > blk_res_used)
> -						dqp->q_res_bcount -= (xfs_qcnt_t)
> +						dqp->q_blk.reserved -= (xfs_qcnt_t)
>   							(qtrx->qt_blk_res -
>   							 blk_res_used);
>   					else
> -						dqp->q_res_bcount -= (xfs_qcnt_t)
> +						dqp->q_blk.reserved -= (xfs_qcnt_t)
>   							(blk_res_used -
>   							 qtrx->qt_blk_res);
>   				}
> @@ -426,7 +426,7 @@ xfs_trans_apply_dquot_deltas(
>   				 * deliberately skip quota reservations.
>   				 */
>   				if (qtrx->qt_bcount_delta) {
> -					dqp->q_res_bcount +=
> +					dqp->q_blk.reserved +=
>   					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
>   				}
>   			}
> @@ -437,17 +437,17 @@ xfs_trans_apply_dquot_deltas(
>   				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
>   					if (qtrx->qt_rtblk_res >
>   					    qtrx->qt_rtblk_res_used)
> -					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
> +					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
>   						       (qtrx->qt_rtblk_res -
>   							qtrx->qt_rtblk_res_used);
>   					else
> -					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
> +					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
>   						       (qtrx->qt_rtblk_res_used -
>   							qtrx->qt_rtblk_res);
>   				}
>   			} else {
>   				if (qtrx->qt_rtbcount_delta)
> -					dqp->q_res_rtbcount +=
> +					dqp->q_rtb.reserved +=
>   					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
>   			}
>   
> @@ -458,20 +458,20 @@ xfs_trans_apply_dquot_deltas(
>   				ASSERT(qtrx->qt_ino_res >=
>   				       qtrx->qt_ino_res_used);
>   				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
> -					dqp->q_res_icount -= (xfs_qcnt_t)
> +					dqp->q_ino.reserved -= (xfs_qcnt_t)
>   						(qtrx->qt_ino_res -
>   						 qtrx->qt_ino_res_used);
>   			} else {
>   				if (qtrx->qt_icount_delta)
> -					dqp->q_res_icount +=
> +					dqp->q_ino.reserved +=
>   					    (xfs_qcnt_t)qtrx->qt_icount_delta;
>   			}
>   
> -			ASSERT(dqp->q_res_bcount >=
> +			ASSERT(dqp->q_blk.reserved >=
>   				be64_to_cpu(dqp->q_core.d_bcount));
> -			ASSERT(dqp->q_res_icount >=
> +			ASSERT(dqp->q_ino.reserved >=
>   				be64_to_cpu(dqp->q_core.d_icount));
> -			ASSERT(dqp->q_res_rtbcount >=
> +			ASSERT(dqp->q_rtb.reserved >=
>   				be64_to_cpu(dqp->q_core.d_rtbcount));
>   		}
>   	}
> @@ -516,7 +516,7 @@ xfs_trans_unreserve_and_mod_dquots(
>   			if (qtrx->qt_blk_res) {
>   				xfs_dqlock(dqp);
>   				locked = true;
> -				dqp->q_res_bcount -=
> +				dqp->q_blk.reserved -=
>   					(xfs_qcnt_t)qtrx->qt_blk_res;
>   			}
>   			if (qtrx->qt_ino_res) {
> @@ -524,7 +524,7 @@ xfs_trans_unreserve_and_mod_dquots(
>   					xfs_dqlock(dqp);
>   					locked = true;
>   				}
> -				dqp->q_res_icount -=
> +				dqp->q_ino.reserved -=
>   					(xfs_qcnt_t)qtrx->qt_ino_res;
>   			}
>   
> @@ -533,7 +533,7 @@ xfs_trans_unreserve_and_mod_dquots(
>   					xfs_dqlock(dqp);
>   					locked = true;
>   				}
> -				dqp->q_res_rtbcount -=
> +				dqp->q_rtb.reserved -=
>   					(xfs_qcnt_t)qtrx->qt_rtblk_res;
>   			}
>   			if (locked)
> @@ -602,7 +602,7 @@ xfs_trans_dqresv(
>   		timer = be32_to_cpu(dqp->q_core.d_btimer);
>   		warns = be16_to_cpu(dqp->q_core.d_bwarns);
>   		warnlimit = defq->bwarnlimit;
> -		resbcountp = &dqp->q_res_bcount;
> +		resbcountp = &dqp->q_blk.reserved;
>   	} else {
>   		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
>   		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
> @@ -614,7 +614,7 @@ xfs_trans_dqresv(
>   		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>   		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
>   		warnlimit = defq->rtbwarnlimit;
> -		resbcountp = &dqp->q_res_rtbcount;
> +		resbcountp = &dqp->q_rtb.reserved;
>   	}
>   
>   	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
> @@ -675,11 +675,11 @@ xfs_trans_dqresv(
>   
>   	/*
>   	 * Change the reservation, but not the actual usage.
> -	 * Note that q_res_bcount = q_core.d_bcount + resv
> +	 * Note that q_blk.reserved = q_core.d_bcount + resv
>   	 */
>   	(*resbcountp) += (xfs_qcnt_t)nblks;
>   	if (ninos != 0)
> -		dqp->q_res_icount += (xfs_qcnt_t)ninos;
> +		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
>   
>   	/*
>   	 * note the reservation amt in the trans struct too,
> @@ -700,9 +700,9 @@ xfs_trans_dqresv(
>   					    XFS_TRANS_DQ_RES_INOS,
>   					    ninos);
>   	}
> -	ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
> -	ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
> -	ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
> +	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
> +	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
> +	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
>   
>   	xfs_dqunlock(dqp);
>   	return 0;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:50   ` Christoph Hellwig
@ 2020-07-01 20:16   ` Allison Collins
  2020-07-01 23:01   ` Dave Chinner
  3 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 20:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add limits fields in the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Ok, looks reasonable to me
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/scrub/quota.c     |   36 ++++--------
>   fs/xfs/xfs_dquot.c       |  136 ++++++++++++++++++++++++++--------------------
>   fs/xfs/xfs_dquot.h       |    6 ++
>   fs/xfs/xfs_qm.c          |   14 ++---
>   fs/xfs/xfs_qm.h          |   12 ++--
>   fs/xfs/xfs_qm_bhv.c      |   12 ++--
>   fs/xfs/xfs_qm_syscalls.c |   40 ++++++--------
>   fs/xfs/xfs_trace.h       |   12 +---
>   fs/xfs/xfs_trans_dquot.c |   12 ++--
>   9 files changed, 139 insertions(+), 141 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 9a271f115882..1a1c6996fc69 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -82,12 +82,6 @@ xchk_quota_item(
>   	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   	xfs_fileoff_t		offset;
> -	unsigned long long	bsoft;
> -	unsigned long long	isoft;
> -	unsigned long long	rsoft;
> -	unsigned long long	bhard;
> -	unsigned long long	ihard;
> -	unsigned long long	rhard;
>   	unsigned long long	bcount;
>   	unsigned long long	icount;
>   	unsigned long long	rcount;
> @@ -110,15 +104,6 @@ xchk_quota_item(
>   	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
> -	/* Check the limits. */
> -	bhard = be64_to_cpu(d->d_blk_hardlimit);
> -	ihard = be64_to_cpu(d->d_ino_hardlimit);
> -	rhard = be64_to_cpu(d->d_rtb_hardlimit);
> -
> -	bsoft = be64_to_cpu(d->d_blk_softlimit);
> -	isoft = be64_to_cpu(d->d_ino_softlimit);
> -	rsoft = be64_to_cpu(d->d_rtb_softlimit);
> -
>   	/*
>   	 * Warn if the hard limits are larger than the fs.
>   	 * Administrators can do this, though in production this seems
> @@ -127,19 +112,19 @@ xchk_quota_item(
>   	 * Complain about corruption if the soft limit is greater than
>   	 * the hard limit.
>   	 */
> -	if (bhard > mp->m_sb.sb_dblocks)
> +	if (dq->q_blk.hardlimit > mp->m_sb.sb_dblocks)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (bsoft > bhard)
> +	if (dq->q_blk.softlimit > dq->q_blk.hardlimit)
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
> -	if (ihard > M_IGEO(mp)->maxicount)
> +	if (dq->q_ino.hardlimit > M_IGEO(mp)->maxicount)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (isoft > ihard)
> +	if (dq->q_ino.softlimit > dq->q_ino.hardlimit)
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
> -	if (rhard > mp->m_sb.sb_rblocks)
> +	if (dq->q_rtb.hardlimit > mp->m_sb.sb_rblocks)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
> -	if (rsoft > rhard)
> +	if (dq->q_rtb.softlimit > dq->q_rtb.hardlimit)
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
>   	/* Check the resource counts. */
> @@ -173,13 +158,16 @@ xchk_quota_item(
>   	if (dq->q_id == 0)
>   		goto out;
>   
> -	if (bhard != 0 && bcount > bhard)
> +	if (dq->q_blk.hardlimit != 0 &&
> +	    bcount > dq->q_blk.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
> -	if (ihard != 0 && icount > ihard)
> +	if (dq->q_ino.hardlimit != 0 &&
> +	    icount > dq->q_ino.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
> -	if (rhard != 0 && rcount > rhard)
> +	if (dq->q_rtb.hardlimit != 0 &&
> +	    rcount > dq->q_rtb.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
>   out:
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 03624a8f0566..63f744bcbc90 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -70,29 +70,28 @@ xfs_qm_adjust_dqlimits(
>   	struct xfs_dquot	*dq)
>   {
>   	struct xfs_quotainfo	*q = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_def_quota	*defq;
>   	int			prealloc = 0;
>   
>   	ASSERT(dq->q_id);
>   	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>   
> -	if (defq->bsoftlimit && !d->d_blk_softlimit) {
> -		d->d_blk_softlimit = cpu_to_be64(defq->bsoftlimit);
> +	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> +		dq->q_blk.softlimit = defq->bsoftlimit;
>   		prealloc = 1;
>   	}
> -	if (defq->bhardlimit && !d->d_blk_hardlimit) {
> -		d->d_blk_hardlimit = cpu_to_be64(defq->bhardlimit);
> +	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> +		dq->q_blk.hardlimit = defq->bhardlimit;
>   		prealloc = 1;
>   	}
> -	if (defq->isoftlimit && !d->d_ino_softlimit)
> -		d->d_ino_softlimit = cpu_to_be64(defq->isoftlimit);
> -	if (defq->ihardlimit && !d->d_ino_hardlimit)
> -		d->d_ino_hardlimit = cpu_to_be64(defq->ihardlimit);
> -	if (defq->rtbsoftlimit && !d->d_rtb_softlimit)
> -		d->d_rtb_softlimit = cpu_to_be64(defq->rtbsoftlimit);
> -	if (defq->rtbhardlimit && !d->d_rtb_hardlimit)
> -		d->d_rtb_hardlimit = cpu_to_be64(defq->rtbhardlimit);
> +	if (defq->isoftlimit && !dq->q_ino.softlimit)
> +		dq->q_ino.softlimit = defq->isoftlimit;
> +	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> +		dq->q_ino.hardlimit = defq->ihardlimit;
> +	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> +		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> +	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> +		dq->q_rtb.hardlimit = defq->rtbhardlimit;
>   
>   	if (prealloc)
>   		xfs_dquot_set_prealloc_limits(dq);
> @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
>   	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>   
>   #ifdef DEBUG
> -	if (d->d_blk_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> -		       be64_to_cpu(d->d_blk_hardlimit));
> -	if (d->d_ino_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> -		       be64_to_cpu(d->d_ino_hardlimit));
> -	if (d->d_rtb_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> -		       be64_to_cpu(d->d_rtb_hardlimit));
> +	if (dq->q_blk.hardlimit)
> +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> +	if (dq->q_ino.hardlimit)
> +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> +	if (dq->q_rtb.hardlimit)
> +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
>   #endif
>   
>   	if (!d->d_btimer) {
> -		if ((d->d_blk_softlimit &&
> -		     (be64_to_cpu(d->d_bcount) >
> -		      be64_to_cpu(d->d_blk_softlimit))) ||
> -		    (d->d_blk_hardlimit &&
> -		     (be64_to_cpu(d->d_bcount) >
> -		      be64_to_cpu(d->d_blk_hardlimit)))) {
> +		if ((dq->q_blk.softlimit &&
> +		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
> +		    (dq->q_blk.hardlimit &&
> +		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
>   			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->btimelimit);
>   		} else {
>   			d->d_bwarns = 0;
>   		}
>   	} else {
> -		if ((!d->d_blk_softlimit ||
> -		     (be64_to_cpu(d->d_bcount) <=
> -		      be64_to_cpu(d->d_blk_softlimit))) &&
> -		    (!d->d_blk_hardlimit ||
> -		    (be64_to_cpu(d->d_bcount) <=
> -		     be64_to_cpu(d->d_blk_hardlimit)))) {
> +		if ((!dq->q_blk.softlimit ||
> +		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
> +		    (!dq->q_blk.hardlimit ||
> +		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
>   			d->d_btimer = 0;
>   		}
>   	}
>   
>   	if (!d->d_itimer) {
> -		if ((d->d_ino_softlimit &&
> -		     (be64_to_cpu(d->d_icount) >
> -		      be64_to_cpu(d->d_ino_softlimit))) ||
> -		    (d->d_ino_hardlimit &&
> -		     (be64_to_cpu(d->d_icount) >
> -		      be64_to_cpu(d->d_ino_hardlimit)))) {
> +		if ((dq->q_ino.softlimit &&
> +		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
> +		    (dq->q_ino.hardlimit &&
> +		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
>   			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->itimelimit);
>   		} else {
>   			d->d_iwarns = 0;
>   		}
>   	} else {
> -		if ((!d->d_ino_softlimit ||
> -		     (be64_to_cpu(d->d_icount) <=
> -		      be64_to_cpu(d->d_ino_softlimit)))  &&
> -		    (!d->d_ino_hardlimit ||
> -		     (be64_to_cpu(d->d_icount) <=
> -		      be64_to_cpu(d->d_ino_hardlimit)))) {
> +		if ((!dq->q_ino.softlimit ||
> +		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
> +		    (!dq->q_ino.hardlimit ||
> +		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
>   			d->d_itimer = 0;
>   		}
>   	}
>   
>   	if (!d->d_rtbtimer) {
> -		if ((d->d_rtb_softlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) >
> -		      be64_to_cpu(d->d_rtb_softlimit))) ||
> -		    (d->d_rtb_hardlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) >
> -		      be64_to_cpu(d->d_rtb_hardlimit)))) {
> +		if ((dq->q_rtb.softlimit &&
> +		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
> +		    (dq->q_rtb.hardlimit &&
> +		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
>   			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->rtbtimelimit);
>   		} else {
>   			d->d_rtbwarns = 0;
>   		}
>   	} else {
> -		if ((!d->d_rtb_softlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <=
> -		      be64_to_cpu(d->d_rtb_softlimit))) &&
> -		    (!d->d_rtb_hardlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <=
> -		      be64_to_cpu(d->d_rtb_hardlimit)))) {
> +		if ((!dq->q_rtb.softlimit ||
> +		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
> +		    (!dq->q_rtb.hardlimit ||
> +		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
>   			d->d_rtbtimer = 0;
>   		}
>   	}
> @@ -290,8 +274,8 @@ xfs_dquot_set_prealloc_limits(struct xfs_dquot *dqp)
>   {
>   	uint64_t space;
>   
> -	dqp->q_prealloc_hi_wmark = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> -	dqp->q_prealloc_lo_wmark = be64_to_cpu(dqp->q_core.d_blk_softlimit);
> +	dqp->q_prealloc_hi_wmark = dqp->q_blk.hardlimit;
> +	dqp->q_prealloc_lo_wmark = dqp->q_blk.softlimit;
>   	if (!dqp->q_prealloc_lo_wmark) {
>   		dqp->q_prealloc_lo_wmark = dqp->q_prealloc_hi_wmark;
>   		do_div(dqp->q_prealloc_lo_wmark, 100);
> @@ -547,6 +531,12 @@ xfs_dquot_from_disk(
>   
>   	/* copy everything from disk dquot to the incore dquot */
>   	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
> +	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
> +	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
> +	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> +	dqp->q_ino.softlimit = be64_to_cpu(ddqp->d_ino_softlimit);
> +	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
> +	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
>   
>   	/*
>   	 * Reservation counters are defined as reservation plus current usage
> @@ -569,6 +559,12 @@ xfs_dquot_to_disk(
>   {
>   	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
>   	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
> +	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
> +	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
> +	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
> +	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
> +	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
>   }
>   
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1123,9 +1119,29 @@ static xfs_failaddr_t
>   xfs_qm_dqflush_check(
>   	struct xfs_dquot	*dqp)
>   {
> +	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> +
>   	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
>   		return __this_address;
>   
> +	if (dqp->q_id == 0)
> +		return NULL;
> +
> +	if (dqp->q_blk.softlimit &&
> +	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> +	    !ddq->d_btimer)
> +		return __this_address;
> +
> +	if (dqp->q_ino.softlimit &&
> +	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> +	    !ddq->d_itimer)
> +		return __this_address;
> +
> +	if (dqp->q_rtb.softlimit &&
> +	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> +	    !ddq->d_rtbtimer)
> +		return __this_address;
> +
>   	return NULL;
>   }
>   
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index cb20df1e774f..edb49788c476 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -30,6 +30,10 @@ enum {
>   struct xfs_dquot_res {
>   	/* Total resources allocated and reserved. */
>   	xfs_qcnt_t		reserved;
> +
> +	/* Absolute and preferred limits. */
> +	xfs_qcnt_t		hardlimit;
> +	xfs_qcnt_t		softlimit;
>   };
>   
>   /*
> @@ -142,7 +146,7 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
>   {
>   	int64_t freesp;
>   
> -	freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_blk.reserved;
> +	freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
>   	if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
>   		return true;
>   
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 6ce3a4402041..54fc3aac1a68 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -550,26 +550,24 @@ xfs_qm_set_defquota(
>   {
>   	struct xfs_dquot	*dqp;
>   	struct xfs_def_quota	*defq;
> -	struct xfs_disk_dquot	*ddqp;
>   	int			error;
>   
>   	error = xfs_qm_dqget_uncached(mp, 0, type, &dqp);
>   	if (error)
>   		return;
>   
> -	ddqp = &dqp->q_core;
>   	defq = xfs_get_defquota(qinf, xfs_dquot_type(dqp));
>   
>   	/*
>   	 * Timers and warnings have been already set, let's just set the
>   	 * default limits for this quota type
>   	 */
> -	defq->bhardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
> -	defq->bsoftlimit = be64_to_cpu(ddqp->d_blk_softlimit);
> -	defq->ihardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> -	defq->isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit);
> -	defq->rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
> -	defq->rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
> +	defq->bhardlimit = dqp->q_blk.hardlimit;
> +	defq->bsoftlimit = dqp->q_blk.softlimit;
> +	defq->ihardlimit = dqp->q_ino.hardlimit;
> +	defq->isoftlimit = dqp->q_ino.softlimit;
> +	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
> +	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
>   	xfs_qm_dqdestroy(dqp);
>   }
>   
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 43b4650cdcdf..84cb8af468b7 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -20,12 +20,12 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>   #define XFS_DQITER_MAP_SIZE	10
>   
>   #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
> -	!dqp->q_core.d_blk_hardlimit && \
> -	!dqp->q_core.d_blk_softlimit && \
> -	!dqp->q_core.d_rtb_hardlimit && \
> -	!dqp->q_core.d_rtb_softlimit && \
> -	!dqp->q_core.d_ino_hardlimit && \
> -	!dqp->q_core.d_ino_softlimit && \
> +	!dqp->q_blk.hardlimit && \
> +	!dqp->q_blk.softlimit && \
> +	!dqp->q_rtb.hardlimit && \
> +	!dqp->q_rtb.softlimit && \
> +	!dqp->q_ino.hardlimit && \
> +	!dqp->q_ino.softlimit && \
>   	!dqp->q_core.d_bcount && \
>   	!dqp->q_core.d_rtbcount && \
>   	!dqp->q_core.d_icount)
> diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
> index 94b2b4b0fc17..0993217e5ac8 100644
> --- a/fs/xfs/xfs_qm_bhv.c
> +++ b/fs/xfs/xfs_qm_bhv.c
> @@ -23,9 +23,9 @@ xfs_fill_statvfs_from_dquot(
>   {
>   	uint64_t		limit;
>   
> -	limit = dqp->q_core.d_blk_softlimit ?
> -		be64_to_cpu(dqp->q_core.d_blk_softlimit) :
> -		be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> +	limit = dqp->q_blk.softlimit ?
> +		dqp->q_blk.softlimit :
> +		dqp->q_blk.hardlimit;
>   	if (limit && statp->f_blocks > limit) {
>   		statp->f_blocks = limit;
>   		statp->f_bfree = statp->f_bavail =
> @@ -33,9 +33,9 @@ xfs_fill_statvfs_from_dquot(
>   			 (statp->f_blocks - dqp->q_blk.reserved) : 0;
>   	}
>   
> -	limit = dqp->q_core.d_ino_softlimit ?
> -		be64_to_cpu(dqp->q_core.d_ino_softlimit) :
> -		be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> +	limit = dqp->q_ino.softlimit ?
> +		dqp->q_ino.softlimit :
> +		dqp->q_ino.hardlimit;
>   	if (limit && statp->f_files > limit) {
>   		statp->f_files = limit;
>   		statp->f_ffree =
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 56fe80395679..ab596d389e3e 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -495,13 +495,13 @@ xfs_qm_scall_setqlim(
>   	 */
>   	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
> -			be64_to_cpu(ddq->d_blk_hardlimit);
> +			dqp->q_blk.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
> -			be64_to_cpu(ddq->d_blk_softlimit);
> +			dqp->q_blk.softlimit;
>   	if (hard == 0 || hard >= soft) {
> -		ddq->d_blk_hardlimit = cpu_to_be64(hard);
> -		ddq->d_blk_softlimit = cpu_to_be64(soft);
> +		dqp->q_blk.hardlimit = hard;
> +		dqp->q_blk.softlimit = soft;
>   		xfs_dquot_set_prealloc_limits(dqp);
>   		if (id == 0) {
>   			defq->bhardlimit = hard;
> @@ -512,13 +512,13 @@ xfs_qm_scall_setqlim(
>   	}
>   	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
> -			be64_to_cpu(ddq->d_rtb_hardlimit);
> +			dqp->q_rtb.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
> -			be64_to_cpu(ddq->d_rtb_softlimit);
> +			dqp->q_rtb.softlimit;
>   	if (hard == 0 || hard >= soft) {
> -		ddq->d_rtb_hardlimit = cpu_to_be64(hard);
> -		ddq->d_rtb_softlimit = cpu_to_be64(soft);
> +		dqp->q_rtb.hardlimit = hard;
> +		dqp->q_rtb.softlimit = soft;
>   		if (id == 0) {
>   			defq->rtbhardlimit = hard;
>   			defq->rtbsoftlimit = soft;
> @@ -529,13 +529,13 @@ xfs_qm_scall_setqlim(
>   
>   	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
>   		(xfs_qcnt_t) newlim->d_ino_hardlimit :
> -			be64_to_cpu(ddq->d_ino_hardlimit);
> +			dqp->q_ino.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
>   		(xfs_qcnt_t) newlim->d_ino_softlimit :
> -			be64_to_cpu(ddq->d_ino_softlimit);
> +			dqp->q_ino.softlimit;
>   	if (hard == 0 || hard >= soft) {
> -		ddq->d_ino_hardlimit = cpu_to_be64(hard);
> -		ddq->d_ino_softlimit = cpu_to_be64(soft);
> +		dqp->q_ino.hardlimit = hard;
> +		dqp->q_ino.softlimit = soft;
>   		if (id == 0) {
>   			defq->ihardlimit = hard;
>   			defq->isoftlimit = soft;
> @@ -619,10 +619,8 @@ xfs_qm_scall_getquota_fill_qc(
>   	struct qc_dqblk		*dst)
>   {
>   	memset(dst, 0, sizeof(*dst));
> -	dst->d_spc_hardlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
> -	dst->d_spc_softlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
> +	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
> +	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
>   	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
>   	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
>   	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
> @@ -631,10 +629,8 @@ xfs_qm_scall_getquota_fill_qc(
>   	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
>   	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
>   	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
> -	dst->d_rt_spc_hardlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
> -	dst->d_rt_spc_softlimit =
> -		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
> +	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
> +	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>   	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>   	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
>   	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> @@ -661,8 +657,8 @@ xfs_qm_scall_getquota_fill_qc(
>   		    (dst->d_spc_softlimit > 0)) {
>   			ASSERT(dst->d_spc_timer != 0);
>   		}
> -		if ((dst->d_ino_count > dst->d_ino_softlimit) &&
> -		    (dst->d_ino_softlimit > 0)) {
> +		if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
> +		    (dqp->q_ino.softlimit > 0)) {
>   			ASSERT(dst->d_ino_timer != 0);
>   		}
>   	}
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 71567ed367f2..7f744a37dc0e 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -882,14 +882,10 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>   		__entry->res_bcount = dqp->q_blk.reserved;
>   		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
>   		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
> -		__entry->blk_hardlimit =
> -			be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> -		__entry->blk_softlimit =
> -			be64_to_cpu(dqp->q_core.d_blk_softlimit);
> -		__entry->ino_hardlimit =
> -			be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> -		__entry->ino_softlimit =
> -			be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
> +		__entry->blk_softlimit = dqp->q_blk.softlimit;
> +		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
> +		__entry->ino_softlimit = dqp->q_ino.softlimit;
>   	),
>   	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
>   		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 469bf7946d3d..7a3d64eb9fbf 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -593,10 +593,10 @@ xfs_trans_dqresv(
>   	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
>   
>   	if (flags & XFS_TRANS_DQ_RES_BLKS) {
> -		hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
> +		hardlimit = dqp->q_blk.hardlimit;
>   		if (!hardlimit)
>   			hardlimit = defq->bhardlimit;
> -		softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
> +		softlimit = dqp->q_blk.softlimit;
>   		if (!softlimit)
>   			softlimit = defq->bsoftlimit;
>   		timer = be32_to_cpu(dqp->q_core.d_btimer);
> @@ -605,10 +605,10 @@ xfs_trans_dqresv(
>   		resbcountp = &dqp->q_blk.reserved;
>   	} else {
>   		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
> -		hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
> +		hardlimit = dqp->q_rtb.hardlimit;
>   		if (!hardlimit)
>   			hardlimit = defq->rtbhardlimit;
> -		softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
> +		softlimit = dqp->q_rtb.softlimit;
>   		if (!softlimit)
>   			softlimit = defq->rtbsoftlimit;
>   		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> @@ -649,10 +649,10 @@ xfs_trans_dqresv(
>   			timer = be32_to_cpu(dqp->q_core.d_itimer);
>   			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>   			warnlimit = defq->iwarnlimit;
> -			hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> +			hardlimit = dqp->q_ino.hardlimit;
>   			if (!hardlimit)
>   				hardlimit = defq->ihardlimit;
> -			softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +			softlimit = dqp->q_ino.softlimit;
>   			if (!softlimit)
>   				softlimit = defq->isoftlimit;
>   
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
                     ` (2 preceding siblings ...)
  2020-07-01  8:42   ` Christoph Hellwig
@ 2020-07-01 22:41   ` Dave Chinner
  2020-07-01 23:16     ` Darrick J. Wong
  3 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 22:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> While loading dquot records off disk, make sure that the quota type
> flags are the same between the incore dquot and the ondisk dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
>  1 file changed, 20 insertions(+), 3 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d5b7f03e93c8..46c8ca83c04d 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -524,13 +524,27 @@ xfs_dquot_alloc(
>  }
>  
>  /* Copy the in-core quota fields in from the on-disk buffer. */
> -STATIC void
> +STATIC int
>  xfs_dquot_from_disk(
>  	struct xfs_dquot	*dqp,
>  	struct xfs_buf		*bp)
>  {
>  	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
>  
> +	/*
> +	 * The only field the verifier didn't check was the quota type flag, so
> +	 * do that here.
> +	 */
> +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> +	    dqp->q_core.d_id != ddqp->d_id) {
> +		xfs_alert(bp->b_mount,
> +			  "Metadata corruption detected at %pS, quota %u",
> +			  __this_address, be32_to_cpu(dqp->q_core.d_id));

Probably should indicate which quota type is invalid, too. Also,
looking at xfs_buf_corruption_error(), it also uses

		xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, ....

Should that be used here, too?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush
  2020-07-01  8:33   ` Christoph Hellwig
@ 2020-07-01 22:42     ` Dave Chinner
  0 siblings, 0 replies; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 22:42 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Darrick J. Wong, linux-xfs

On Wed, Jul 01, 2020 at 09:33:58AM +0100, Christoph Hellwig wrote:
> On Tue, Jun 30, 2020 at 08:41:56AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > In commit 8d3d7e2b35ea, we changed xfs_qm_dqpurge to bail out if we
> > can't lock the dquot buf to flush the dquot.  This prevents the AIL from
> > blocking on the dquot, but it also forgets to clear the FREEING flag on
> > its way out.  A subsequent purge attempt will see the FREEING flag is
> > set and bail out, which leads to dqpurge_all failing to purge all the
> > dquots.  This causes unmounts and quotaoff operations to hang.
> > 
> > Fixes: 8d3d7e2b35ea ("xfs: trylock underlying buffer on dquot flush")
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Looks like Dave submitted this as a separate fix just after you..

Ah, I didn't look at this patchset yesterday so didn't notice that
Darrick had already posted it. I'm happy for this version to be
merged...

Reviewed-by: Dave Chinner <dchinner@redhat.com>

-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
                     ` (2 preceding siblings ...)
  2020-07-01 20:15   ` Allison Collins
@ 2020-07-01 22:50   ` Dave Chinner
  2020-07-01 23:19     ` Darrick J. Wong
  3 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 22:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Use the incore dq_flags to figure out the dquot type.  This is the first
> step towards removing xfs_disk_dquot from the incore dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
>  fs/xfs/scrub/quota.c           |    4 ----
>  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
>  fs/xfs/xfs_dquot.h             |    2 ++
>  fs/xfs/xfs_dquot_item.c        |    6 ++++--
>  fs/xfs/xfs_qm.c                |    4 ++--
>  fs/xfs/xfs_qm.h                |    2 +-
>  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
>  8 files changed, 45 insertions(+), 17 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> index 56d9dd787e7b..459023b0a304 100644
> --- a/fs/xfs/libxfs/xfs_quota_defs.h
> +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
>  
>  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
>  
> +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)

That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?

> +
>  #define XFS_DQ_FLAGS \
>  	{ XFS_DQ_USER,		"USER" }, \
>  	{ XFS_DQ_PROJ,		"PROJ" }, \
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 905a34558361..710659d3fa28 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -108,10 +108,6 @@ xchk_quota_item(
>  
>  	sqi->last_id = id;
>  
> -	/* Did we get the dquot type we wanted? */
> -	if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
> -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> -
>  	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
>  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>  
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 46c8ca83c04d..59d1bce34a98 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -561,6 +561,16 @@ xfs_dquot_from_disk(
>  	return 0;
>  }
>  
> +/* Copy the in-core quota fields into the on-disk buffer. */
> +void
> +xfs_dquot_to_disk(
> +	struct xfs_disk_dquot	*ddqp,
> +	struct xfs_dquot	*dqp)
> +{
> +	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +}
> +
>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
>  static int
>  xfs_qm_dqread_alloc(
> @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done(
>  	xfs_dqfunlock(dqp);
>  }
>  
> +/* Check incore dquot for errors before we flush. */
> +static xfs_failaddr_t
> +xfs_qm_dqflush_check(
> +	struct xfs_dquot	*dqp)
> +{
> +	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> +		return __this_address;

This only checks the low 8 bits in dq_flags, which is a 32 bit
field. If we ever renumber the dq flags and the dquot types end up
outside the LSB, this code will break.

I don't really see a need to micro-optimise the code so much it
leaves landmines like this in the code...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
                     ` (2 preceding siblings ...)
  2020-07-01 20:16   ` Allison Collins
@ 2020-07-01 23:01   ` Dave Chinner
  2020-07-01 23:13     ` Darrick J. Wong
  3 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:01 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add limits fields in the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
....
> @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
>  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>  
>  #ifdef DEBUG
> -	if (d->d_blk_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> -		       be64_to_cpu(d->d_blk_hardlimit));
> -	if (d->d_ino_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> -		       be64_to_cpu(d->d_ino_hardlimit));
> -	if (d->d_rtb_hardlimit)
> -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> -		       be64_to_cpu(d->d_rtb_hardlimit));
> +	if (dq->q_blk.hardlimit)
> +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> +	if (dq->q_ino.hardlimit)
> +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> +	if (dq->q_rtb.hardlimit)
> +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
>  #endif

You can get rid of the ifdef DEBUG here - if ASSERT is not defined
then the compiler will elide all this code anyway.

>  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1123,9 +1119,29 @@ static xfs_failaddr_t
>  xfs_qm_dqflush_check(
>  	struct xfs_dquot	*dqp)
>  {
> +	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> +
>  	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
>  		return __this_address;
>  
> +	if (dqp->q_id == 0)
> +		return NULL;
> +
> +	if (dqp->q_blk.softlimit &&
> +	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> +	    !ddq->d_btimer)
> +		return __this_address;
> +
> +	if (dqp->q_ino.softlimit &&
> +	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> +	    !ddq->d_itimer)
> +		return __this_address;
> +
> +	if (dqp->q_rtb.softlimit &&
> +	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> +	    !ddq->d_rtbtimer)
> +		return __this_address;

These are new in this patch. These are checked by
xfs_dquot_verify(), so what's the reason for duplicating the checks
here?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:52   ` Christoph Hellwig
@ 2020-07-01 23:07   ` Dave Chinner
  2020-07-01 23:14     ` Darrick J. Wong
  2020-07-02  2:06   ` Allison Collins
  3 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:07 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've stopped using qcore entirely, drop it from the incore
> dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
....
> @@ -1180,7 +1184,6 @@ xfs_qm_dqflush(
>  	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
>  	struct xfs_buf		*bp;
>  	struct xfs_dqblk	*dqb;
> -	struct xfs_disk_dquot	*ddqp;
>  	xfs_failaddr_t		fa;
>  	int			error;
>  
> @@ -1204,22 +1207,6 @@ xfs_qm_dqflush(
>  	if (error)
>  		goto out_abort;
>  
> -	/*
> -	 * Calculate the location of the dquot inside the buffer.
> -	 */
> -	dqb = bp->b_addr + dqp->q_bufoffset;
> -	ddqp = &dqb->dd_diskdq;
> -
> -	/* sanity check the in-core structure before we flush */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
> -	if (fa) {
> -		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				dqp->q_id, fa);
> -		xfs_buf_relse(bp);
> -		error = -EFSCORRUPTED;
> -		goto out_abort;
> -	}
> -
>  	fa = xfs_qm_dqflush_check(dqp);
>  	if (fa) {
>  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> @@ -1229,7 +1216,9 @@ xfs_qm_dqflush(
>  		goto out_abort;
>  	}
>  
> -	xfs_dquot_to_disk(ddqp, dqp);
> +	/* Flush the incore dquot to the ondisk buffer. */
> +	dqb = bp->b_addr + dqp->q_bufoffset;
> +	xfs_dquot_to_disk(&dqb->dd_diskdq, dqp);

Oh, this is really hard to read now. d, q, b, and p are all the same
shape just at different rotations/mirroring, so this now just looks
like a jumble of random letter salad...

Can you rename dqb to dqblk so it's clearly the pointer to the
on-disk dquot block and so easy to differentiate at a glance from
the in-memory dquot pointer?

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-07-01 23:01   ` Dave Chinner
@ 2020-07-01 23:13     ` Darrick J. Wong
  2020-07-01 23:33       ` Darrick J. Wong
  0 siblings, 1 reply; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:13 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote:
> On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Add limits fields in the incore dquot, and use that instead of the ones
> > in qcore.  This eliminates a bunch of endian conversions and will
> > eventually allow us to remove qcore entirely.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ....
> > @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
> >  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
> >  
> >  #ifdef DEBUG
> > -	if (d->d_blk_hardlimit)
> > -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> > -		       be64_to_cpu(d->d_blk_hardlimit));
> > -	if (d->d_ino_hardlimit)
> > -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> > -		       be64_to_cpu(d->d_ino_hardlimit));
> > -	if (d->d_rtb_hardlimit)
> > -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> > -		       be64_to_cpu(d->d_rtb_hardlimit));
> > +	if (dq->q_blk.hardlimit)
> > +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> > +	if (dq->q_ino.hardlimit)
> > +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> > +	if (dq->q_rtb.hardlimit)
> > +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
> >  #endif
> 
> You can get rid of the ifdef DEBUG here - if ASSERT is not defined
> then the compiler will elide all this code anyway.

OK.

> >  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t
> >  xfs_qm_dqflush_check(
> >  	struct xfs_dquot	*dqp)
> >  {
> > +	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> > +
> >  	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> >  		return __this_address;
> >  
> > +	if (dqp->q_id == 0)
> > +		return NULL;
> > +
> > +	if (dqp->q_blk.softlimit &&
> > +	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> > +	    !ddq->d_btimer)
> > +		return __this_address;
> > +
> > +	if (dqp->q_ino.softlimit &&
> > +	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> > +	    !ddq->d_itimer)
> > +		return __this_address;
> > +
> > +	if (dqp->q_rtb.softlimit &&
> > +	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> > +	    !ddq->d_rtbtimer)
> > +		return __this_address;
> 
> These are new in this patch. These are checked by
> xfs_dquot_verify(), so what's the reason for duplicating the checks
> here?

The new functions perform spot-checks of the incore dquot before we start
flushing them out to disk, because the goal of this patch is to further
decouple the incore and ondisk dquots ahead of the y2038 support series.

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-07-01 23:07   ` Dave Chinner
@ 2020-07-01 23:14     ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:14 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 09:07:54AM +1000, Dave Chinner wrote:
> On Tue, Jun 30, 2020 at 08:43:01AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Now that we've stopped using qcore entirely, drop it from the incore
> > dquot.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ....
> > @@ -1180,7 +1184,6 @@ xfs_qm_dqflush(
> >  	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
> >  	struct xfs_buf		*bp;
> >  	struct xfs_dqblk	*dqb;
> > -	struct xfs_disk_dquot	*ddqp;
> >  	xfs_failaddr_t		fa;
> >  	int			error;
> >  
> > @@ -1204,22 +1207,6 @@ xfs_qm_dqflush(
> >  	if (error)
> >  		goto out_abort;
> >  
> > -	/*
> > -	 * Calculate the location of the dquot inside the buffer.
> > -	 */
> > -	dqb = bp->b_addr + dqp->q_bufoffset;
> > -	ddqp = &dqb->dd_diskdq;
> > -
> > -	/* sanity check the in-core structure before we flush */
> > -	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
> > -	if (fa) {
> > -		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> > -				dqp->q_id, fa);
> > -		xfs_buf_relse(bp);
> > -		error = -EFSCORRUPTED;
> > -		goto out_abort;
> > -	}
> > -
> >  	fa = xfs_qm_dqflush_check(dqp);
> >  	if (fa) {
> >  		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> > @@ -1229,7 +1216,9 @@ xfs_qm_dqflush(
> >  		goto out_abort;
> >  	}
> >  
> > -	xfs_dquot_to_disk(ddqp, dqp);
> > +	/* Flush the incore dquot to the ondisk buffer. */
> > +	dqb = bp->b_addr + dqp->q_bufoffset;
> > +	xfs_dquot_to_disk(&dqb->dd_diskdq, dqp);
> 
> Oh, this is really hard to read now. d, q, b, and p are all the same
> shape just at different rotations/mirroring, so this now just looks
> like a jumble of random letter salad...
> 
> Can you rename dqb to dqblk so it's clearly the pointer to the
> on-disk dquot block and so easy to differentiate at a glance from
> the in-memory dquot pointer?

Ok.

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-07-01 22:41   ` Dave Chinner
@ 2020-07-01 23:16     ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:16 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 08:41:12AM +1000, Dave Chinner wrote:
> On Tue, Jun 30, 2020 at 08:42:09AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > While loading dquot records off disk, make sure that the quota type
> > flags are the same between the incore dquot and the ondisk dquot.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/xfs_dquot.c |   23 ++++++++++++++++++++---
> >  1 file changed, 20 insertions(+), 3 deletions(-)
> > 
> > 
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index d5b7f03e93c8..46c8ca83c04d 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -524,13 +524,27 @@ xfs_dquot_alloc(
> >  }
> >  
> >  /* Copy the in-core quota fields in from the on-disk buffer. */
> > -STATIC void
> > +STATIC int
> >  xfs_dquot_from_disk(
> >  	struct xfs_dquot	*dqp,
> >  	struct xfs_buf		*bp)
> >  {
> >  	struct xfs_disk_dquot	*ddqp = bp->b_addr + dqp->q_bufoffset;
> >  
> > +	/*
> > +	 * The only field the verifier didn't check was the quota type flag, so
> > +	 * do that here.
> > +	 */
> > +	if ((dqp->dq_flags & XFS_DQ_ALLTYPES) !=
> > +	    (ddqp->d_flags & XFS_DQ_ALLTYPES) ||
> > +	    dqp->q_core.d_id != ddqp->d_id) {
> > +		xfs_alert(bp->b_mount,
> > +			  "Metadata corruption detected at %pS, quota %u",
> > +			  __this_address, be32_to_cpu(dqp->q_core.d_id));
> 
> Probably should indicate which quota type is invalid, too. Also,
> looking at xfs_buf_corruption_error(), it also uses
> 
> 		xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR, ....
> 
> Should that be used here, too?

Yeah.  Will fix.

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-01 22:50   ` Dave Chinner
@ 2020-07-01 23:19     ` Darrick J. Wong
  2020-07-01 23:44       ` Dave Chinner
  0 siblings, 1 reply; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:19 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Use the incore dq_flags to figure out the dquot type.  This is the first
> > step towards removing xfs_disk_dquot from the incore dquot.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
> >  fs/xfs/scrub/quota.c           |    4 ----
> >  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
> >  fs/xfs/xfs_dquot.h             |    2 ++
> >  fs/xfs/xfs_dquot_item.c        |    6 ++++--
> >  fs/xfs/xfs_qm.c                |    4 ++--
> >  fs/xfs/xfs_qm.h                |    2 +-
> >  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
> >  8 files changed, 45 insertions(+), 17 deletions(-)
> > 
> > 
> > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > index 56d9dd787e7b..459023b0a304 100644
> > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
> >  
> >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> >  
> > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> 
> That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?

Well, based on Christoph's suggestions I broke the incore dquot flags
(XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*).  Not sure
if that's really better, but at least the namespaces are separate now.

> > +
> >  #define XFS_DQ_FLAGS \
> >  	{ XFS_DQ_USER,		"USER" }, \
> >  	{ XFS_DQ_PROJ,		"PROJ" }, \
> > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> > index 905a34558361..710659d3fa28 100644
> > --- a/fs/xfs/scrub/quota.c
> > +++ b/fs/xfs/scrub/quota.c
> > @@ -108,10 +108,6 @@ xchk_quota_item(
> >  
> >  	sqi->last_id = id;
> >  
> > -	/* Did we get the dquot type we wanted? */
> > -	if (dqtype != (d->d_flags & XFS_DQ_ALLTYPES))
> > -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> > -
> >  	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
> >  		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> >  
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index 46c8ca83c04d..59d1bce34a98 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -561,6 +561,16 @@ xfs_dquot_from_disk(
> >  	return 0;
> >  }
> >  
> > +/* Copy the in-core quota fields into the on-disk buffer. */
> > +void
> > +xfs_dquot_to_disk(
> > +	struct xfs_disk_dquot	*ddqp,
> > +	struct xfs_dquot	*dqp)
> > +{
> > +	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> > +	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> > +}
> > +
> >  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> >  static int
> >  xfs_qm_dqread_alloc(
> > @@ -1108,6 +1118,17 @@ xfs_qm_dqflush_done(
> >  	xfs_dqfunlock(dqp);
> >  }
> >  
> > +/* Check incore dquot for errors before we flush. */
> > +static xfs_failaddr_t
> > +xfs_qm_dqflush_check(
> > +	struct xfs_dquot	*dqp)
> > +{
> > +	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> > +		return __this_address;
> 
> This only checks the low 8 bits in dq_flags, which is a 32 bit
> field. If we ever renumber the dq flags and the dquot types end up
> outside the LSB, this code will break.
> 
> I don't really see a need to micro-optimise the code so much it
> leaves landmines like this in the code...

Ok. Fixed.

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 08/18] xfs: stop using q_core counters in the quota code
  2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
@ 2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 23:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add counter fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, looks good
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/scrub/quota.c     |   18 ++++++------------
>   fs/xfs/xfs_dquot.c       |   47 +++++++++++++++++++++++++---------------------
>   fs/xfs/xfs_dquot.h       |    3 +++
>   fs/xfs/xfs_qm.c          |    6 +++---
>   fs/xfs/xfs_qm.h          |    6 +++---
>   fs/xfs/xfs_trace.h       |    4 ++--
>   fs/xfs/xfs_trans_dquot.c |   36 ++++++++++++++---------------------
>   7 files changed, 57 insertions(+), 63 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 1a1c6996fc69..2fc2625feca0 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -82,9 +82,6 @@ xchk_quota_item(
>   	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   	xfs_fileoff_t		offset;
> -	unsigned long long	bcount;
> -	unsigned long long	icount;
> -	unsigned long long	rcount;
>   	xfs_ino_t		fs_icount;
>   	int			error = 0;
>   
> @@ -128,9 +125,6 @@ xchk_quota_item(
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
>   	/* Check the resource counts. */
> -	bcount = be64_to_cpu(d->d_bcount);
> -	icount = be64_to_cpu(d->d_icount);
> -	rcount = be64_to_cpu(d->d_rtbcount);
>   	fs_icount = percpu_counter_sum(&mp->m_icount);
>   
>   	/*
> @@ -139,15 +133,15 @@ xchk_quota_item(
>   	 * if there are no quota limits.
>   	 */
>   	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
> -		if (mp->m_sb.sb_dblocks < bcount)
> +		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
>   			xchk_fblock_set_warning(sc, XFS_DATA_FORK,
>   					offset);
>   	} else {
> -		if (mp->m_sb.sb_dblocks < bcount)
> +		if (mp->m_sb.sb_dblocks < dq->q_blk.count)
>   			xchk_fblock_set_corrupt(sc, XFS_DATA_FORK,
>   					offset);
>   	}
> -	if (icount > fs_icount || rcount > mp->m_sb.sb_rblocks)
> +	if (dq->q_ino.count > fs_icount || dq->q_rtb.count > mp->m_sb.sb_rblocks)
>   		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
>   
>   	/*
> @@ -159,15 +153,15 @@ xchk_quota_item(
>   		goto out;
>   
>   	if (dq->q_blk.hardlimit != 0 &&
> -	    bcount > dq->q_blk.hardlimit)
> +	    dq->q_blk.count > dq->q_blk.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
>   	if (dq->q_ino.hardlimit != 0 &&
> -	    icount > dq->q_ino.hardlimit)
> +	    dq->q_ino.count > dq->q_ino.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
>   	if (dq->q_rtb.hardlimit != 0 &&
> -	    rcount > dq->q_rtb.hardlimit)
> +	    dq->q_rtb.count > dq->q_rtb.hardlimit)
>   		xchk_fblock_set_warning(sc, XFS_DATA_FORK, offset);
>   
>   out:
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 63f744bcbc90..02eae8c2ba1b 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -133,9 +133,9 @@ xfs_qm_adjust_dqtimers(
>   
>   	if (!d->d_btimer) {
>   		if ((dq->q_blk.softlimit &&
> -		     (be64_to_cpu(d->d_bcount) > dq->q_blk.softlimit)) ||
> +		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
>   		    (dq->q_blk.hardlimit &&
> -		     (be64_to_cpu(d->d_bcount) > dq->q_blk.hardlimit))) {
> +		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
>   			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->btimelimit);
>   		} else {
> @@ -143,18 +143,18 @@ xfs_qm_adjust_dqtimers(
>   		}
>   	} else {
>   		if ((!dq->q_blk.softlimit ||
> -		     (be64_to_cpu(d->d_bcount) <= dq->q_blk.softlimit)) &&
> +		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
>   		    (!dq->q_blk.hardlimit ||
> -		    (be64_to_cpu(d->d_bcount) <= dq->q_blk.hardlimit))) {
> +		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
>   			d->d_btimer = 0;
>   		}
>   	}
>   
>   	if (!d->d_itimer) {
>   		if ((dq->q_ino.softlimit &&
> -		     (be64_to_cpu(d->d_icount) > dq->q_ino.softlimit)) ||
> +		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
>   		    (dq->q_ino.hardlimit &&
> -		     (be64_to_cpu(d->d_icount) > dq->q_ino.hardlimit))) {
> +		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
>   			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->itimelimit);
>   		} else {
> @@ -162,18 +162,18 @@ xfs_qm_adjust_dqtimers(
>   		}
>   	} else {
>   		if ((!dq->q_ino.softlimit ||
> -		     (be64_to_cpu(d->d_icount) <= dq->q_ino.softlimit))  &&
> +		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
>   		    (!dq->q_ino.hardlimit ||
> -		     (be64_to_cpu(d->d_icount) <= dq->q_ino.hardlimit))) {
> +		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
>   			d->d_itimer = 0;
>   		}
>   	}
>   
>   	if (!d->d_rtbtimer) {
>   		if ((dq->q_rtb.softlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.softlimit)) ||
> +		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
>   		    (dq->q_rtb.hardlimit &&
> -		     (be64_to_cpu(d->d_rtbcount) > dq->q_rtb.hardlimit))) {
> +		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
>   			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->rtbtimelimit);
>   		} else {
> @@ -181,9 +181,9 @@ xfs_qm_adjust_dqtimers(
>   		}
>   	} else {
>   		if ((!dq->q_rtb.softlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.softlimit)) &&
> +		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
>   		    (!dq->q_rtb.hardlimit ||
> -		     (be64_to_cpu(d->d_rtbcount) <= dq->q_rtb.hardlimit))) {
> +		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
>   			d->d_rtbtimer = 0;
>   		}
>   	}
> @@ -538,13 +538,17 @@ xfs_dquot_from_disk(
>   	dqp->q_rtb.hardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit);
>   	dqp->q_rtb.softlimit = be64_to_cpu(ddqp->d_rtb_softlimit);
>   
> +	dqp->q_blk.count = be64_to_cpu(ddqp->d_bcount);
> +	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
> +	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
> +
>   	/*
>   	 * Reservation counters are defined as reservation plus current usage
>   	 * to avoid having to add every time.
>   	 */
> -	dqp->q_blk.reserved = be64_to_cpu(ddqp->d_bcount);
> -	dqp->q_ino.reserved = be64_to_cpu(ddqp->d_icount);
> -	dqp->q_rtb.reserved = be64_to_cpu(ddqp->d_rtbcount);
> +	dqp->q_blk.reserved = dqp->q_blk.count;
> +	dqp->q_ino.reserved = dqp->q_ino.count;
> +	dqp->q_rtb.reserved = dqp->q_rtb.count;
>   
>   	/* initialize the dquot speculative prealloc thresholds */
>   	xfs_dquot_set_prealloc_limits(dqp);
> @@ -565,6 +569,10 @@ xfs_dquot_to_disk(
>   	ddqp->d_ino_softlimit = cpu_to_be64(dqp->q_ino.softlimit);
>   	ddqp->d_rtb_hardlimit = cpu_to_be64(dqp->q_rtb.hardlimit);
>   	ddqp->d_rtb_softlimit = cpu_to_be64(dqp->q_rtb.softlimit);
> +
> +	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
> +	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
> +	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
>   }
>   
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1127,18 +1135,15 @@ xfs_qm_dqflush_check(
>   	if (dqp->q_id == 0)
>   		return NULL;
>   
> -	if (dqp->q_blk.softlimit &&
> -	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> +	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
>   	    !ddq->d_btimer)
>   		return __this_address;
>   
> -	if (dqp->q_ino.softlimit &&
> -	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> +	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
>   	    !ddq->d_itimer)
>   		return __this_address;
>   
> -	if (dqp->q_rtb.softlimit &&
> -	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> +	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
>   	    !ddq->d_rtbtimer)
>   		return __this_address;
>   
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index edb49788c476..23e05b0d7567 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -31,6 +31,9 @@ struct xfs_dquot_res {
>   	/* Total resources allocated and reserved. */
>   	xfs_qcnt_t		reserved;
>   
> +	/* Total resources allocated. */
> +	xfs_qcnt_t		count;
> +
>   	/* Absolute and preferred limits. */
>   	xfs_qcnt_t		hardlimit;
>   	xfs_qcnt_t		softlimit;
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 54fc3aac1a68..b47bba204240 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1093,14 +1093,14 @@ xfs_qm_quotacheck_dqadjust(
>   	 * Adjust the inode count and the block count to reflect this inode's
>   	 * resource usage.
>   	 */
> -	be64_add_cpu(&dqp->q_core.d_icount, 1);
> +	dqp->q_ino.count++;
>   	dqp->q_ino.reserved++;
>   	if (nblks) {
> -		be64_add_cpu(&dqp->q_core.d_bcount, nblks);
> +		dqp->q_blk.count += nblks;
>   		dqp->q_blk.reserved += nblks;
>   	}
>   	if (rtblks) {
> -		be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks);
> +		dqp->q_rtb.count += rtblks;
>   		dqp->q_rtb.reserved += rtblks;
>   	}
>   
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 84cb8af468b7..6ed4ae942603 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -26,9 +26,9 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>   	!dqp->q_rtb.softlimit && \
>   	!dqp->q_ino.hardlimit && \
>   	!dqp->q_ino.softlimit && \
> -	!dqp->q_core.d_bcount && \
> -	!dqp->q_core.d_rtbcount && \
> -	!dqp->q_core.d_icount)
> +	!dqp->q_blk.count && \
> +	!dqp->q_rtb.count && \
> +	!dqp->q_ino.count)
>   
>   /*
>    * This defines the unit of allocation of dquots.
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 7f744a37dc0e..851f97dfe9e3 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -880,8 +880,8 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>   		__entry->flags = dqp->dq_flags;
>   		__entry->nrefs = dqp->q_nrefs;
>   		__entry->res_bcount = dqp->q_blk.reserved;
> -		__entry->bcount = be64_to_cpu(dqp->q_core.d_bcount);
> -		__entry->icount = be64_to_cpu(dqp->q_core.d_icount);
> +		__entry->bcount = dqp->q_blk.count;
> +		__entry->icount = dqp->q_ino.count;
>   		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
>   		__entry->blk_softlimit = dqp->q_blk.softlimit;
>   		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 7a3d64eb9fbf..b36d747989a7 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -309,7 +309,6 @@ xfs_trans_apply_dquot_deltas(
>   	int			i, j;
>   	struct xfs_dquot	*dqp;
>   	struct xfs_dqtrx	*qtrx, *qa;
> -	struct xfs_disk_dquot	*d;
>   	int64_t			totalbdelta;
>   	int64_t			totalrtbdelta;
>   
> @@ -341,7 +340,6 @@ xfs_trans_apply_dquot_deltas(
>   			/*
>   			 * adjust the actual number of blocks used
>   			 */
> -			d = &dqp->q_core;
>   
>   			/*
>   			 * The issue here is - sometimes we don't make a blkquota
> @@ -362,25 +360,22 @@ xfs_trans_apply_dquot_deltas(
>   				qtrx->qt_delrtb_delta;
>   #ifdef DEBUG
>   			if (totalbdelta < 0)
> -				ASSERT(be64_to_cpu(d->d_bcount) >=
> -				       -totalbdelta);
> +				ASSERT(dqp->q_blk.count >= -totalbdelta);
>   
>   			if (totalrtbdelta < 0)
> -				ASSERT(be64_to_cpu(d->d_rtbcount) >=
> -				       -totalrtbdelta);
> +				ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
>   
>   			if (qtrx->qt_icount_delta < 0)
> -				ASSERT(be64_to_cpu(d->d_icount) >=
> -				       -qtrx->qt_icount_delta);
> +				ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
>   #endif
>   			if (totalbdelta)
> -				be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
> +				dqp->q_blk.count += totalbdelta;
>   
>   			if (qtrx->qt_icount_delta)
> -				be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
> +				dqp->q_ino.count += qtrx->qt_icount_delta;
>   
>   			if (totalrtbdelta)
> -				be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
> +				dqp->q_rtb.count += totalrtbdelta;
>   
>   			/*
>   			 * Get any default limits in use.
> @@ -467,12 +462,9 @@ xfs_trans_apply_dquot_deltas(
>   					    (xfs_qcnt_t)qtrx->qt_icount_delta;
>   			}
>   
> -			ASSERT(dqp->q_blk.reserved >=
> -				be64_to_cpu(dqp->q_core.d_bcount));
> -			ASSERT(dqp->q_ino.reserved >=
> -				be64_to_cpu(dqp->q_core.d_icount));
> -			ASSERT(dqp->q_rtb.reserved >=
> -				be64_to_cpu(dqp->q_core.d_rtbcount));
> +			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
> +			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
> +			ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
>   		}
>   	}
>   }
> @@ -645,7 +637,7 @@ xfs_trans_dqresv(
>   			}
>   		}
>   		if (ninos > 0) {
> -			total_count = dqp->q_res_icount + ninos;
> +			total_count = dqp->q_ino.reserved + ninos;
>   			timer = be32_to_cpu(dqp->q_core.d_itimer);
>   			warns = be16_to_cpu(dqp->q_core.d_iwarns);
>   			warnlimit = defq->iwarnlimit;
> @@ -675,7 +667,7 @@ xfs_trans_dqresv(
>   
>   	/*
>   	 * Change the reservation, but not the actual usage.
> -	 * Note that q_blk.reserved = q_core.d_bcount + resv
> +	 * Note that q_blk.reserved = q_blk.count + resv
>   	 */
>   	(*resbcountp) += (xfs_qcnt_t)nblks;
>   	if (ninos != 0)
> @@ -700,9 +692,9 @@ xfs_trans_dqresv(
>   					    XFS_TRANS_DQ_RES_INOS,
>   					    ninos);
>   	}
> -	ASSERT(dqp->q_blk.reserved >= be64_to_cpu(dqp->q_core.d_bcount));
> -	ASSERT(dqp->q_rtb.reserved >= be64_to_cpu(dqp->q_core.d_rtbcount));
> -	ASSERT(dqp->q_ino.reserved >= be64_to_cpu(dqp->q_core.d_icount));
> +	ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
> +	ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
> +	ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
>   
>   	xfs_dqunlock(dqp);
>   	return 0;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 09/18] xfs: stop using q_core warning counters in the quota code
  2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
  2020-07-01  8:33   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
@ 2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 23:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add warning counter fields to the incore dquot, and use that instead of
> the ones in qcore.  This eliminates a bunch of endian conversions and
> will eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c       |   14 +++++++++++---
>   fs/xfs/xfs_dquot.h       |    8 ++++++++
>   fs/xfs/xfs_qm.c          |   12 ++++++------
>   fs/xfs/xfs_qm_syscalls.c |   12 ++++++------
>   fs/xfs/xfs_trans_dquot.c |    6 +++---
>   5 files changed, 34 insertions(+), 18 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 02eae8c2ba1b..a1edb49ceda5 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -139,7 +139,7 @@ xfs_qm_adjust_dqtimers(
>   			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->btimelimit);
>   		} else {
> -			d->d_bwarns = 0;
> +			dq->q_blk.warnings = 0;
>   		}
>   	} else {
>   		if ((!dq->q_blk.softlimit ||
> @@ -158,7 +158,7 @@ xfs_qm_adjust_dqtimers(
>   			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->itimelimit);
>   		} else {
> -			d->d_iwarns = 0;
> +			dq->q_ino.warnings = 0;
>   		}
>   	} else {
>   		if ((!dq->q_ino.softlimit ||
> @@ -177,7 +177,7 @@ xfs_qm_adjust_dqtimers(
>   			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
>   					defq->rtbtimelimit);
>   		} else {
> -			d->d_rtbwarns = 0;
> +			dq->q_rtb.warnings = 0;
>   		}
>   	} else {
>   		if ((!dq->q_rtb.softlimit ||
> @@ -542,6 +542,10 @@ xfs_dquot_from_disk(
>   	dqp->q_ino.count = be64_to_cpu(ddqp->d_icount);
>   	dqp->q_rtb.count = be64_to_cpu(ddqp->d_rtbcount);
>   
> +	dqp->q_blk.warnings = be16_to_cpu(ddqp->d_bwarns);
> +	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
> +	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
> +
>   	/*
>   	 * Reservation counters are defined as reservation plus current usage
>   	 * to avoid having to add every time.
> @@ -573,6 +577,10 @@ xfs_dquot_to_disk(
>   	ddqp->d_bcount = cpu_to_be64(dqp->q_blk.count);
>   	ddqp->d_icount = cpu_to_be64(dqp->q_ino.count);
>   	ddqp->d_rtbcount = cpu_to_be64(dqp->q_rtb.count);
> +
> +	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
> +	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
> +	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
>   }
>   
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 23e05b0d7567..5840bc54b772 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -37,6 +37,14 @@ struct xfs_dquot_res {
>   	/* Absolute and preferred limits. */
>   	xfs_qcnt_t		hardlimit;
>   	xfs_qcnt_t		softlimit;
> +
> +	/*
> +	 * For root dquots, this is the maximum number of warnings that will
> +	 * be issued for this quota type.  Otherwise, this is the number of
> +	 * warnings issued against this quota.  Note that none of this is
> +	 * implemented.
> +	 */
> +	xfs_qwarncnt_t		warnings;
>   };
>   
>   /*
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index b47bba204240..4e233cfef46d 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -616,12 +616,12 @@ xfs_qm_init_timelimits(
>   		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
>   	if (ddqp->d_rtbtimer)
>   		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
> -	if (ddqp->d_bwarns)
> -		defq->bwarnlimit = be16_to_cpu(ddqp->d_bwarns);
> -	if (ddqp->d_iwarns)
> -		defq->iwarnlimit = be16_to_cpu(ddqp->d_iwarns);
> -	if (ddqp->d_rtbwarns)
> -		defq->rtbwarnlimit = be16_to_cpu(ddqp->d_rtbwarns);
> +	if (dqp->q_blk.warnings)
> +		defq->bwarnlimit = dqp->q_blk.warnings;
> +	if (dqp->q_ino.warnings)
> +		defq->iwarnlimit = dqp->q_ino.warnings;
> +	if (dqp->q_rtb.warnings)
> +		defq->rtbwarnlimit = dqp->q_rtb.warnings;
>   
>   	xfs_qm_dqdestroy(dqp);
>   }
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index ab596d389e3e..5d3bccdbd3bf 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -548,11 +548,11 @@ xfs_qm_scall_setqlim(
>   	 * Update warnings counter(s) if requested
>   	 */
>   	if (newlim->d_fieldmask & QC_SPC_WARNS)
> -		ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns);
> +		dqp->q_blk.warnings = newlim->d_spc_warns;
>   	if (newlim->d_fieldmask & QC_INO_WARNS)
> -		ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns);
> +		dqp->q_ino.warnings = newlim->d_ino_warns;
>   	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -		ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns);
> +		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
>   
>   	if (id == 0) {
>   		if (newlim->d_fieldmask & QC_SPC_WARNS)
> @@ -627,13 +627,13 @@ xfs_qm_scall_getquota_fill_qc(
>   	dst->d_ino_count = dqp->q_ino.reserved;
>   	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
>   	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
> -	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
> -	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
> +	dst->d_ino_warns = dqp->q_ino.warnings;
> +	dst->d_spc_warns = dqp->q_blk.warnings;
>   	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
>   	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>   	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
>   	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> -	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> +	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
>   
>   	/*
>   	 * Internally, we don't reset all the timers when quota enforcement
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index b36d747989a7..21ed8eda3c80 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -592,7 +592,7 @@ xfs_trans_dqresv(
>   		if (!softlimit)
>   			softlimit = defq->bsoftlimit;
>   		timer = be32_to_cpu(dqp->q_core.d_btimer);
> -		warns = be16_to_cpu(dqp->q_core.d_bwarns);
> +		warns = dqp->q_blk.warnings;
>   		warnlimit = defq->bwarnlimit;
>   		resbcountp = &dqp->q_blk.reserved;
>   	} else {
> @@ -604,7 +604,7 @@ xfs_trans_dqresv(
>   		if (!softlimit)
>   			softlimit = defq->rtbsoftlimit;
>   		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> -		warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
> +		warns = dqp->q_rtb.warnings;
>   		warnlimit = defq->rtbwarnlimit;
>   		resbcountp = &dqp->q_rtb.reserved;
>   	}
> @@ -639,7 +639,7 @@ xfs_trans_dqresv(
>   		if (ninos > 0) {
>   			total_count = dqp->q_ino.reserved + ninos;
>   			timer = be32_to_cpu(dqp->q_core.d_itimer);
> -			warns = be16_to_cpu(dqp->q_core.d_iwarns);
> +			warns = dqp->q_ino.warnings;
>   			warnlimit = defq->iwarnlimit;
>   			hardlimit = dqp->q_ino.hardlimit;
>   			if (!hardlimit)
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 10/18] xfs: stop using q_core timers in the quota code
  2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
  2020-07-01  8:34   ` Chandan Babu R
  2020-07-01  8:51   ` Christoph Hellwig
@ 2020-07-01 23:20   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-01 23:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:42 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add timers fields to the incore dquot, and use that instead of the ones
> in qcore.  This eliminates a bunch of endian conversions and will
> eventually allow us to remove qcore entirely.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c       |   41 +++++++++++++++++++++++------------------
>   fs/xfs/xfs_dquot.h       |    7 +++++++
>   fs/xfs/xfs_qm.c          |   15 ++++++---------
>   fs/xfs/xfs_qm_syscalls.c |   18 ++++++++----------
>   fs/xfs/xfs_trans_dquot.c |    6 +++---
>   5 files changed, 47 insertions(+), 40 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index a1edb49ceda5..7434ee57ec43 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -116,7 +116,6 @@ xfs_qm_adjust_dqtimers(
>   	struct xfs_dquot	*dq)
>   {
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_def_quota	*defq;
>   
>   	ASSERT(dq->q_id);
> @@ -131,13 +130,13 @@ xfs_qm_adjust_dqtimers(
>   		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
>   #endif
>   
> -	if (!d->d_btimer) {
> +	if (!dq->q_blk.timer) {
>   		if ((dq->q_blk.softlimit &&
>   		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
>   		    (dq->q_blk.hardlimit &&
>   		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
> -			d->d_btimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->btimelimit);
> +			dq->q_blk.timer = ktime_get_real_seconds() +
> +					defq->btimelimit;
>   		} else {
>   			dq->q_blk.warnings = 0;
>   		}
> @@ -146,17 +145,17 @@ xfs_qm_adjust_dqtimers(
>   		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
>   		    (!dq->q_blk.hardlimit ||
>   		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
> -			d->d_btimer = 0;
> +			dq->q_blk.timer = 0;
>   		}
>   	}
>   
> -	if (!d->d_itimer) {
> +	if (!dq->q_ino.timer) {
>   		if ((dq->q_ino.softlimit &&
>   		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
>   		    (dq->q_ino.hardlimit &&
>   		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
> -			d->d_itimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->itimelimit);
> +			dq->q_ino.timer = ktime_get_real_seconds() +
> +					defq->itimelimit;
>   		} else {
>   			dq->q_ino.warnings = 0;
>   		}
> @@ -165,17 +164,17 @@ xfs_qm_adjust_dqtimers(
>   		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
>   		    (!dq->q_ino.hardlimit ||
>   		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
> -			d->d_itimer = 0;
> +			dq->q_ino.timer = 0;
>   		}
>   	}
>   
> -	if (!d->d_rtbtimer) {
> +	if (!dq->q_rtb.timer) {
>   		if ((dq->q_rtb.softlimit &&
>   		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
>   		    (dq->q_rtb.hardlimit &&
>   		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
> -			d->d_rtbtimer = cpu_to_be32(ktime_get_real_seconds() +
> -					defq->rtbtimelimit);
> +			dq->q_rtb.timer = ktime_get_real_seconds() +
> +					defq->rtbtimelimit;
>   		} else {
>   			dq->q_rtb.warnings = 0;
>   		}
> @@ -184,7 +183,7 @@ xfs_qm_adjust_dqtimers(
>   		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
>   		    (!dq->q_rtb.hardlimit ||
>   		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
> -			d->d_rtbtimer = 0;
> +			dq->q_rtb.timer = 0;
>   		}
>   	}
>   }
> @@ -546,6 +545,10 @@ xfs_dquot_from_disk(
>   	dqp->q_ino.warnings = be16_to_cpu(ddqp->d_iwarns);
>   	dqp->q_rtb.warnings = be16_to_cpu(ddqp->d_rtbwarns);
>   
> +	dqp->q_blk.timer = be32_to_cpu(ddqp->d_btimer);
> +	dqp->q_ino.timer = be32_to_cpu(ddqp->d_itimer);
> +	dqp->q_rtb.timer = be32_to_cpu(ddqp->d_rtbtimer);
> +
>   	/*
>   	 * Reservation counters are defined as reservation plus current usage
>   	 * to avoid having to add every time.
> @@ -581,6 +584,10 @@ xfs_dquot_to_disk(
>   	ddqp->d_bwarns = cpu_to_be16(dqp->q_blk.warnings);
>   	ddqp->d_iwarns = cpu_to_be16(dqp->q_ino.warnings);
>   	ddqp->d_rtbwarns = cpu_to_be16(dqp->q_rtb.warnings);
> +
> +	ddqp->d_btimer = cpu_to_be32(dqp->q_blk.timer);
> +	ddqp->d_itimer = cpu_to_be32(dqp->q_ino.timer);
> +	ddqp->d_rtbtimer = cpu_to_be32(dqp->q_rtb.timer);
>   }
>   
>   /* Allocate and initialize the dquot buffer for this in-core dquot. */
> @@ -1135,8 +1142,6 @@ static xfs_failaddr_t
>   xfs_qm_dqflush_check(
>   	struct xfs_dquot	*dqp)
>   {
> -	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> -
>   	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
>   		return __this_address;
>   
> @@ -1144,15 +1149,15 @@ xfs_qm_dqflush_check(
>   		return NULL;
>   
>   	if (dqp->q_blk.softlimit && dqp->q_blk.count > dqp->q_blk.softlimit &&
> -	    !ddq->d_btimer)
> +	    !dqp->q_blk.timer)
>   		return __this_address;
>   
>   	if (dqp->q_ino.softlimit && dqp->q_ino.count > dqp->q_ino.softlimit &&
> -	    !ddq->d_itimer)
> +	    !dqp->q_ino.timer)
>   		return __this_address;
>   
>   	if (dqp->q_rtb.softlimit && dqp->q_rtb.count > dqp->q_rtb.softlimit &&
> -	    !ddq->d_rtbtimer)
> +	    !dqp->q_rtb.timer)
>   		return __this_address;
>   
>   	return NULL;
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 5840bc54b772..414bae537b1d 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -38,6 +38,13 @@ struct xfs_dquot_res {
>   	xfs_qcnt_t		hardlimit;
>   	xfs_qcnt_t		softlimit;
>   
> +	/*
> +	 * For root dquots, this is the default grace period, in seconds.
> +	 * Otherwise, this is when the quota grace period expires,
> +	 * in seconds since the Unix epoch.
> +	 */
> +	time64_t		timer;
> +
>   	/*
>   	 * For root dquots, this is the maximum number of warnings that will
>   	 * be issued for this quota type.  Otherwise, this is the number of
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 4e233cfef46d..a56c6e4a5d99 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -579,7 +579,6 @@ xfs_qm_init_timelimits(
>   {
>   	struct xfs_quotainfo	*qinf = mp->m_quotainfo;
>   	struct xfs_def_quota	*defq;
> -	struct xfs_disk_dquot	*ddqp;
>   	struct xfs_dquot	*dqp;
>   	int			error;
>   
> @@ -603,19 +602,17 @@ xfs_qm_init_timelimits(
>   	if (error)
>   		return;
>   
> -	ddqp = &dqp->q_core;
> -
>   	/*
>   	 * The warnings and timers set the grace period given to
>   	 * a user or group before he or she can not perform any
>   	 * more writing. If it is zero, a default is used.
>   	 */
> -	if (ddqp->d_btimer)
> -		defq->btimelimit = be32_to_cpu(ddqp->d_btimer);
> -	if (ddqp->d_itimer)
> -		defq->itimelimit = be32_to_cpu(ddqp->d_itimer);
> -	if (ddqp->d_rtbtimer)
> -		defq->rtbtimelimit = be32_to_cpu(ddqp->d_rtbtimer);
> +	if (dqp->q_blk.timer)
> +		defq->btimelimit = dqp->q_blk.timer;
> +	if (dqp->q_ino.timer)
> +		defq->itimelimit = dqp->q_ino.timer;
> +	if (dqp->q_rtb.timer)
> +		defq->rtbtimelimit = dqp->q_rtb.timer;
>   	if (dqp->q_blk.warnings)
>   		defq->bwarnlimit = dqp->q_blk.warnings;
>   	if (dqp->q_ino.warnings)
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 5d3bccdbd3bf..1b2b70b1660f 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -447,7 +447,6 @@ xfs_qm_scall_setqlim(
>   	struct qc_dqblk		*newlim)
>   {
>   	struct xfs_quotainfo	*q = mp->m_quotainfo;
> -	struct xfs_disk_dquot	*ddq;
>   	struct xfs_dquot	*dqp;
>   	struct xfs_trans	*tp;
>   	struct xfs_def_quota	*defq;
> @@ -488,7 +487,6 @@ xfs_qm_scall_setqlim(
>   
>   	xfs_dqlock(dqp);
>   	xfs_trans_dqjoin(tp, dqp);
> -	ddq = &dqp->q_core;
>   
>   	/*
>   	 * Make sure that hardlimits are >= soft limits before changing.
> @@ -573,11 +571,11 @@ xfs_qm_scall_setqlim(
>   	 * the soft limit.
>   	 */
>   	if (newlim->d_fieldmask & QC_SPC_TIMER)
> -		ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer);
> +		dqp->q_blk.timer = newlim->d_spc_timer;
>   	if (newlim->d_fieldmask & QC_INO_TIMER)
> -		ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer);
> +		dqp->q_ino.timer = newlim->d_ino_timer;
>   	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -		ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer);
> +		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
>   
>   	if (id == 0) {
>   		if (newlim->d_fieldmask & QC_SPC_TIMER)
> @@ -621,18 +619,18 @@ xfs_qm_scall_getquota_fill_qc(
>   	memset(dst, 0, sizeof(*dst));
>   	dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
>   	dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
> -	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
> -	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
> +	dst->d_ino_hardlimit = dqp->q_ino.hardlimit;
> +	dst->d_ino_softlimit = dqp->q_ino.softlimit;
>   	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
>   	dst->d_ino_count = dqp->q_ino.reserved;
> -	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
> -	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
> +	dst->d_spc_timer = dqp->q_blk.timer;
> +	dst->d_ino_timer = dqp->q_ino.timer;
>   	dst->d_ino_warns = dqp->q_ino.warnings;
>   	dst->d_spc_warns = dqp->q_blk.warnings;
>   	dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
>   	dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
>   	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
> -	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> +	dst->d_rt_spc_timer = dqp->q_rtb.timer;
>   	dst->d_rt_spc_warns = dqp->q_rtb.warnings;
>   
>   	/*
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 21ed8eda3c80..28b59a4069a3 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -591,7 +591,7 @@ xfs_trans_dqresv(
>   		softlimit = dqp->q_blk.softlimit;
>   		if (!softlimit)
>   			softlimit = defq->bsoftlimit;
> -		timer = be32_to_cpu(dqp->q_core.d_btimer);
> +		timer = dqp->q_blk.timer;
>   		warns = dqp->q_blk.warnings;
>   		warnlimit = defq->bwarnlimit;
>   		resbcountp = &dqp->q_blk.reserved;
> @@ -603,7 +603,7 @@ xfs_trans_dqresv(
>   		softlimit = dqp->q_rtb.softlimit;
>   		if (!softlimit)
>   			softlimit = defq->rtbsoftlimit;
> -		timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
> +		timer = dqp->q_rtb.timer;
>   		warns = dqp->q_rtb.warnings;
>   		warnlimit = defq->rtbwarnlimit;
>   		resbcountp = &dqp->q_rtb.reserved;
> @@ -638,7 +638,7 @@ xfs_trans_dqresv(
>   		}
>   		if (ninos > 0) {
>   			total_count = dqp->q_ino.reserved + ninos;
> -			timer = be32_to_cpu(dqp->q_core.d_itimer);
> +			timer = dqp->q_ino.timer;
>   			warns = dqp->q_ino.warnings;
>   			warnlimit = defq->iwarnlimit;
>   			hardlimit = dqp->q_ino.hardlimit;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
  2020-07-01  8:52   ` Chandan Babu R
  2020-07-01  8:53   ` Christoph Hellwig
@ 2020-07-01 23:30   ` Dave Chinner
  2020-07-02  0:07     ` Darrick J. Wong
  2020-07-02  2:06   ` Allison Collins
  3 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:30 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've split up the dquot resource fields into separate structs,
> do the same for the default limits to enable further refactoring.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_dquot.c       |   30 +++++++++++++++---------------
>  fs/xfs/xfs_qm.c          |   36 ++++++++++++++++++------------------
>  fs/xfs/xfs_qm.h          |   22 ++++++++++------------
>  fs/xfs/xfs_qm_syscalls.c |   24 ++++++++++++------------
>  fs/xfs/xfs_quotaops.c    |   12 ++++++------
>  fs/xfs/xfs_trans_dquot.c |   18 +++++++++---------
>  6 files changed, 70 insertions(+), 72 deletions(-)

A few things here, starting with the "defq" naming. These are
quota limits, not "default quotas". I'd suggest taht this whole
set of structures need to be renamed as "quota limits". e.g

struct xfs_quota_limits {
	xfs_qcnt_t		hard;	/* default hard limit */
	xfs_qcnt_t		soft;	/* default soft limit */
	time64_t		time;	/* limit for timers */
	xfs_qwarncnt_t		warn;	/* limit for warnings */
};

Then we have

	qlim = xfs_qm_get_default_limits(q, xfs_dquot_type(dq));
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 2d6b50760962..6975c27145fc 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits(
>  	ASSERT(dq->q_id);
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>  
> -	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> -		dq->q_blk.softlimit = defq->bsoftlimit;
> +	if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) {
> +		dq->q_blk.softlimit = defq->dfq_blk.softlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> -		dq->q_blk.hardlimit = defq->bhardlimit;
> +	if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) {
> +		dq->q_blk.hardlimit = defq->dfq_blk.hardlimit;
>  		prealloc = 1;
>  	}
> -	if (defq->isoftlimit && !dq->q_ino.softlimit)
> -		dq->q_ino.softlimit = defq->isoftlimit;
> -	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> -		dq->q_ino.hardlimit = defq->ihardlimit;
> -	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> -		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> -	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> -		dq->q_rtb.hardlimit = defq->rtbhardlimit;
> +	if (defq->dfq_ino.softlimit && !dq->q_ino.softlimit)
> +		dq->q_ino.softlimit = defq->dfq_ino.softlimit;
> +	if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit)
> +		dq->q_ino.hardlimit = defq->dfq_ino.hardlimit;
> +	if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit)
> +		dq->q_rtb.softlimit = defq->dfq_rtb.softlimit;
> +	if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit)
> +		dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit;

And all this turns into somthing much easier to read:

....
	if (qlim->ino.soft && !dq->q_ino.softlimit)
		dq->q_ino.softlimit = qlim->ino.soft;
	if (qlim->ino.hard && !dq->q_ino.hardlimit)
		dq->q_ino.hardlimit = qlim->ino.hard;
....

I'll also suggest we don't need to check qlim values here. It could
just be:

	if (!dq->q_ino.softlimit)
		dq->q_ino.softlimit = qlim->ino.soft;
	if (!dq->q_ino.hardlimit)
		dq->q_ino.hardlimit = qlim->ino.hard;


> @@ -41,20 +41,18 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>   */
>  #define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
>  
> +struct xfs_def_qres {
> +	xfs_qcnt_t		hardlimit;	/* default hard limit */
> +	xfs_qcnt_t		softlimit;	/* default soft limit */
> +	time64_t		timelimit;	/* limit for timers */
> +	xfs_qwarncnt_t		warnlimit;	/* limit for warnings */
> +};

As I implied above, this is a quota limits structure, not a "default
quota" structure. I'm not sure what the "res" in the name means,
either...

> +
>  /* Defaults for each quota type: time limits, warn limits, usage limits */
>  struct xfs_def_quota {
> -	time64_t	btimelimit;	/* limit for blks timer */
> -	time64_t	itimelimit;	/* limit for inodes timer */
> -	time64_t	rtbtimelimit;	/* limit for rt blks timer */
> -	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
> -	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
> -	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
> -	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
> -	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
> -	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
> -	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
> -	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
> -	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
> +	struct xfs_def_qres	dfq_blk;
> +	struct xfs_def_qres	dfq_ino;
> +	struct xfs_def_qres	dfq_rtb;
>  };

The namespacing of these variables adds no value. It just makes the
code more verbose and harder to read. e.g.

> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 1b2b70b1660f..393b88612cc8 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim(
>  		dqp->q_blk.softlimit = soft;
>  		xfs_dquot_set_prealloc_limits(dqp);
>  		if (id == 0) {
> -			defq->bhardlimit = hard;
> -			defq->bsoftlimit = soft;
> +			defq->dfq_blk.hardlimit = hard;
> +			defq->dfq_blk.softlimit = soft;

IMO, these sorts of changes decrease the reability of the code. I'd
much prefer something like:

 		if (id == 0) {
-			defq->bhardlimit = hard;
-			defq->bsoftlimit = soft;
+			qlim->blk.hard = hard;
+			qlim->blk.soft = soft;

As it is still clear we are changing the hard block quota limits...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-07-01 23:13     ` Darrick J. Wong
@ 2020-07-01 23:33       ` Darrick J. Wong
  2020-07-01 23:45         ` Dave Chinner
  0 siblings, 1 reply; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:33 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 04:13:43PM -0700, Darrick J. Wong wrote:
> On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote:
> > On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > 
> > > Add limits fields in the incore dquot, and use that instead of the ones
> > > in qcore.  This eliminates a bunch of endian conversions and will
> > > eventually allow us to remove qcore entirely.
> > > 
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ....
> > > @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
> > >  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
> > >  
> > >  #ifdef DEBUG
> > > -	if (d->d_blk_hardlimit)
> > > -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> > > -		       be64_to_cpu(d->d_blk_hardlimit));
> > > -	if (d->d_ino_hardlimit)
> > > -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> > > -		       be64_to_cpu(d->d_ino_hardlimit));
> > > -	if (d->d_rtb_hardlimit)
> > > -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> > > -		       be64_to_cpu(d->d_rtb_hardlimit));
> > > +	if (dq->q_blk.hardlimit)
> > > +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> > > +	if (dq->q_ino.hardlimit)
> > > +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> > > +	if (dq->q_rtb.hardlimit)
> > > +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
> > >  #endif
> > 
> > You can get rid of the ifdef DEBUG here - if ASSERT is not defined
> > then the compiler will elide all this code anyway.
> 
> OK.

Actually, not ok.  A later patch in this series will refactor this whole
ugly function (and in the next round the #ifdefs) out of existence, so
I'll leave this part of the patch the way it is.

--D

> > >  /* Allocate and initialize the dquot buffer for this in-core dquot. */
> > > @@ -1123,9 +1119,29 @@ static xfs_failaddr_t
> > >  xfs_qm_dqflush_check(
> > >  	struct xfs_dquot	*dqp)
> > >  {
> > > +	struct xfs_disk_dquot	*ddq = &dqp->q_core;
> > > +
> > >  	if (hweight8(dqp->dq_flags & XFS_DQ_ALLTYPES) != 1)
> > >  		return __this_address;
> > >  
> > > +	if (dqp->q_id == 0)
> > > +		return NULL;
> > > +
> > > +	if (dqp->q_blk.softlimit &&
> > > +	    be64_to_cpu(ddq->d_bcount) > dqp->q_blk.softlimit &&
> > > +	    !ddq->d_btimer)
> > > +		return __this_address;
> > > +
> > > +	if (dqp->q_ino.softlimit &&
> > > +	    be64_to_cpu(ddq->d_icount) > dqp->q_ino.softlimit &&
> > > +	    !ddq->d_itimer)
> > > +		return __this_address;
> > > +
> > > +	if (dqp->q_rtb.softlimit &&
> > > +	    be64_to_cpu(ddq->d_rtbcount) > dqp->q_rtb.softlimit &&
> > > +	    !ddq->d_rtbtimer)
> > > +		return __this_address;
> > 
> > These are new in this patch. These are checked by
> > xfs_dquot_verify(), so what's the reason for duplicating the checks
> > here?
> 
> The new functions perform spot-checks of the incore dquot before we start
> flushing them out to disk, because the goal of this patch is to further
> decouple the incore and ondisk dquots ahead of the y2038 support series.
> 
> --D
> 
> > Cheers,
> > 
> > Dave.
> > -- 
> > Dave Chinner
> > david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-07-01 17:51     ` Darrick J. Wong
  2020-07-01 18:48       ` Eric Sandeen
@ 2020-07-01 23:34       ` Dave Chinner
  1 sibling, 0 replies; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:34 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: Christoph Hellwig, linux-xfs, Eric Sandeen, Amir Goldstein

On Wed, Jul 01, 2020 at 10:51:34AM -0700, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 09:56:21AM +0100, Christoph Hellwig wrote:
> > On Tue, Jun 30, 2020 at 08:43:20AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > 
> > > Refactor the open-coded test for whether or not we're over quota.
> > > 
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ---
> > >  fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
> > >  1 file changed, 30 insertions(+), 65 deletions(-)
> > > 
> > > 
> > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > > index 35a113d1b42b..ef34c82c28a0 100644
> > > --- a/fs/xfs/xfs_dquot.c
> > > +++ b/fs/xfs/xfs_dquot.c
> > > @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
> > >  		xfs_dquot_set_prealloc_limits(dq);
> > >  }
> > >  
> > > +/*
> > > + * Determine if this quota counter is over either limit and set the quota
> > > + * timers as appropriate.
> > > + */
> > > +static inline void
> > > +xfs_qm_adjust_res_timer(
> > > +	struct xfs_dquot_res	*res,
> > > +	struct xfs_def_qres	*dres)
> > > +{
> > > +	bool			over;
> > > +
> > > +#ifdef DEBUG
> > > +	if (res->hardlimit)
> > > +		ASSERT(res->softlimit <= res->hardlimit);
> > > +#endif
> > 
> > Maybe:
> > 	ASSERRT(!res->hardlimit || res->softlimit <= res->hardlimit);
> 
> Changed.
> 
> > 
> > > +
> > > +	over = (res->softlimit && res->count > res->softlimit) ||
> > > +	       (res->hardlimit && res->count > res->hardlimit);
> > > +
> > > +	if (over && res->timer == 0)
> > > +		res->timer = ktime_get_real_seconds() + dres->timelimit;
> > > +	else if (!over && res->timer != 0)
> > > +		res->timer = 0;
> > > +	else if (!over && res->timer == 0)
> > > +		res->warnings = 0;
> > 
> > What about:
> > 
> > 	if ((res->softlimit && res->count > res->softlimit) ||
> > 	    (res->hardlimit && res->count > res->hardlimit)) {
> > 		if (res->timer == 0)	
> > 			res->timer = ktime_get_real_seconds() + dres->timelimit;
> > 	} else {
> > 		if (res->timer)
> > 			res->timer = 0;
> > 		else
> > 			res->warnings = 0;
> > 	}
> 
> I don't care either way, but the last time I sent this patch out, Eric
> and Amir seemed to want a flatter if structure:

I much prefer Christoph's version - I was going to suggest the same
sort of thing myself as the "flatter" version just looks needlessly
convoluted to me.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-01 23:19     ` Darrick J. Wong
@ 2020-07-01 23:44       ` Dave Chinner
  2020-07-01 23:50         ` Darrick J. Wong
  0 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > 
> > > Use the incore dq_flags to figure out the dquot type.  This is the first
> > > step towards removing xfs_disk_dquot from the incore dquot.
> > > 
> > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ---
> > >  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
> > >  fs/xfs/scrub/quota.c           |    4 ----
> > >  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
> > >  fs/xfs/xfs_dquot.h             |    2 ++
> > >  fs/xfs/xfs_dquot_item.c        |    6 ++++--
> > >  fs/xfs/xfs_qm.c                |    4 ++--
> > >  fs/xfs/xfs_qm.h                |    2 +-
> > >  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
> > >  8 files changed, 45 insertions(+), 17 deletions(-)
> > > 
> > > 
> > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > index 56d9dd787e7b..459023b0a304 100644
> > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
> > >  
> > >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > >  
> > > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> > 
> > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
> 
> Well, based on Christoph's suggestions I broke the incore dquot flags
> (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*).  Not sure
> if that's really better, but at least the namespaces are separate now.

Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
doesn't actually indicate what part of the on-disk dquot it refers
to. We use the phrase "on-disk dquot" to refer to the entire on-disk
dquot, not a subset of flags in a flags field in the on-disk
dquot. Hence the name of this variable needs to be more specific as
to what it applies to in the on-disk dquot...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 07/18] xfs: stop using q_core limits in the quota code
  2020-07-01 23:33       ` Darrick J. Wong
@ 2020-07-01 23:45         ` Dave Chinner
  0 siblings, 0 replies; 94+ messages in thread
From: Dave Chinner @ 2020-07-01 23:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 04:33:30PM -0700, Darrick J. Wong wrote:
> On Wed, Jul 01, 2020 at 04:13:43PM -0700, Darrick J. Wong wrote:
> > On Thu, Jul 02, 2020 at 09:01:36AM +1000, Dave Chinner wrote:
> > > On Tue, Jun 30, 2020 at 08:42:36AM -0700, Darrick J. Wong wrote:
> > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > > 
> > > > Add limits fields in the incore dquot, and use that instead of the ones
> > > > in qcore.  This eliminates a bunch of endian conversions and will
> > > > eventually allow us to remove qcore entirely.
> > > > 
> > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > ....
> > > > @@ -124,82 +123,67 @@ xfs_qm_adjust_dqtimers(
> > > >  	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
> > > >  
> > > >  #ifdef DEBUG
> > > > -	if (d->d_blk_hardlimit)
> > > > -		ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
> > > > -		       be64_to_cpu(d->d_blk_hardlimit));
> > > > -	if (d->d_ino_hardlimit)
> > > > -		ASSERT(be64_to_cpu(d->d_ino_softlimit) <=
> > > > -		       be64_to_cpu(d->d_ino_hardlimit));
> > > > -	if (d->d_rtb_hardlimit)
> > > > -		ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
> > > > -		       be64_to_cpu(d->d_rtb_hardlimit));
> > > > +	if (dq->q_blk.hardlimit)
> > > > +		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> > > > +	if (dq->q_ino.hardlimit)
> > > > +		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> > > > +	if (dq->q_rtb.hardlimit)
> > > > +		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
> > > >  #endif
> > > 
> > > You can get rid of the ifdef DEBUG here - if ASSERT is not defined
> > > then the compiler will elide all this code anyway.
> > 
> > OK.
> 
> Actually, not ok.  A later patch in this series will refactor this whole
> ugly function (and in the next round the #ifdefs) out of existence, so
> I'll leave this part of the patch the way it is.

Ok.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-01 23:44       ` Dave Chinner
@ 2020-07-01 23:50         ` Darrick J. Wong
  2020-07-03  0:58           ` Dave Chinner
  0 siblings, 1 reply; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-01 23:50 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote:
> On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > > 
> > > > Use the incore dq_flags to figure out the dquot type.  This is the first
> > > > step towards removing xfs_disk_dquot from the incore dquot.
> > > > 
> > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > ---
> > > >  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
> > > >  fs/xfs/scrub/quota.c           |    4 ----
> > > >  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
> > > >  fs/xfs/xfs_dquot.h             |    2 ++
> > > >  fs/xfs/xfs_dquot_item.c        |    6 ++++--
> > > >  fs/xfs/xfs_qm.c                |    4 ++--
> > > >  fs/xfs/xfs_qm.h                |    2 +-
> > > >  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
> > > >  8 files changed, 45 insertions(+), 17 deletions(-)
> > > > 
> > > > 
> > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > index 56d9dd787e7b..459023b0a304 100644
> > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
> > > >  
> > > >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > > >  
> > > > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> > > 
> > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
> > 
> > Well, based on Christoph's suggestions I broke the incore dquot flags
> > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*).  Not sure
> > if that's really better, but at least the namespaces are separate now.
> 
> Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
> doesn't actually indicate what part of the on-disk dquot it refers
> to. We use the phrase "on-disk dquot" to refer to the entire on-disk
> dquot, not a subset of flags in a flags field in the on-disk
> dquot. Hence the name of this variable needs to be more specific as
> to what it applies to in the on-disk dquot...

Sorry, I was typing too fast.  xfs_format.h now has:

#define XFS_DQFLAG_USER		0x01		/* user dquot record */
#define XFS_DQFLAG_PROJ		0x02		/* project dquot record */
#define XFS_DQFLAG_GROUP	0x04		/* group dquot record */

#define XFS_DQFLAG_TYPE_MASK	(XFS_DQFLAG_USER | \
				 XFS_DQFLAG_PROJ | \
				 XFS_DQFLAG_GROUP)

#define XFS_DQFLAG_ALL		(XFS_DQFLAG_TYPE_MASK)

/*
 * This is the main portion of the on-disk representation of quota
 * information for a user. This is the q_core of the struct xfs_dquot
 * that is kept in kernel memory. We pad this with some more expansion
 * room to construct the on disk structure.
 */
struct xfs_disk_dquot {
	__be16		d_magic;	/* dquot magic = XFS_DQUOT_MAGIC */
	__u8		d_version;	/* dquot version */
	__u8		d_flags;	/* XFS_DQFLAG_* */

I'm not particularly thrilled about the DQFLAG/DQ thing though.  DDFLAG?

(Also note that the future bigtime series will add a new ondisk flag
XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.)

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-07-01 23:30   ` Dave Chinner
@ 2020-07-02  0:07     ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-02  0:07 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 09:30:01AM +1000, Dave Chinner wrote:
> On Tue, Jun 30, 2020 at 08:43:07AM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Now that we've split up the dquot resource fields into separate structs,
> > do the same for the default limits to enable further refactoring.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  fs/xfs/xfs_dquot.c       |   30 +++++++++++++++---------------
> >  fs/xfs/xfs_qm.c          |   36 ++++++++++++++++++------------------
> >  fs/xfs/xfs_qm.h          |   22 ++++++++++------------
> >  fs/xfs/xfs_qm_syscalls.c |   24 ++++++++++++------------
> >  fs/xfs/xfs_quotaops.c    |   12 ++++++------
> >  fs/xfs/xfs_trans_dquot.c |   18 +++++++++---------
> >  6 files changed, 70 insertions(+), 72 deletions(-)
> 
> A few things here, starting with the "defq" naming. These are
> quota limits, not "default quotas". I'd suggest taht this whole
> set of structures need to be renamed as "quota limits". e.g
> 
> struct xfs_quota_limits {
> 	xfs_qcnt_t		hard;	/* default hard limit */
> 	xfs_qcnt_t		soft;	/* default soft limit */
> 	time64_t		time;	/* limit for timers */
> 	xfs_qwarncnt_t		warn;	/* limit for warnings */

Ahaha, much better naming.  Thank you!

> };
> 
> Then we have
> 
> 	qlim = xfs_qm_get_default_limits(q, xfs_dquot_type(dq));
> > 
> > 
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index 2d6b50760962..6975c27145fc 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits(
> >  	ASSERT(dq->q_id);
> >  	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
> >  
> > -	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> > -		dq->q_blk.softlimit = defq->bsoftlimit;
> > +	if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) {
> > +		dq->q_blk.softlimit = defq->dfq_blk.softlimit;
> >  		prealloc = 1;
> >  	}
> > -	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> > -		dq->q_blk.hardlimit = defq->bhardlimit;
> > +	if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) {
> > +		dq->q_blk.hardlimit = defq->dfq_blk.hardlimit;
> >  		prealloc = 1;
> >  	}
> > -	if (defq->isoftlimit && !dq->q_ino.softlimit)
> > -		dq->q_ino.softlimit = defq->isoftlimit;
> > -	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> > -		dq->q_ino.hardlimit = defq->ihardlimit;
> > -	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> > -		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> > -	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> > -		dq->q_rtb.hardlimit = defq->rtbhardlimit;
> > +	if (defq->dfq_ino.softlimit && !dq->q_ino.softlimit)
> > +		dq->q_ino.softlimit = defq->dfq_ino.softlimit;
> > +	if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit)
> > +		dq->q_ino.hardlimit = defq->dfq_ino.hardlimit;
> > +	if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit)
> > +		dq->q_rtb.softlimit = defq->dfq_rtb.softlimit;
> > +	if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit)
> > +		dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit;
> 
> And all this turns into somthing much easier to read:
> 
> ....
> 	if (qlim->ino.soft && !dq->q_ino.softlimit)
> 		dq->q_ino.softlimit = qlim->ino.soft;
> 	if (qlim->ino.hard && !dq->q_ino.hardlimit)
> 		dq->q_ino.hardlimit = qlim->ino.hard;
> ....

<nod> Will do.

> I'll also suggest we don't need to check qlim values here. It could
> just be:
> 
> 	if (!dq->q_ino.softlimit)
> 		dq->q_ino.softlimit = qlim->ino.soft;
> 	if (!dq->q_ino.hardlimit)
> 		dq->q_ino.hardlimit = qlim->ino.hard;

Separate patch, but yes, I don't think we really need to check that the
defaults are set, because (afaict) xfs_qm_set_defquota always sets them
to something nowadays, even if that something is a zero limit in the root
dquot.

> 
> > @@ -41,20 +41,18 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
> >   */
> >  #define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
> >  
> > +struct xfs_def_qres {
> > +	xfs_qcnt_t		hardlimit;	/* default hard limit */
> > +	xfs_qcnt_t		softlimit;	/* default soft limit */
> > +	time64_t		timelimit;	/* limit for timers */
> > +	xfs_qwarncnt_t		warnlimit;	/* limit for warnings */
> > +};
> 
> As I implied above, this is a quota limits structure, not a "default
> quota" structure. I'm not sure what the "res" in the name means,
> either...

default quota resource limit, but xfs_quota_limits fits the bill
nicely.

> > +
> >  /* Defaults for each quota type: time limits, warn limits, usage limits */
> >  struct xfs_def_quota {
> > -	time64_t	btimelimit;	/* limit for blks timer */
> > -	time64_t	itimelimit;	/* limit for inodes timer */
> > -	time64_t	rtbtimelimit;	/* limit for rt blks timer */
> > -	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
> > -	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
> > -	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
> > -	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
> > -	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
> > -	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
> > -	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
> > -	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
> > -	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
> > +	struct xfs_def_qres	dfq_blk;
> > +	struct xfs_def_qres	dfq_ino;
> > +	struct xfs_def_qres	dfq_rtb;
> >  };
> 
> The namespacing of these variables adds no value. It just makes the
> code more verbose and harder to read. e.g.
> 
> > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> > index 1b2b70b1660f..393b88612cc8 100644
> > --- a/fs/xfs/xfs_qm_syscalls.c
> > +++ b/fs/xfs/xfs_qm_syscalls.c
> > @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim(
> >  		dqp->q_blk.softlimit = soft;
> >  		xfs_dquot_set_prealloc_limits(dqp);
> >  		if (id == 0) {
> > -			defq->bhardlimit = hard;
> > -			defq->bsoftlimit = soft;
> > +			defq->dfq_blk.hardlimit = hard;
> > +			defq->dfq_blk.softlimit = soft;
> 
> IMO, these sorts of changes decrease the reability of the code. I'd
> much prefer something like:
> 
>  		if (id == 0) {
> -			defq->bhardlimit = hard;
> -			defq->bsoftlimit = soft;
> +			qlim->blk.hard = hard;
> +			qlim->blk.soft = soft;
> 
> As it is still clear we are changing the hard block quota limits...

<nod> Done.  Thanks for slogging through this growing patchset...

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 11/18] xfs: remove qcore from incore dquots
  2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
                     ` (2 preceding siblings ...)
  2020-07-01 23:07   ` Dave Chinner
@ 2020-07-02  2:06   ` Allison Collins
  3 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-02  2:06 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've stopped using qcore entirely, drop it from the incore
> dquot.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/scrub/quota.c |    4 ----
>   fs/xfs/xfs_dquot.c   |   29 +++++++++--------------------
>   fs/xfs/xfs_dquot.h   |    1 -
>   3 files changed, 9 insertions(+), 25 deletions(-)
> 
> 
> diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c
> index 2fc2625feca0..f4aad5b00188 100644
> --- a/fs/xfs/scrub/quota.c
> +++ b/fs/xfs/scrub/quota.c
> @@ -79,7 +79,6 @@ xchk_quota_item(
>   	struct xchk_quota_info	*sqi = priv;
>   	struct xfs_scrub	*sc = sqi->sc;
>   	struct xfs_mount	*mp = sc->mp;
> -	struct xfs_disk_dquot	*d = &dq->q_core;
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   	xfs_fileoff_t		offset;
>   	xfs_ino_t		fs_icount;
> @@ -98,9 +97,6 @@ xchk_quota_item(
>   
>   	sqi->last_id = dq->q_id;
>   
> -	if (d->d_pad0 != cpu_to_be32(0) || d->d_pad != cpu_to_be16(0))
> -		xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, offset);
> -
>   	/*
>   	 * Warn if the hard limits are larger than the fs.
>   	 * Administrators can do this, though in production this seems
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 7434ee57ec43..2d6b50760962 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -529,7 +529,6 @@ xfs_dquot_from_disk(
>   	}
>   
>   	/* copy everything from disk dquot to the incore dquot */
> -	memcpy(&dqp->q_core, ddqp, sizeof(struct xfs_disk_dquot));
>   	dqp->q_blk.hardlimit = be64_to_cpu(ddqp->d_blk_hardlimit);
>   	dqp->q_blk.softlimit = be64_to_cpu(ddqp->d_blk_softlimit);
>   	dqp->q_ino.hardlimit = be64_to_cpu(ddqp->d_ino_hardlimit);
> @@ -568,8 +567,13 @@ xfs_dquot_to_disk(
>   	struct xfs_disk_dquot	*ddqp,
>   	struct xfs_dquot	*dqp)
>   {
> -	memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
> +	ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC);
> +	ddqp->d_version = XFS_DQUOT_VERSION;
>   	ddqp->d_flags = dqp->dq_flags & XFS_DQ_ONDISK;
> +	ddqp->d_id = cpu_to_be32(dqp->q_id);
> +	ddqp->d_pad0 = 0;
> +	ddqp->d_pad = 0;
> +
>   	ddqp->d_blk_hardlimit = cpu_to_be64(dqp->q_blk.hardlimit);
>   	ddqp->d_blk_softlimit = cpu_to_be64(dqp->q_blk.softlimit);
>   	ddqp->d_ino_hardlimit = cpu_to_be64(dqp->q_ino.hardlimit);
> @@ -1180,7 +1184,6 @@ xfs_qm_dqflush(
>   	struct xfs_log_item	*lip = &dqp->q_logitem.qli_item;
>   	struct xfs_buf		*bp;
>   	struct xfs_dqblk	*dqb;
> -	struct xfs_disk_dquot	*ddqp;
>   	xfs_failaddr_t		fa;
>   	int			error;
>   
> @@ -1204,22 +1207,6 @@ xfs_qm_dqflush(
>   	if (error)
>   		goto out_abort;
>   
> -	/*
> -	 * Calculate the location of the dquot inside the buffer.
> -	 */
> -	dqb = bp->b_addr + dqp->q_bufoffset;
> -	ddqp = &dqb->dd_diskdq;
> -
> -	/* sanity check the in-core structure before we flush */
> -	fa = xfs_dquot_verify(mp, &dqp->q_core, dqp->q_id, 0);
> -	if (fa) {
> -		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> -				dqp->q_id, fa);
> -		xfs_buf_relse(bp);
> -		error = -EFSCORRUPTED;
> -		goto out_abort;
> -	}
> -
>   	fa = xfs_qm_dqflush_check(dqp);
>   	if (fa) {
>   		xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
> @@ -1229,7 +1216,9 @@ xfs_qm_dqflush(
>   		goto out_abort;
>   	}
>   
> -	xfs_dquot_to_disk(ddqp, dqp);
> +	/* Flush the incore dquot to the ondisk buffer. */
> +	dqb = bp->b_addr + dqp->q_bufoffset;
> +	xfs_dquot_to_disk(&dqb->dd_diskdq, dqp);
>   
>   	/*
>   	 * Clear the dirty field and remember the flush lsn for later use.
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 414bae537b1d..62b0fc6e0133 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -71,7 +71,6 @@ struct xfs_dquot {
>   	struct xfs_dquot_res	q_ino;	/* inodes */
>   	struct xfs_dquot_res	q_rtb;	/* realtime blocks */
>   
> -	struct xfs_disk_dquot	q_core;
>   	struct xfs_dq_logitem	q_logitem;
>   
>   	xfs_qcnt_t		q_prealloc_lo_wmark;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 12/18] xfs: refactor default quota limits by resource
  2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
                     ` (2 preceding siblings ...)
  2020-07-01 23:30   ` Dave Chinner
@ 2020-07-02  2:06   ` Allison Collins
  3 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-02  2:06 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've split up the dquot resource fields into separate structs,
> do the same for the default limits to enable further refactoring.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, looks good
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c       |   30 +++++++++++++++---------------
>   fs/xfs/xfs_qm.c          |   36 ++++++++++++++++++------------------
>   fs/xfs/xfs_qm.h          |   22 ++++++++++------------
>   fs/xfs/xfs_qm_syscalls.c |   24 ++++++++++++------------
>   fs/xfs/xfs_quotaops.c    |   12 ++++++------
>   fs/xfs/xfs_trans_dquot.c |   18 +++++++++---------
>   6 files changed, 70 insertions(+), 72 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 2d6b50760962..6975c27145fc 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -76,22 +76,22 @@ xfs_qm_adjust_dqlimits(
>   	ASSERT(dq->q_id);
>   	defq = xfs_get_defquota(q, xfs_dquot_type(dq));
>   
> -	if (defq->bsoftlimit && !dq->q_blk.softlimit) {
> -		dq->q_blk.softlimit = defq->bsoftlimit;
> +	if (defq->dfq_blk.softlimit && !dq->q_blk.softlimit) {
> +		dq->q_blk.softlimit = defq->dfq_blk.softlimit;
>   		prealloc = 1;
>   	}
> -	if (defq->bhardlimit && !dq->q_blk.hardlimit) {
> -		dq->q_blk.hardlimit = defq->bhardlimit;
> +	if (defq->dfq_blk.hardlimit && !dq->q_blk.hardlimit) {
> +		dq->q_blk.hardlimit = defq->dfq_blk.hardlimit;
>   		prealloc = 1;
>   	}
> -	if (defq->isoftlimit && !dq->q_ino.softlimit)
> -		dq->q_ino.softlimit = defq->isoftlimit;
> -	if (defq->ihardlimit && !dq->q_ino.hardlimit)
> -		dq->q_ino.hardlimit = defq->ihardlimit;
> -	if (defq->rtbsoftlimit && !dq->q_rtb.softlimit)
> -		dq->q_rtb.softlimit = defq->rtbsoftlimit;
> -	if (defq->rtbhardlimit && !dq->q_rtb.hardlimit)
> -		dq->q_rtb.hardlimit = defq->rtbhardlimit;
> +	if (defq->dfq_ino.softlimit && !dq->q_ino.softlimit)
> +		dq->q_ino.softlimit = defq->dfq_ino.softlimit;
> +	if (defq->dfq_ino.hardlimit && !dq->q_ino.hardlimit)
> +		dq->q_ino.hardlimit = defq->dfq_ino.hardlimit;
> +	if (defq->dfq_rtb.softlimit && !dq->q_rtb.softlimit)
> +		dq->q_rtb.softlimit = defq->dfq_rtb.softlimit;
> +	if (defq->dfq_rtb.hardlimit && !dq->q_rtb.hardlimit)
> +		dq->q_rtb.hardlimit = defq->dfq_rtb.hardlimit;
>   
>   	if (prealloc)
>   		xfs_dquot_set_prealloc_limits(dq);
> @@ -136,7 +136,7 @@ xfs_qm_adjust_dqtimers(
>   		    (dq->q_blk.hardlimit &&
>   		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
>   			dq->q_blk.timer = ktime_get_real_seconds() +
> -					defq->btimelimit;
> +					defq->dfq_blk.timelimit;
>   		} else {
>   			dq->q_blk.warnings = 0;
>   		}
> @@ -155,7 +155,7 @@ xfs_qm_adjust_dqtimers(
>   		    (dq->q_ino.hardlimit &&
>   		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
>   			dq->q_ino.timer = ktime_get_real_seconds() +
> -					defq->itimelimit;
> +					defq->dfq_ino.timelimit;
>   		} else {
>   			dq->q_ino.warnings = 0;
>   		}
> @@ -174,7 +174,7 @@ xfs_qm_adjust_dqtimers(
>   		    (dq->q_rtb.hardlimit &&
>   		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
>   			dq->q_rtb.timer = ktime_get_real_seconds() +
> -					defq->rtbtimelimit;
> +					defq->dfq_rtb.timelimit;
>   		} else {
>   			dq->q_rtb.warnings = 0;
>   		}
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index a56c6e4a5d99..28326a6264a8 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -562,12 +562,12 @@ xfs_qm_set_defquota(
>   	 * Timers and warnings have been already set, let's just set the
>   	 * default limits for this quota type
>   	 */
> -	defq->bhardlimit = dqp->q_blk.hardlimit;
> -	defq->bsoftlimit = dqp->q_blk.softlimit;
> -	defq->ihardlimit = dqp->q_ino.hardlimit;
> -	defq->isoftlimit = dqp->q_ino.softlimit;
> -	defq->rtbhardlimit = dqp->q_rtb.hardlimit;
> -	defq->rtbsoftlimit = dqp->q_rtb.softlimit;
> +	defq->dfq_blk.hardlimit = dqp->q_blk.hardlimit;
> +	defq->dfq_blk.softlimit = dqp->q_blk.softlimit;
> +	defq->dfq_ino.hardlimit = dqp->q_ino.hardlimit;
> +	defq->dfq_ino.softlimit = dqp->q_ino.softlimit;
> +	defq->dfq_rtb.hardlimit = dqp->q_rtb.hardlimit;
> +	defq->dfq_rtb.softlimit = dqp->q_rtb.softlimit;
>   	xfs_qm_dqdestroy(dqp);
>   }
>   
> @@ -584,12 +584,12 @@ xfs_qm_init_timelimits(
>   
>   	defq = xfs_get_defquota(qinf, type);
>   
> -	defq->btimelimit = XFS_QM_BTIMELIMIT;
> -	defq->itimelimit = XFS_QM_ITIMELIMIT;
> -	defq->rtbtimelimit = XFS_QM_RTBTIMELIMIT;
> -	defq->bwarnlimit = XFS_QM_BWARNLIMIT;
> -	defq->iwarnlimit = XFS_QM_IWARNLIMIT;
> -	defq->rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
> +	defq->dfq_blk.timelimit = XFS_QM_BTIMELIMIT;
> +	defq->dfq_ino.timelimit = XFS_QM_ITIMELIMIT;
> +	defq->dfq_rtb.timelimit = XFS_QM_RTBTIMELIMIT;
> +	defq->dfq_blk.warnlimit = XFS_QM_BWARNLIMIT;
> +	defq->dfq_ino.warnlimit = XFS_QM_IWARNLIMIT;
> +	defq->dfq_rtb.warnlimit = XFS_QM_RTBWARNLIMIT;
>   
>   	/*
>   	 * We try to get the limits from the superuser's limits fields.
> @@ -608,17 +608,17 @@ xfs_qm_init_timelimits(
>   	 * more writing. If it is zero, a default is used.
>   	 */
>   	if (dqp->q_blk.timer)
> -		defq->btimelimit = dqp->q_blk.timer;
> +		defq->dfq_blk.timelimit = dqp->q_blk.timer;
>   	if (dqp->q_ino.timer)
> -		defq->itimelimit = dqp->q_ino.timer;
> +		defq->dfq_ino.timelimit = dqp->q_ino.timer;
>   	if (dqp->q_rtb.timer)
> -		defq->rtbtimelimit = dqp->q_rtb.timer;
> +		defq->dfq_rtb.timelimit = dqp->q_rtb.timer;
>   	if (dqp->q_blk.warnings)
> -		defq->bwarnlimit = dqp->q_blk.warnings;
> +		defq->dfq_blk.warnlimit = dqp->q_blk.warnings;
>   	if (dqp->q_ino.warnings)
> -		defq->iwarnlimit = dqp->q_ino.warnings;
> +		defq->dfq_ino.warnlimit = dqp->q_ino.warnings;
>   	if (dqp->q_rtb.warnings)
> -		defq->rtbwarnlimit = dqp->q_rtb.warnings;
> +		defq->dfq_rtb.warnlimit = dqp->q_rtb.warnings;
>   
>   	xfs_qm_dqdestroy(dqp);
>   }
> diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h
> index 6ed4ae942603..e2f0027f0ac1 100644
> --- a/fs/xfs/xfs_qm.h
> +++ b/fs/xfs/xfs_qm.h
> @@ -41,20 +41,18 @@ extern struct kmem_zone	*xfs_qm_dqtrxzone;
>    */
>   #define XFS_DQUOT_CLUSTER_SIZE_FSB	(xfs_filblks_t)1
>   
> +struct xfs_def_qres {
> +	xfs_qcnt_t		hardlimit;	/* default hard limit */
> +	xfs_qcnt_t		softlimit;	/* default soft limit */
> +	time64_t		timelimit;	/* limit for timers */
> +	xfs_qwarncnt_t		warnlimit;	/* limit for warnings */
> +};
> +
>   /* Defaults for each quota type: time limits, warn limits, usage limits */
>   struct xfs_def_quota {
> -	time64_t	btimelimit;	/* limit for blks timer */
> -	time64_t	itimelimit;	/* limit for inodes timer */
> -	time64_t	rtbtimelimit;	/* limit for rt blks timer */
> -	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
> -	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
> -	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
> -	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
> -	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
> -	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
> -	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
> -	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
> -	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
> +	struct xfs_def_qres	dfq_blk;
> +	struct xfs_def_qres	dfq_ino;
> +	struct xfs_def_qres	dfq_rtb;
>   };
>   
>   /*
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 1b2b70b1660f..393b88612cc8 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -502,8 +502,8 @@ xfs_qm_scall_setqlim(
>   		dqp->q_blk.softlimit = soft;
>   		xfs_dquot_set_prealloc_limits(dqp);
>   		if (id == 0) {
> -			defq->bhardlimit = hard;
> -			defq->bsoftlimit = soft;
> +			defq->dfq_blk.hardlimit = hard;
> +			defq->dfq_blk.softlimit = soft;
>   		}
>   	} else {
>   		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
> @@ -518,8 +518,8 @@ xfs_qm_scall_setqlim(
>   		dqp->q_rtb.hardlimit = hard;
>   		dqp->q_rtb.softlimit = soft;
>   		if (id == 0) {
> -			defq->rtbhardlimit = hard;
> -			defq->rtbsoftlimit = soft;
> +			defq->dfq_rtb.hardlimit = hard;
> +			defq->dfq_rtb.softlimit = soft;
>   		}
>   	} else {
>   		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
> @@ -535,8 +535,8 @@ xfs_qm_scall_setqlim(
>   		dqp->q_ino.hardlimit = hard;
>   		dqp->q_ino.softlimit = soft;
>   		if (id == 0) {
> -			defq->ihardlimit = hard;
> -			defq->isoftlimit = soft;
> +			defq->dfq_ino.hardlimit = hard;
> +			defq->dfq_ino.softlimit = soft;
>   		}
>   	} else {
>   		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
> @@ -554,11 +554,11 @@ xfs_qm_scall_setqlim(
>   
>   	if (id == 0) {
>   		if (newlim->d_fieldmask & QC_SPC_WARNS)
> -			defq->bwarnlimit = newlim->d_spc_warns;
> +			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
>   		if (newlim->d_fieldmask & QC_INO_WARNS)
> -			defq->iwarnlimit = newlim->d_ino_warns;
> +			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
>   		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -			defq->rtbwarnlimit = newlim->d_rt_spc_warns;
> +			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
>   	}
>   
>   	/*
> @@ -579,11 +579,11 @@ xfs_qm_scall_setqlim(
>   
>   	if (id == 0) {
>   		if (newlim->d_fieldmask & QC_SPC_TIMER)
> -			defq->btimelimit = newlim->d_spc_timer;
> +			defq->dfq_blk.timelimit = newlim->d_spc_timer;
>   		if (newlim->d_fieldmask & QC_INO_TIMER)
> -			defq->itimelimit = newlim->d_ino_timer;
> +			defq->dfq_ino.timelimit = newlim->d_ino_timer;
>   		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -			defq->rtbtimelimit = newlim->d_rt_spc_timer;
> +			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
>   	}
>   
>   	if (id != 0) {
> diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
> index bf809b77a316..c86a6fe263da 100644
> --- a/fs/xfs/xfs_quotaops.c
> +++ b/fs/xfs/xfs_quotaops.c
> @@ -37,12 +37,12 @@ xfs_qm_fill_state(
>   	tstate->flags |= QCI_SYSFILE;
>   	tstate->blocks = ip->i_d.di_nblocks;
>   	tstate->nextents = ip->i_df.if_nextents;
> -	tstate->spc_timelimit = (u32)defq->btimelimit;
> -	tstate->ino_timelimit = (u32)defq->itimelimit;
> -	tstate->rt_spc_timelimit = (u32)defq->rtbtimelimit;
> -	tstate->spc_warnlimit = defq->bwarnlimit;
> -	tstate->ino_warnlimit = defq->iwarnlimit;
> -	tstate->rt_spc_warnlimit = defq->rtbwarnlimit;
> +	tstate->spc_timelimit = (u32)defq->dfq_blk.timelimit;
> +	tstate->ino_timelimit = (u32)defq->dfq_ino.timelimit;
> +	tstate->rt_spc_timelimit = (u32)defq->dfq_rtb.timelimit;
> +	tstate->spc_warnlimit = defq->dfq_blk.warnlimit;
> +	tstate->ino_warnlimit = defq->dfq_ino.warnlimit;
> +	tstate->rt_spc_warnlimit = defq->dfq_rtb.warnlimit;
>   	if (tempqip)
>   		xfs_irele(ip);
>   }
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 28b59a4069a3..392e51baad6f 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -587,25 +587,25 @@ xfs_trans_dqresv(
>   	if (flags & XFS_TRANS_DQ_RES_BLKS) {
>   		hardlimit = dqp->q_blk.hardlimit;
>   		if (!hardlimit)
> -			hardlimit = defq->bhardlimit;
> +			hardlimit = defq->dfq_blk.hardlimit;
>   		softlimit = dqp->q_blk.softlimit;
>   		if (!softlimit)
> -			softlimit = defq->bsoftlimit;
> +			softlimit = defq->dfq_blk.softlimit;
>   		timer = dqp->q_blk.timer;
>   		warns = dqp->q_blk.warnings;
> -		warnlimit = defq->bwarnlimit;
> +		warnlimit = defq->dfq_blk.warnlimit;
>   		resbcountp = &dqp->q_blk.reserved;
>   	} else {
>   		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
>   		hardlimit = dqp->q_rtb.hardlimit;
>   		if (!hardlimit)
> -			hardlimit = defq->rtbhardlimit;
> +			hardlimit = defq->dfq_rtb.hardlimit;
>   		softlimit = dqp->q_rtb.softlimit;
>   		if (!softlimit)
> -			softlimit = defq->rtbsoftlimit;
> +			softlimit = defq->dfq_rtb.softlimit;
>   		timer = dqp->q_rtb.timer;
>   		warns = dqp->q_rtb.warnings;
> -		warnlimit = defq->rtbwarnlimit;
> +		warnlimit = defq->dfq_rtb.warnlimit;
>   		resbcountp = &dqp->q_rtb.reserved;
>   	}
>   
> @@ -640,13 +640,13 @@ xfs_trans_dqresv(
>   			total_count = dqp->q_ino.reserved + ninos;
>   			timer = dqp->q_ino.timer;
>   			warns = dqp->q_ino.warnings;
> -			warnlimit = defq->iwarnlimit;
> +			warnlimit = defq->dfq_ino.warnlimit;
>   			hardlimit = dqp->q_ino.hardlimit;
>   			if (!hardlimit)
> -				hardlimit = defq->ihardlimit;
> +				hardlimit = defq->dfq_ino.hardlimit;
>   			softlimit = dqp->q_ino.softlimit;
>   			if (!softlimit)
> -				softlimit = defq->isoftlimit;
> +				softlimit = defq->dfq_ino.softlimit;
>   
>   			if (hardlimit && total_count > hardlimit) {
>   				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions
  2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
  2020-07-01  8:53   ` Christoph Hellwig
  2020-07-01  8:58   ` Chandan Babu R
@ 2020-07-02  2:06   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-02  2:06 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> struct xfs_dquot already has a pointer to the xfs mount, so remove the
> redundant parameter from xfs_qm_adjust_dq*.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks fine
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_dquot.c       |    4 ++--
>   fs/xfs/xfs_dquot.h       |    6 ++----
>   fs/xfs/xfs_qm.c          |    4 ++--
>   fs/xfs/xfs_qm_syscalls.c |    2 +-
>   fs/xfs/xfs_trans_dquot.c |    4 ++--
>   5 files changed, 9 insertions(+), 11 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 6975c27145fc..35a113d1b42b 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -66,9 +66,9 @@ xfs_qm_dqdestroy(
>    */
>   void
>   xfs_qm_adjust_dqlimits(
> -	struct xfs_mount	*mp,
>   	struct xfs_dquot	*dq)
>   {
> +	struct xfs_mount	*mp = dq->q_mount;
>   	struct xfs_quotainfo	*q = mp->m_quotainfo;
>   	struct xfs_def_quota	*defq;
>   	int			prealloc = 0;
> @@ -112,9 +112,9 @@ xfs_qm_adjust_dqlimits(
>    */
>   void
>   xfs_qm_adjust_dqtimers(
> -	struct xfs_mount	*mp,
>   	struct xfs_dquot	*dq)
>   {
> +	struct xfs_mount	*mp = dq->q_mount;
>   	struct xfs_quotainfo	*qi = mp->m_quotainfo;
>   	struct xfs_def_quota	*defq;
>   
> diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
> index 62b0fc6e0133..e37b4bebc1ea 100644
> --- a/fs/xfs/xfs_dquot.h
> +++ b/fs/xfs/xfs_dquot.h
> @@ -181,10 +181,8 @@ void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
>   void		xfs_qm_dqdestroy(struct xfs_dquot *dqp);
>   int		xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
>   void		xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
> -void		xfs_qm_adjust_dqtimers(struct xfs_mount *mp,
> -						struct xfs_dquot *d);
> -void		xfs_qm_adjust_dqlimits(struct xfs_mount *mp,
> -						struct xfs_dquot *d);
> +void		xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
> +void		xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
>   xfs_dqid_t	xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type);
>   int		xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
>   					uint type, bool can_alloc,
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 28326a6264a8..30deb6cf6a7a 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1107,8 +1107,8 @@ xfs_qm_quotacheck_dqadjust(
>   	 * There are no timers for the default values set in the root dquot.
>   	 */
>   	if (dqp->q_id) {
> -		xfs_qm_adjust_dqlimits(mp, dqp);
> -		xfs_qm_adjust_dqtimers(mp, dqp);
> +		xfs_qm_adjust_dqlimits(dqp);
> +		xfs_qm_adjust_dqtimers(dqp);
>   	}
>   
>   	dqp->dq_flags |= XFS_DQ_DIRTY;
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 393b88612cc8..5423e02f9837 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -594,7 +594,7 @@ xfs_qm_scall_setqlim(
>   		 * is on or off. We don't really want to bother with iterating
>   		 * over all ondisk dquots and turning the timers on/off.
>   		 */
> -		xfs_qm_adjust_dqtimers(mp, dqp);
> +		xfs_qm_adjust_dqtimers(dqp);
>   	}
>   	dqp->dq_flags |= XFS_DQ_DIRTY;
>   	xfs_trans_log_dquot(tp, dqp);
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 392e51baad6f..2712814d696d 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -382,8 +382,8 @@ xfs_trans_apply_dquot_deltas(
>   			 * Start/reset the timer(s) if needed.
>   			 */
>   			if (dqp->q_id) {
> -				xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
> -				xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
> +				xfs_qm_adjust_dqlimits(dqp);
> +				xfs_qm_adjust_dqtimers(dqp);
>   			}
>   
>   			dqp->dq_flags |= XFS_DQ_DIRTY;
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-07-01 18:25     ` Darrick J. Wong
@ 2020-07-02  6:30       ` Christoph Hellwig
  2020-07-02 15:13         ` Darrick J. Wong
  0 siblings, 1 reply; 94+ messages in thread
From: Christoph Hellwig @ 2020-07-02  6:30 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, linux-xfs

On Wed, Jul 01, 2020 at 11:25:08AM -0700, Darrick J. Wong wrote:
> > 	/*
> > 	 * Ensure we got the type and ID we were looking for.  Everything else
> > 	 * we checked by the verifier.
> > 	 */
> > 	if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
> > 	    ddqp->d_id != dqp->q_core.d_id)
> 
> Sounds good to me.  I'll make that change.

We also don't need the mask on the on-disk flags, as it never contains
anything but the type, so this can be further simplified.

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 03/18] xfs: validate ondisk/incore dquot flags
  2020-07-02  6:30       ` Christoph Hellwig
@ 2020-07-02 15:13         ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-02 15:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs

On Thu, Jul 02, 2020 at 07:30:21AM +0100, Christoph Hellwig wrote:
> On Wed, Jul 01, 2020 at 11:25:08AM -0700, Darrick J. Wong wrote:
> > > 	/*
> > > 	 * Ensure we got the type and ID we were looking for.  Everything else
> > > 	 * we checked by the verifier.
> > > 	 */
> > > 	if ((ddqp->d_flags & XFS_DQ_ALLTYPES) != dqp->dq_flags ||
> > > 	    ddqp->d_id != dqp->q_core.d_id)
> > 
> > Sounds good to me.  I'll make that change.
> 
> We also don't need the mask on the on-disk flags, as it never contains
> anything but the type, so this can be further simplified.

d_flags will contain more than the type Real Soon Now; I was planning to
send out the y2038 feature patchset (at least for another RFC) right
after landing this series.

--D

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 14/18] xfs: refactor quota exceeded test
  2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
  2020-07-01 10:19   ` Chandan Babu R
@ 2020-07-02 18:57   ` Allison Collins
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-02 18:57 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor the open-coded test for whether or not we're over quota.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Ok, the changes look correct.  I do not have a preference on the if/else 
logic mentioned in some of the other reviews.  At first glance they both 
require a bit of a pause, but I didn't find either to be too unsightly 
to read through.  I am amicable to either solution folks prefer.

Reviewed-by: Allison Collins <allison.henderson@oracle.com>
> ---
>   fs/xfs/xfs_dquot.c |   95 ++++++++++++++++------------------------------------
>   1 file changed, 30 insertions(+), 65 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 35a113d1b42b..ef34c82c28a0 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -97,6 +97,33 @@ xfs_qm_adjust_dqlimits(
>   		xfs_dquot_set_prealloc_limits(dq);
>   }
>   
> +/*
> + * Determine if this quota counter is over either limit and set the quota
> + * timers as appropriate.
> + */
> +static inline void
> +xfs_qm_adjust_res_timer(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres)
> +{
> +	bool			over;
> +
> +#ifdef DEBUG
> +	if (res->hardlimit)
> +		ASSERT(res->softlimit <= res->hardlimit);
> +#endif
> +
> +	over = (res->softlimit && res->count > res->softlimit) ||
> +	       (res->hardlimit && res->count > res->hardlimit);
> +
> +	if (over && res->timer == 0)
> +		res->timer = ktime_get_real_seconds() + dres->timelimit;
> +	else if (!over && res->timer != 0)
> +		res->timer = 0;
> +	else if (!over && res->timer == 0)
> +		res->warnings = 0;
> +}
> +
>   /*
>    * Check the limits and timers of a dquot and start or reset timers
>    * if necessary.
> @@ -121,71 +148,9 @@ xfs_qm_adjust_dqtimers(
>   	ASSERT(dq->q_id);
>   	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));
>   
> -#ifdef DEBUG
> -	if (dq->q_blk.hardlimit)
> -		ASSERT(dq->q_blk.softlimit <= dq->q_blk.hardlimit);
> -	if (dq->q_ino.hardlimit)
> -		ASSERT(dq->q_ino.softlimit <= dq->q_ino.hardlimit);
> -	if (dq->q_rtb.hardlimit)
> -		ASSERT(dq->q_rtb.softlimit <= dq->q_rtb.hardlimit);
> -#endif
> -
> -	if (!dq->q_blk.timer) {
> -		if ((dq->q_blk.softlimit &&
> -		     (dq->q_blk.count > dq->q_blk.softlimit)) ||
> -		    (dq->q_blk.hardlimit &&
> -		     (dq->q_blk.count > dq->q_blk.hardlimit))) {
> -			dq->q_blk.timer = ktime_get_real_seconds() +
> -					defq->dfq_blk.timelimit;
> -		} else {
> -			dq->q_blk.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_blk.softlimit ||
> -		     (dq->q_blk.count <= dq->q_blk.softlimit)) &&
> -		    (!dq->q_blk.hardlimit ||
> -		    (dq->q_blk.count <= dq->q_blk.hardlimit))) {
> -			dq->q_blk.timer = 0;
> -		}
> -	}
> -
> -	if (!dq->q_ino.timer) {
> -		if ((dq->q_ino.softlimit &&
> -		     (dq->q_ino.count > dq->q_ino.softlimit)) ||
> -		    (dq->q_ino.hardlimit &&
> -		     (dq->q_ino.count > dq->q_ino.hardlimit))) {
> -			dq->q_ino.timer = ktime_get_real_seconds() +
> -					defq->dfq_ino.timelimit;
> -		} else {
> -			dq->q_ino.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_ino.softlimit ||
> -		     (dq->q_ino.count <= dq->q_ino.softlimit))  &&
> -		    (!dq->q_ino.hardlimit ||
> -		     (dq->q_ino.count <= dq->q_ino.hardlimit))) {
> -			dq->q_ino.timer = 0;
> -		}
> -	}
> -
> -	if (!dq->q_rtb.timer) {
> -		if ((dq->q_rtb.softlimit &&
> -		     (dq->q_rtb.count > dq->q_rtb.softlimit)) ||
> -		    (dq->q_rtb.hardlimit &&
> -		     (dq->q_rtb.count > dq->q_rtb.hardlimit))) {
> -			dq->q_rtb.timer = ktime_get_real_seconds() +
> -					defq->dfq_rtb.timelimit;
> -		} else {
> -			dq->q_rtb.warnings = 0;
> -		}
> -	} else {
> -		if ((!dq->q_rtb.softlimit ||
> -		     (dq->q_rtb.count <= dq->q_rtb.softlimit)) &&
> -		    (!dq->q_rtb.hardlimit ||
> -		     (dq->q_rtb.count <= dq->q_rtb.hardlimit))) {
> -			dq->q_rtb.timer = 0;
> -		}
> -	}
> +	xfs_qm_adjust_res_timer(&dq->q_blk, &defq->dfq_blk);
> +	xfs_qm_adjust_res_timer(&dq->q_ino, &defq->dfq_ino);
> +	xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->dfq_rtb);
>   }
>   
>   /*
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-01 23:50         ` Darrick J. Wong
@ 2020-07-03  0:58           ` Dave Chinner
  2020-07-03 18:01             ` Darrick J. Wong
  0 siblings, 1 reply; 94+ messages in thread
From: Dave Chinner @ 2020-07-03  0:58 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Wed, Jul 01, 2020 at 04:50:31PM -0700, Darrick J. Wong wrote:
> On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote:
> > On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> > > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > > > 
> > > > > Use the incore dq_flags to figure out the dquot type.  This is the first
> > > > > step towards removing xfs_disk_dquot from the incore dquot.
> > > > > 
> > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > > ---
> > > > >  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
> > > > >  fs/xfs/scrub/quota.c           |    4 ----
> > > > >  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
> > > > >  fs/xfs/xfs_dquot.h             |    2 ++
> > > > >  fs/xfs/xfs_dquot_item.c        |    6 ++++--
> > > > >  fs/xfs/xfs_qm.c                |    4 ++--
> > > > >  fs/xfs/xfs_qm.h                |    2 +-
> > > > >  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
> > > > >  8 files changed, 45 insertions(+), 17 deletions(-)
> > > > > 
> > > > > 
> > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > index 56d9dd787e7b..459023b0a304 100644
> > > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
> > > > >  
> > > > >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > > > >  
> > > > > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> > > > 
> > > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
> > > 
> > > Well, based on Christoph's suggestions I broke the incore dquot flags
> > > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*).  Not sure
> > > if that's really better, but at least the namespaces are separate now.
> > 
> > Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
> > doesn't actually indicate what part of the on-disk dquot it refers
> > to. We use the phrase "on-disk dquot" to refer to the entire on-disk
> > dquot, not a subset of flags in a flags field in the on-disk
> > dquot. Hence the name of this variable needs to be more specific as
> > to what it applies to in the on-disk dquot...
> 
> Sorry, I was typing too fast.  xfs_format.h now has:
> 
> #define XFS_DQFLAG_USER		0x01		/* user dquot record */
> #define XFS_DQFLAG_PROJ		0x02		/* project dquot record */
> #define XFS_DQFLAG_GROUP	0x04		/* group dquot record */
> 
> #define XFS_DQFLAG_TYPE_MASK	(XFS_DQFLAG_USER | \
> 				 XFS_DQFLAG_PROJ | \
> 				 XFS_DQFLAG_GROUP)
> 
> #define XFS_DQFLAG_ALL		(XFS_DQFLAG_TYPE_MASK)
> 
> /*
>  * This is the main portion of the on-disk representation of quota
>  * information for a user. This is the q_core of the struct xfs_dquot
>  * that is kept in kernel memory. We pad this with some more expansion
>  * room to construct the on disk structure.
>  */
> struct xfs_disk_dquot {
> 	__be16		d_magic;	/* dquot magic = XFS_DQUOT_MAGIC */
> 	__u8		d_version;	/* dquot version */
> 	__u8		d_flags;	/* XFS_DQFLAG_* */
> 
> I'm not particularly thrilled about the DQFLAG/DQ thing though.  DDFLAG?
> (Also note that the future bigtime series will add a new ondisk flag
> XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.)

/me shrugs

I don't have any good ideas, but I think that DQFLAG is a bad choice
for an on-disk flag namespace because it's way too generic. It's
more a type/feature indicator so perhaps we should rename d_flags to
d_type or d_features and use:

#define XFS_DDQTYPE_USER
#define XFS_DDQTYPE_PROJ
#define XFS_DDQTYPE_GROUP
#define XFS_DDQTYPE_BIGTIME

#define XFS_DDQTYPE_QUOTA_MASK	(XFS_DDQTYPE_USER | ...

#define XFS_DDQTYPE_ALL		(XFS_DDQTYPE_QUOTA_MASK | XFS_DDQTYPE_BIGTIME)

Or something like that...

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim
  2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
@ 2020-07-03  4:11   ` Allison Collins
  2020-07-03 12:39   ` Chandan Babu R
  2 siblings, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-03  4:11 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we can pass around quota resource and limit structures, clean
> up the open-coded field setting in xfs_qm_scall_setqlim.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, I followed it through, and I think it looks ok
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_qm_syscalls.c |  164 ++++++++++++++++++++++++++--------------------
>   1 file changed, 93 insertions(+), 71 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 5423e02f9837..5044c333af5c 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -436,6 +436,58 @@ xfs_qm_scall_quotaon(
>   #define XFS_QC_MASK \
>   	(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
>   
> +/*
> + * Adjust limits of this quota, and the defaults if passed in.  Returns true
> + * if the new limits made sense and were applied, false otherwise.
> + */
> +static inline bool
> +xfs_setqlim_limits(
> +	struct xfs_mount	*mp,
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	xfs_qcnt_t		hard,
> +	xfs_qcnt_t		soft,
> +	const char		*tag)
> +{
> +	/* The hard limit can't be less than the soft limit. */
> +	if (hard != 0 && hard < soft) {
> +		xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag,
> +				soft);
> +		return false;
> +	}
> +
> +	res->hardlimit = hard;
> +	res->softlimit = soft;
> +	if (dres) {
> +		dres->hardlimit = hard;
> +		dres->softlimit = soft;
> +	}
> +
> +	return true;
> +}
> +
> +static inline void
> +xfs_setqlim_warns(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	int			warns)
> +{
> +	res->warnings = warns;
> +	if (dres)
> +		dres->warnlimit = warns;
> +}
> +
> +static inline void
> +xfs_setqlim_timer(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	s64			timer)
> +{
> +	res->timer = timer;
> +	if (dres)
> +		dres->timelimit = timer;
> +}
> +
>   /*
>    * Adjust quota limits, and start/stop timers accordingly.
>    */
> @@ -450,6 +502,8 @@ xfs_qm_scall_setqlim(
>   	struct xfs_dquot	*dqp;
>   	struct xfs_trans	*tp;
>   	struct xfs_def_quota	*defq;
> +	struct xfs_dquot_res	*res;
> +	struct xfs_def_qres	*dres;
>   	int			error;
>   	xfs_qcnt_t		hard, soft;
>   
> @@ -489,102 +543,70 @@ xfs_qm_scall_setqlim(
>   	xfs_trans_dqjoin(tp, dqp);
>   
>   	/*
> +	 * Update quota limits, warnings, and timers, and the defaults
> +	 * if we're touching id == 0.
> +	 *
>   	 * Make sure that hardlimits are >= soft limits before changing.
> +	 *
> +	 * Update warnings counter(s) if requested.
> +	 *
> +	 * Timelimits for the super user set the relative time the other users
> +	 * can be over quota for this file system. If it is zero a default is
> +	 * used.  Ditto for the default soft and hard limit values (already
> +	 * done, above), and for warnings.
> +	 *
> +	 * For other IDs, userspace can bump out the grace period if over
> +	 * the soft limit.
>   	 */
> +
> +	/* Blocks on the data device. */
>   	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
>   			dqp->q_blk.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
>   			dqp->q_blk.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_blk.hardlimit = hard;
> -		dqp->q_blk.softlimit = soft;
> +	res = &dqp->q_blk;
> +	dres = id == 0 ? &defq->dfq_blk : NULL;
> +
> +	if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk"))
>   		xfs_dquot_set_prealloc_limits(dqp);
> -		if (id == 0) {
> -			defq->dfq_blk.hardlimit = hard;
> -			defq->dfq_blk.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
> -	}
> +	if (newlim->d_fieldmask & QC_SPC_WARNS)
> +		xfs_setqlim_warns(res, dres, newlim->d_spc_warns);
> +	if (newlim->d_fieldmask & QC_SPC_TIMER)
> +		xfs_setqlim_timer(res, dres, newlim->d_spc_timer);
> +
> +	/* Blocks on the realtime device. */
>   	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
>   			dqp->q_rtb.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
>   		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
>   			dqp->q_rtb.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_rtb.hardlimit = hard;
> -		dqp->q_rtb.softlimit = soft;
> -		if (id == 0) {
> -			defq->dfq_rtb.hardlimit = hard;
> -			defq->dfq_rtb.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
> -	}
> +	res = &dqp->q_rtb;
> +	dres = id == 0 ? &defq->dfq_rtb : NULL;
>   
> +	xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb");
> +	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> +		xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns);
> +	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> +		xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer);
> +
> +	/* Inodes */
>   	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
>   		(xfs_qcnt_t) newlim->d_ino_hardlimit :
>   			dqp->q_ino.hardlimit;
>   	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
>   		(xfs_qcnt_t) newlim->d_ino_softlimit :
>   			dqp->q_ino.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_ino.hardlimit = hard;
> -		dqp->q_ino.softlimit = soft;
> -		if (id == 0) {
> -			defq->dfq_ino.hardlimit = hard;
> -			defq->dfq_ino.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
> -	}
> +	res = &dqp->q_ino;
> +	dres = id == 0 ? &defq->dfq_ino : NULL;
>   
> -	/*
> -	 * Update warnings counter(s) if requested
> -	 */
> -	if (newlim->d_fieldmask & QC_SPC_WARNS)
> -		dqp->q_blk.warnings = newlim->d_spc_warns;
> +	xfs_setqlim_limits(mp, res, dres, hard, soft, "ino");
>   	if (newlim->d_fieldmask & QC_INO_WARNS)
> -		dqp->q_ino.warnings = newlim->d_ino_warns;
> -	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
> -
> -	if (id == 0) {
> -		if (newlim->d_fieldmask & QC_SPC_WARNS)
> -			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
> -		if (newlim->d_fieldmask & QC_INO_WARNS)
> -			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
> -		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
> -	}
> -
> -	/*
> -	 * Timelimits for the super user set the relative time the other users
> -	 * can be over quota for this file system. If it is zero a default is
> -	 * used.  Ditto for the default soft and hard limit values (already
> -	 * done, above), and for warnings.
> -	 *
> -	 * For other IDs, userspace can bump out the grace period if over
> -	 * the soft limit.
> -	 */
> -	if (newlim->d_fieldmask & QC_SPC_TIMER)
> -		dqp->q_blk.timer = newlim->d_spc_timer;
> +		xfs_setqlim_warns(res, dres, newlim->d_ino_warns);
>   	if (newlim->d_fieldmask & QC_INO_TIMER)
> -		dqp->q_ino.timer = newlim->d_ino_timer;
> -	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
> -
> -	if (id == 0) {
> -		if (newlim->d_fieldmask & QC_SPC_TIMER)
> -			defq->dfq_blk.timelimit = newlim->d_spc_timer;
> -		if (newlim->d_fieldmask & QC_INO_TIMER)
> -			defq->dfq_ino.timelimit = newlim->d_ino_timer;
> -		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
> -	}
> +		xfs_setqlim_timer(res, dres, newlim->d_ino_timer);
>   
>   	if (id != 0) {
>   		/*
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 16/18] xfs: refactor xfs_trans_dqresv
  2020-06-30 15:43 ` [PATCH 16/18] xfs: refactor xfs_trans_dqresv Darrick J. Wong
@ 2020-07-03  4:11   ` Allison Collins
  2020-07-03 13:00   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-03  4:11 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've refactored the resource usage and limits into
> per-resource structures, we can refactor some of the open-coded
> reservation limit checking in xfs_trans_dqresv.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Ok, I followed it through, and I think it makes sense
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_trans_dquot.c |  153 +++++++++++++++++++++++-----------------------
>   1 file changed, 78 insertions(+), 75 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 2712814d696d..30a011dc9828 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -554,6 +554,58 @@ xfs_quota_warn(
>   			   mp->m_super->s_dev, type);
>   }
>   
> +/*
> + * Decide if we can make an additional reservation against a quota resource.
> + * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
> + *
> + * Note that we assume that the numeric difference between the inode and block
> + * warning codes will always be 3 since it's userspace ABI now, and will never
> + * decrease the quota reservation, so the *BELOW messages are irrelevant.
> + */
> +static inline int
> +xfs_dqresv_check(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	int64_t			delta,
> +	bool			*fatal)
> +{
> +	xfs_qcnt_t		hardlimit = res->hardlimit;
> +	xfs_qcnt_t		softlimit = res->softlimit;
> +	xfs_qcnt_t		total_count = res->reserved + delta;
> +
> +	BUILD_BUG_ON(QUOTA_NL_BHARDWARN     != QUOTA_NL_IHARDWARN + 3);
> +	BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
> +	BUILD_BUG_ON(QUOTA_NL_BSOFTWARN     != QUOTA_NL_ISOFTWARN + 3);
> +
> +	*fatal = false;
> +	if (delta <= 0)
> +		return QUOTA_NL_NOWARN;
> +
> +	if (!hardlimit)
> +		hardlimit = dres->hardlimit;
> +	if (!softlimit)
> +		softlimit = dres->softlimit;
> +
> +	if (hardlimit && total_count > hardlimit) {
> +		*fatal = true;
> +		return QUOTA_NL_IHARDWARN;
> +	}
> +
> +	if (softlimit && total_count > softlimit) {
> +		time64_t	now = ktime_get_real_seconds();
> +
> +		if ((res->timer != 0 && now > res->timer) ||
> +		    (res->warnings != 0 && res->warnings >= dres->warnlimit)) {
> +			*fatal = true;
> +			return QUOTA_NL_ISOFTLONGWARN;
> +		}
> +
> +		return QUOTA_NL_ISOFTWARN;
> +	}
> +
> +	return QUOTA_NL_NOWARN;
> +}
> +
>   /*
>    * This reserves disk blocks and inodes against a dquot.
>    * Flags indicate if the dquot is to be locked here and also
> @@ -569,99 +621,51 @@ xfs_trans_dqresv(
>   	long			ninos,
>   	uint			flags)
>   {
> -	xfs_qcnt_t		hardlimit;
> -	xfs_qcnt_t		softlimit;
> -	time64_t		timer;
> -	xfs_qwarncnt_t		warns;
> -	xfs_qwarncnt_t		warnlimit;
> -	xfs_qcnt_t		total_count;
> -	xfs_qcnt_t		*resbcountp;
>   	struct xfs_quotainfo	*q = mp->m_quotainfo;
>   	struct xfs_def_quota	*defq;
> -
> +	struct xfs_dquot_res	*blkres;
> +	struct xfs_def_qres	*def_blkres;
>   
>   	xfs_dqlock(dqp);
>   
>   	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
>   
>   	if (flags & XFS_TRANS_DQ_RES_BLKS) {
> -		hardlimit = dqp->q_blk.hardlimit;
> -		if (!hardlimit)
> -			hardlimit = defq->dfq_blk.hardlimit;
> -		softlimit = dqp->q_blk.softlimit;
> -		if (!softlimit)
> -			softlimit = defq->dfq_blk.softlimit;
> -		timer = dqp->q_blk.timer;
> -		warns = dqp->q_blk.warnings;
> -		warnlimit = defq->dfq_blk.warnlimit;
> -		resbcountp = &dqp->q_blk.reserved;
> +		blkres = &dqp->q_blk;
> +		def_blkres = &defq->dfq_blk;
>   	} else {
> -		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
> -		hardlimit = dqp->q_rtb.hardlimit;
> -		if (!hardlimit)
> -			hardlimit = defq->dfq_rtb.hardlimit;
> -		softlimit = dqp->q_rtb.softlimit;
> -		if (!softlimit)
> -			softlimit = defq->dfq_rtb.softlimit;
> -		timer = dqp->q_rtb.timer;
> -		warns = dqp->q_rtb.warnings;
> -		warnlimit = defq->dfq_rtb.warnlimit;
> -		resbcountp = &dqp->q_rtb.reserved;
> +		blkres = &dqp->q_rtb;
> +		def_blkres = &defq->dfq_rtb;
>   	}
>   
>   	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
>   	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
>   	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
>   	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
> -		if (nblks > 0) {
> +		int		quota_nl;
> +		bool		fatal;
> +
> +		/*
> +		 * dquot is locked already. See if we'd go over the hardlimit
> +		 * or exceed the timelimit if we'd reserve resources.
> +		 */
> +		quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal);
> +		if (quota_nl != QUOTA_NL_NOWARN) {
>   			/*
> -			 * dquot is locked already. See if we'd go over the
> -			 * hardlimit or exceed the timelimit if we allocate
> -			 * nblks.
> +			 * Quota block warning codes are 3 more than the inode
> +			 * codes, which we check above.
>   			 */
> -			total_count = *resbcountp + nblks;
> -			if (hardlimit && total_count > hardlimit) {
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
> +			xfs_quota_warn(mp, dqp, quota_nl + 3);
> +			if (fatal)
>   				goto error_return;
> -			}
> -			if (softlimit && total_count > softlimit) {
> -				if ((timer != 0 &&
> -				     ktime_get_real_seconds() > timer) ||
> -				    (warns != 0 && warns >= warnlimit)) {
> -					xfs_quota_warn(mp, dqp,
> -						       QUOTA_NL_BSOFTLONGWARN);
> -					goto error_return;
> -				}
> -
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
> -			}
>   		}
> -		if (ninos > 0) {
> -			total_count = dqp->q_ino.reserved + ninos;
> -			timer = dqp->q_ino.timer;
> -			warns = dqp->q_ino.warnings;
> -			warnlimit = defq->dfq_ino.warnlimit;
> -			hardlimit = dqp->q_ino.hardlimit;
> -			if (!hardlimit)
> -				hardlimit = defq->dfq_ino.hardlimit;
> -			softlimit = dqp->q_ino.softlimit;
> -			if (!softlimit)
> -				softlimit = defq->dfq_ino.softlimit;
>   
> -			if (hardlimit && total_count > hardlimit) {
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
> +		quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos,
> +				&fatal);
> +		if (quota_nl != QUOTA_NL_NOWARN) {
> +			xfs_quota_warn(mp, dqp, quota_nl);
> +			if (fatal)
>   				goto error_return;
> -			}
> -			if (softlimit && total_count > softlimit) {
> -				if  ((timer != 0 &&
> -				      ktime_get_real_seconds() > timer) ||
> -				     (warns != 0 && warns >= warnlimit)) {
> -					xfs_quota_warn(mp, dqp,
> -						       QUOTA_NL_ISOFTLONGWARN);
> -					goto error_return;
> -				}
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
> -			}
>   		}
>   	}
>   
> @@ -669,9 +673,8 @@ xfs_trans_dqresv(
>   	 * Change the reservation, but not the actual usage.
>   	 * Note that q_blk.reserved = q_blk.count + resv
>   	 */
> -	(*resbcountp) += (xfs_qcnt_t)nblks;
> -	if (ninos != 0)
> -		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
> +	blkres->reserved += (xfs_qcnt_t)nblks;
> +	dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
>   
>   	/*
>   	 * note the reservation amt in the trans struct too,
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim
  2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
  2020-07-01  8:56   ` Christoph Hellwig
  2020-07-03  4:11   ` Allison Collins
@ 2020-07-03 12:39   ` Chandan Babu R
  2 siblings, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-03 12:39 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:26 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we can pass around quota resource and limit structures, clean
> up the open-coded field setting in xfs_qm_scall_setqlim.
>

The changes are logically correct.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_qm_syscalls.c |  164 ++++++++++++++++++++++++++--------------------
>  1 file changed, 93 insertions(+), 71 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index 5423e02f9837..5044c333af5c 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -436,6 +436,58 @@ xfs_qm_scall_quotaon(
>  #define XFS_QC_MASK \
>  	(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
>  
> +/*
> + * Adjust limits of this quota, and the defaults if passed in.  Returns true
> + * if the new limits made sense and were applied, false otherwise.
> + */
> +static inline bool
> +xfs_setqlim_limits(
> +	struct xfs_mount	*mp,
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	xfs_qcnt_t		hard,
> +	xfs_qcnt_t		soft,
> +	const char		*tag)
> +{
> +	/* The hard limit can't be less than the soft limit. */
> +	if (hard != 0 && hard < soft) {
> +		xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag,
> +				soft);
> +		return false;
> +	}
> +
> +	res->hardlimit = hard;
> +	res->softlimit = soft;
> +	if (dres) {
> +		dres->hardlimit = hard;
> +		dres->softlimit = soft;
> +	}
> +
> +	return true;
> +}
> +
> +static inline void
> +xfs_setqlim_warns(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	int			warns)
> +{
> +	res->warnings = warns;
> +	if (dres)
> +		dres->warnlimit = warns;
> +}
> +
> +static inline void
> +xfs_setqlim_timer(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	s64			timer)
> +{
> +	res->timer = timer;
> +	if (dres)
> +		dres->timelimit = timer;
> +}
> +
>  /*
>   * Adjust quota limits, and start/stop timers accordingly.
>   */
> @@ -450,6 +502,8 @@ xfs_qm_scall_setqlim(
>  	struct xfs_dquot	*dqp;
>  	struct xfs_trans	*tp;
>  	struct xfs_def_quota	*defq;
> +	struct xfs_dquot_res	*res;
> +	struct xfs_def_qres	*dres;
>  	int			error;
>  	xfs_qcnt_t		hard, soft;
>  
> @@ -489,102 +543,70 @@ xfs_qm_scall_setqlim(
>  	xfs_trans_dqjoin(tp, dqp);
>  
>  	/*
> +	 * Update quota limits, warnings, and timers, and the defaults
> +	 * if we're touching id == 0.
> +	 *
>  	 * Make sure that hardlimits are >= soft limits before changing.
> +	 *
> +	 * Update warnings counter(s) if requested.
> +	 *
> +	 * Timelimits for the super user set the relative time the other users
> +	 * can be over quota for this file system. If it is zero a default is
> +	 * used.  Ditto for the default soft and hard limit values (already
> +	 * done, above), and for warnings.
> +	 *
> +	 * For other IDs, userspace can bump out the grace period if over
> +	 * the soft limit.
>  	 */
> +
> +	/* Blocks on the data device. */
>  	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
>  			dqp->q_blk.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
>  			dqp->q_blk.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_blk.hardlimit = hard;
> -		dqp->q_blk.softlimit = soft;
> +	res = &dqp->q_blk;
> +	dres = id == 0 ? &defq->dfq_blk : NULL;
> +
> +	if (xfs_setqlim_limits(mp, res, dres, hard, soft, "blk"))
>  		xfs_dquot_set_prealloc_limits(dqp);
> -		if (id == 0) {
> -			defq->dfq_blk.hardlimit = hard;
> -			defq->dfq_blk.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
> -	}
> +	if (newlim->d_fieldmask & QC_SPC_WARNS)
> +		xfs_setqlim_warns(res, dres, newlim->d_spc_warns);
> +	if (newlim->d_fieldmask & QC_SPC_TIMER)
> +		xfs_setqlim_timer(res, dres, newlim->d_spc_timer);
> +
> +	/* Blocks on the realtime device. */
>  	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
>  			dqp->q_rtb.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
>  		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
>  			dqp->q_rtb.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_rtb.hardlimit = hard;
> -		dqp->q_rtb.softlimit = soft;
> -		if (id == 0) {
> -			defq->dfq_rtb.hardlimit = hard;
> -			defq->dfq_rtb.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
> -	}
> +	res = &dqp->q_rtb;
> +	dres = id == 0 ? &defq->dfq_rtb : NULL;
>  
> +	xfs_setqlim_limits(mp, res, dres, hard, soft, "rtb");
> +	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> +		xfs_setqlim_warns(res, dres, newlim->d_rt_spc_warns);
> +	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> +		xfs_setqlim_timer(res, dres, newlim->d_rt_spc_timer);
> +
> +	/* Inodes */
>  	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
>  		(xfs_qcnt_t) newlim->d_ino_hardlimit :
>  			dqp->q_ino.hardlimit;
>  	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
>  		(xfs_qcnt_t) newlim->d_ino_softlimit :
>  			dqp->q_ino.softlimit;
> -	if (hard == 0 || hard >= soft) {
> -		dqp->q_ino.hardlimit = hard;
> -		dqp->q_ino.softlimit = soft;
> -		if (id == 0) {
> -			defq->dfq_ino.hardlimit = hard;
> -			defq->dfq_ino.softlimit = soft;
> -		}
> -	} else {
> -		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
> -	}
> +	res = &dqp->q_ino;
> +	dres = id == 0 ? &defq->dfq_ino : NULL;
>  
> -	/*
> -	 * Update warnings counter(s) if requested
> -	 */
> -	if (newlim->d_fieldmask & QC_SPC_WARNS)
> -		dqp->q_blk.warnings = newlim->d_spc_warns;
> +	xfs_setqlim_limits(mp, res, dres, hard, soft, "ino");
>  	if (newlim->d_fieldmask & QC_INO_WARNS)
> -		dqp->q_ino.warnings = newlim->d_ino_warns;
> -	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -		dqp->q_rtb.warnings = newlim->d_rt_spc_warns;
> -
> -	if (id == 0) {
> -		if (newlim->d_fieldmask & QC_SPC_WARNS)
> -			defq->dfq_blk.warnlimit = newlim->d_spc_warns;
> -		if (newlim->d_fieldmask & QC_INO_WARNS)
> -			defq->dfq_ino.warnlimit = newlim->d_ino_warns;
> -		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
> -			defq->dfq_rtb.warnlimit = newlim->d_rt_spc_warns;
> -	}
> -
> -	/*
> -	 * Timelimits for the super user set the relative time the other users
> -	 * can be over quota for this file system. If it is zero a default is
> -	 * used.  Ditto for the default soft and hard limit values (already
> -	 * done, above), and for warnings.
> -	 *
> -	 * For other IDs, userspace can bump out the grace period if over
> -	 * the soft limit.
> -	 */
> -	if (newlim->d_fieldmask & QC_SPC_TIMER)
> -		dqp->q_blk.timer = newlim->d_spc_timer;
> +		xfs_setqlim_warns(res, dres, newlim->d_ino_warns);
>  	if (newlim->d_fieldmask & QC_INO_TIMER)
> -		dqp->q_ino.timer = newlim->d_ino_timer;
> -	if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -		dqp->q_rtb.timer = newlim->d_rt_spc_timer;
> -
> -	if (id == 0) {
> -		if (newlim->d_fieldmask & QC_SPC_TIMER)
> -			defq->dfq_blk.timelimit = newlim->d_spc_timer;
> -		if (newlim->d_fieldmask & QC_INO_TIMER)
> -			defq->dfq_ino.timelimit = newlim->d_ino_timer;
> -		if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
> -			defq->dfq_rtb.timelimit = newlim->d_rt_spc_timer;
> -	}
> +		xfs_setqlim_timer(res, dres, newlim->d_ino_timer);
>  
>  	if (id != 0) {
>  		/*
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 16/18] xfs: refactor xfs_trans_dqresv
  2020-06-30 15:43 ` [PATCH 16/18] xfs: refactor xfs_trans_dqresv Darrick J. Wong
  2020-07-03  4:11   ` Allison Collins
@ 2020-07-03 13:00   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-03 13:00 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:32 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we've refactored the resource usage and limits into
> per-resource structures, we can refactor some of the open-coded
> reservation limit checking in xfs_trans_dqresv.
>

The changes are consistent with the previous functionality.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_trans_dquot.c |  153 +++++++++++++++++++++++-----------------------
>  1 file changed, 78 insertions(+), 75 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 2712814d696d..30a011dc9828 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -554,6 +554,58 @@ xfs_quota_warn(
>  			   mp->m_super->s_dev, type);
>  }
>  
> +/*
> + * Decide if we can make an additional reservation against a quota resource.
> + * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
> + *
> + * Note that we assume that the numeric difference between the inode and block
> + * warning codes will always be 3 since it's userspace ABI now, and will never
> + * decrease the quota reservation, so the *BELOW messages are irrelevant.
> + */
> +static inline int
> +xfs_dqresv_check(
> +	struct xfs_dquot_res	*res,
> +	struct xfs_def_qres	*dres,
> +	int64_t			delta,
> +	bool			*fatal)
> +{
> +	xfs_qcnt_t		hardlimit = res->hardlimit;
> +	xfs_qcnt_t		softlimit = res->softlimit;
> +	xfs_qcnt_t		total_count = res->reserved + delta;
> +
> +	BUILD_BUG_ON(QUOTA_NL_BHARDWARN     != QUOTA_NL_IHARDWARN + 3);
> +	BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
> +	BUILD_BUG_ON(QUOTA_NL_BSOFTWARN     != QUOTA_NL_ISOFTWARN + 3);
> +
> +	*fatal = false;
> +	if (delta <= 0)
> +		return QUOTA_NL_NOWARN;
> +
> +	if (!hardlimit)
> +		hardlimit = dres->hardlimit;
> +	if (!softlimit)
> +		softlimit = dres->softlimit;
> +
> +	if (hardlimit && total_count > hardlimit) {
> +		*fatal = true;
> +		return QUOTA_NL_IHARDWARN;
> +	}
> +
> +	if (softlimit && total_count > softlimit) {
> +		time64_t	now = ktime_get_real_seconds();
> +
> +		if ((res->timer != 0 && now > res->timer) ||
> +		    (res->warnings != 0 && res->warnings >= dres->warnlimit)) {
> +			*fatal = true;
> +			return QUOTA_NL_ISOFTLONGWARN;
> +		}
> +
> +		return QUOTA_NL_ISOFTWARN;
> +	}
> +
> +	return QUOTA_NL_NOWARN;
> +}
> +
>  /*
>   * This reserves disk blocks and inodes against a dquot.
>   * Flags indicate if the dquot is to be locked here and also
> @@ -569,99 +621,51 @@ xfs_trans_dqresv(
>  	long			ninos,
>  	uint			flags)
>  {
> -	xfs_qcnt_t		hardlimit;
> -	xfs_qcnt_t		softlimit;
> -	time64_t		timer;
> -	xfs_qwarncnt_t		warns;
> -	xfs_qwarncnt_t		warnlimit;
> -	xfs_qcnt_t		total_count;
> -	xfs_qcnt_t		*resbcountp;
>  	struct xfs_quotainfo	*q = mp->m_quotainfo;
>  	struct xfs_def_quota	*defq;
> -
> +	struct xfs_dquot_res	*blkres;
> +	struct xfs_def_qres	*def_blkres;
>  
>  	xfs_dqlock(dqp);
>  
>  	defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
>  
>  	if (flags & XFS_TRANS_DQ_RES_BLKS) {
> -		hardlimit = dqp->q_blk.hardlimit;
> -		if (!hardlimit)
> -			hardlimit = defq->dfq_blk.hardlimit;
> -		softlimit = dqp->q_blk.softlimit;
> -		if (!softlimit)
> -			softlimit = defq->dfq_blk.softlimit;
> -		timer = dqp->q_blk.timer;
> -		warns = dqp->q_blk.warnings;
> -		warnlimit = defq->dfq_blk.warnlimit;
> -		resbcountp = &dqp->q_blk.reserved;
> +		blkres = &dqp->q_blk;
> +		def_blkres = &defq->dfq_blk;
>  	} else {
> -		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
> -		hardlimit = dqp->q_rtb.hardlimit;
> -		if (!hardlimit)
> -			hardlimit = defq->dfq_rtb.hardlimit;
> -		softlimit = dqp->q_rtb.softlimit;
> -		if (!softlimit)
> -			softlimit = defq->dfq_rtb.softlimit;
> -		timer = dqp->q_rtb.timer;
> -		warns = dqp->q_rtb.warnings;
> -		warnlimit = defq->dfq_rtb.warnlimit;
> -		resbcountp = &dqp->q_rtb.reserved;
> +		blkres = &dqp->q_rtb;
> +		def_blkres = &defq->dfq_rtb;
>  	}
>  
>  	if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
>  	    ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
>  	     (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
>  	     (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
> -		if (nblks > 0) {
> +		int		quota_nl;
> +		bool		fatal;
> +
> +		/*
> +		 * dquot is locked already. See if we'd go over the hardlimit
> +		 * or exceed the timelimit if we'd reserve resources.
> +		 */
> +		quota_nl = xfs_dqresv_check(blkres, def_blkres, nblks, &fatal);
> +		if (quota_nl != QUOTA_NL_NOWARN) {
>  			/*
> -			 * dquot is locked already. See if we'd go over the
> -			 * hardlimit or exceed the timelimit if we allocate
> -			 * nblks.
> +			 * Quota block warning codes are 3 more than the inode
> +			 * codes, which we check above.
>  			 */
> -			total_count = *resbcountp + nblks;
> -			if (hardlimit && total_count > hardlimit) {
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
> +			xfs_quota_warn(mp, dqp, quota_nl + 3);
> +			if (fatal)
>  				goto error_return;
> -			}
> -			if (softlimit && total_count > softlimit) {
> -				if ((timer != 0 &&
> -				     ktime_get_real_seconds() > timer) ||
> -				    (warns != 0 && warns >= warnlimit)) {
> -					xfs_quota_warn(mp, dqp,
> -						       QUOTA_NL_BSOFTLONGWARN);
> -					goto error_return;
> -				}
> -
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
> -			}
>  		}
> -		if (ninos > 0) {
> -			total_count = dqp->q_ino.reserved + ninos;
> -			timer = dqp->q_ino.timer;
> -			warns = dqp->q_ino.warnings;
> -			warnlimit = defq->dfq_ino.warnlimit;
> -			hardlimit = dqp->q_ino.hardlimit;
> -			if (!hardlimit)
> -				hardlimit = defq->dfq_ino.hardlimit;
> -			softlimit = dqp->q_ino.softlimit;
> -			if (!softlimit)
> -				softlimit = defq->dfq_ino.softlimit;
>  
> -			if (hardlimit && total_count > hardlimit) {
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
> +		quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->dfq_ino, ninos,
> +				&fatal);
> +		if (quota_nl != QUOTA_NL_NOWARN) {
> +			xfs_quota_warn(mp, dqp, quota_nl);
> +			if (fatal)
>  				goto error_return;
> -			}
> -			if (softlimit && total_count > softlimit) {
> -				if  ((timer != 0 &&
> -				      ktime_get_real_seconds() > timer) ||
> -				     (warns != 0 && warns >= warnlimit)) {
> -					xfs_quota_warn(mp, dqp,
> -						       QUOTA_NL_ISOFTLONGWARN);
> -					goto error_return;
> -				}
> -				xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
> -			}
>  		}
>  	}
>  
> @@ -669,9 +673,8 @@ xfs_trans_dqresv(
>  	 * Change the reservation, but not the actual usage.
>  	 * Note that q_blk.reserved = q_blk.count + resv
>  	 */
> -	(*resbcountp) += (xfs_qcnt_t)nblks;
> -	if (ninos != 0)
> -		dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
> +	blkres->reserved += (xfs_qcnt_t)nblks;
> +	dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
>  
>  	/*
>  	 * note the reservation amt in the trans struct too,
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code
  2020-07-03  0:58           ` Dave Chinner
@ 2020-07-03 18:01             ` Darrick J. Wong
  0 siblings, 0 replies; 94+ messages in thread
From: Darrick J. Wong @ 2020-07-03 18:01 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Fri, Jul 03, 2020 at 10:58:50AM +1000, Dave Chinner wrote:
> On Wed, Jul 01, 2020 at 04:50:31PM -0700, Darrick J. Wong wrote:
> > On Thu, Jul 02, 2020 at 09:44:35AM +1000, Dave Chinner wrote:
> > > On Wed, Jul 01, 2020 at 04:19:10PM -0700, Darrick J. Wong wrote:
> > > > On Thu, Jul 02, 2020 at 08:50:53AM +1000, Dave Chinner wrote:
> > > > > On Tue, Jun 30, 2020 at 08:42:16AM -0700, Darrick J. Wong wrote:
> > > > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > > > > 
> > > > > > Use the incore dq_flags to figure out the dquot type.  This is the first
> > > > > > step towards removing xfs_disk_dquot from the incore dquot.
> > > > > > 
> > > > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > > > ---
> > > > > >  fs/xfs/libxfs/xfs_quota_defs.h |    2 ++
> > > > > >  fs/xfs/scrub/quota.c           |    4 ----
> > > > > >  fs/xfs/xfs_dquot.c             |   33 +++++++++++++++++++++++++++++++--
> > > > > >  fs/xfs/xfs_dquot.h             |    2 ++
> > > > > >  fs/xfs/xfs_dquot_item.c        |    6 ++++--
> > > > > >  fs/xfs/xfs_qm.c                |    4 ++--
> > > > > >  fs/xfs/xfs_qm.h                |    2 +-
> > > > > >  fs/xfs/xfs_qm_syscalls.c       |    9 +++------
> > > > > >  8 files changed, 45 insertions(+), 17 deletions(-)
> > > > > > 
> > > > > > 
> > > > > > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > > index 56d9dd787e7b..459023b0a304 100644
> > > > > > --- a/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > > +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> > > > > > @@ -29,6 +29,8 @@ typedef uint16_t	xfs_qwarncnt_t;
> > > > > >  
> > > > > >  #define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
> > > > > >  
> > > > > > +#define XFS_DQ_ONDISK		(XFS_DQ_ALLTYPES)
> > > > > 
> > > > > That's used as an on-disk flags mask. Perhaps XFS_DQF_ONDISK_MASK?
> > > > 
> > > > Well, based on Christoph's suggestions I broke the incore dquot flags
> > > > (XFS_DQ_*) apart from the ondisk dquot flags (XFS_DQFLAG_*).  Not sure
> > > > if that's really better, but at least the namespaces are separate now.
> > > 
> > > Sure, but the point I was trying to make is that "XFS_DQ_ONDISK"
> > > doesn't actually indicate what part of the on-disk dquot it refers
> > > to. We use the phrase "on-disk dquot" to refer to the entire on-disk
> > > dquot, not a subset of flags in a flags field in the on-disk
> > > dquot. Hence the name of this variable needs to be more specific as
> > > to what it applies to in the on-disk dquot...
> > 
> > Sorry, I was typing too fast.  xfs_format.h now has:
> > 
> > #define XFS_DQFLAG_USER		0x01		/* user dquot record */
> > #define XFS_DQFLAG_PROJ		0x02		/* project dquot record */
> > #define XFS_DQFLAG_GROUP	0x04		/* group dquot record */
> > 
> > #define XFS_DQFLAG_TYPE_MASK	(XFS_DQFLAG_USER | \
> > 				 XFS_DQFLAG_PROJ | \
> > 				 XFS_DQFLAG_GROUP)
> > 
> > #define XFS_DQFLAG_ALL		(XFS_DQFLAG_TYPE_MASK)
> > 
> > /*
> >  * This is the main portion of the on-disk representation of quota
> >  * information for a user. This is the q_core of the struct xfs_dquot
> >  * that is kept in kernel memory. We pad this with some more expansion
> >  * room to construct the on disk structure.
> >  */
> > struct xfs_disk_dquot {
> > 	__be16		d_magic;	/* dquot magic = XFS_DQUOT_MAGIC */
> > 	__u8		d_version;	/* dquot version */
> > 	__u8		d_flags;	/* XFS_DQFLAG_* */
> > 
> > I'm not particularly thrilled about the DQFLAG/DQ thing though.  DDFLAG?
> > (Also note that the future bigtime series will add a new ondisk flag
> > XFS_DQFLAG_BIGTIME, which ofc will get added to XFS_DQFLAG_ALL.)
> 
> /me shrugs
> 
> I don't have any good ideas, but I think that DQFLAG is a bad choice
> for an on-disk flag namespace because it's way too generic. It's
> more a type/feature indicator so perhaps we should rename d_flags to
> d_type or d_features and use:
> 
> #define XFS_DDQTYPE_USER
> #define XFS_DDQTYPE_PROJ
> #define XFS_DDQTYPE_GROUP
> #define XFS_DDQTYPE_BIGTIME
> 
> #define XFS_DDQTYPE_QUOTA_MASK	(XFS_DDQTYPE_USER | ...
> 
> #define XFS_DDQTYPE_ALL		(XFS_DDQTYPE_QUOTA_MASK | XFS_DDQTYPE_BIGTIME)
> 
> Or something like that...

I prefer d_features/DDQFEAT over d_type/DDQTYPE because I don't want
people to mix up "ondisk dquot type (user/group/proj/bigtime)" with
"quota type (user/group/proj)".

--D

> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas
  2020-06-30 15:43 ` [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas Darrick J. Wong
@ 2020-07-04 20:41   ` Allison Collins
  2020-07-06 13:40   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-04 20:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Hoist the code that adjusts the incore quota reservation count
> adjustments into a separate function, both to reduce the level of
> indentation and also to reduce the amount of open-coded logic.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Ok, it's a bit of a hoist and a simplification, but I think it's a good 
clean up.

Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_trans_dquot.c |  103 +++++++++++++++++++++-------------------------
>   1 file changed, 46 insertions(+), 57 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 30a011dc9828..701923ea6c04 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin(
>   	}
>   }
>   
> +/* Apply dqtrx changes to the quota reservation counters. */
> +static inline void
> +xfs_apply_quota_reservation_deltas(
> +	struct xfs_dquot_res	*res,
> +	uint64_t		reserved,
> +	int64_t			res_used,
> +	int64_t			count_delta)
> +{
> +	if (reserved != 0) {
> +		/*
> +		 * Subtle math here: If reserved > res_used (the normal case),
> +		 * we're simply subtracting the unused transaction quota
> +		 * reservation from the dquot reservation.
> +		 *
> +		 * If, however, res_used > reserved, then we have allocated
> +		 * more quota blocks than were reserved for the transaction.
> +		 * We must add that excess to the dquot reservation since it
> +		 * tracks (usage + resv) and by definition we didn't reserve
> +		 * that excess.
> +		 */
> +		res->reserved -= abs(reserved - res_used);
> +	} else if (count_delta != 0) {
> +		/*
> +		 * These blks were never reserved, either inside a transaction
> +		 * or outside one (in a delayed allocation). Also, this isn't
> +		 * always a negative number since we sometimes deliberately
> +		 * skip quota reservations.
> +		 */
> +		res->reserved += count_delta;
> +	}
> +}
>   
>   /*
>    * Called by xfs_trans_commit() and similar in spirit to
> @@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas(
>   		xfs_trans_dqlockedjoin(tp, qa);
>   
>   		for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
> +			uint64_t	blk_res_used;
> +
>   			qtrx = &qa[i];
>   			/*
>   			 * The array of dquots is filled
> @@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas(
>   			 * In case of delayed allocations, there's no
>   			 * reservation that a transaction structure knows of.
>   			 */
> -			if (qtrx->qt_blk_res != 0) {
> -				uint64_t	blk_res_used = 0;
> +			blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
> +			xfs_apply_quota_reservation_deltas(&dqp->q_blk,
> +					qtrx->qt_blk_res, blk_res_used,
> +					qtrx->qt_bcount_delta);
>   
> -				if (qtrx->qt_bcount_delta > 0)
> -					blk_res_used = qtrx->qt_bcount_delta;
> -
> -				if (qtrx->qt_blk_res != blk_res_used) {
> -					if (qtrx->qt_blk_res > blk_res_used)
> -						dqp->q_blk.reserved -= (xfs_qcnt_t)
> -							(qtrx->qt_blk_res -
> -							 blk_res_used);
> -					else
> -						dqp->q_blk.reserved -= (xfs_qcnt_t)
> -							(blk_res_used -
> -							 qtrx->qt_blk_res);
> -				}
> -			} else {
> -				/*
> -				 * These blks were never reserved, either inside
> -				 * a transaction or outside one (in a delayed
> -				 * allocation). Also, this isn't always a
> -				 * negative number since we sometimes
> -				 * deliberately skip quota reservations.
> -				 */
> -				if (qtrx->qt_bcount_delta) {
> -					dqp->q_blk.reserved +=
> -					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
> -				}
> -			}
>   			/*
>   			 * Adjust the RT reservation.
>   			 */
> -			if (qtrx->qt_rtblk_res != 0) {
> -				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
> -					if (qtrx->qt_rtblk_res >
> -					    qtrx->qt_rtblk_res_used)
> -					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
> -						       (qtrx->qt_rtblk_res -
> -							qtrx->qt_rtblk_res_used);
> -					else
> -					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
> -						       (qtrx->qt_rtblk_res_used -
> -							qtrx->qt_rtblk_res);
> -				}
> -			} else {
> -				if (qtrx->qt_rtbcount_delta)
> -					dqp->q_rtb.reserved +=
> -					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
> -			}
> +			xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
> +					qtrx->qt_rtblk_res,
> +					qtrx->qt_rtblk_res_used,
> +					qtrx->qt_rtbcount_delta);
>   
>   			/*
>   			 * Adjust the inode reservation.
>   			 */
> -			if (qtrx->qt_ino_res != 0) {
> -				ASSERT(qtrx->qt_ino_res >=
> -				       qtrx->qt_ino_res_used);
> -				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
> -					dqp->q_ino.reserved -= (xfs_qcnt_t)
> -						(qtrx->qt_ino_res -
> -						 qtrx->qt_ino_res_used);
> -			} else {
> -				if (qtrx->qt_icount_delta)
> -					dqp->q_ino.reserved +=
> -					    (xfs_qcnt_t)qtrx->qt_icount_delta;
> -			}
> +			ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
> +			xfs_apply_quota_reservation_deltas(&dqp->q_ino,
> +					qtrx->qt_ino_res,
> +					qtrx->qt_ino_res_used,
> +					qtrx->qt_icount_delta);
>   
>   			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
>   			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 18/18] xfs: add more dquot tracepoints
  2020-06-30 15:43 ` [PATCH 18/18] xfs: add more dquot tracepoints Darrick J. Wong
@ 2020-07-04 20:41   ` Allison Collins
  2020-07-06 13:42   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Allison Collins @ 2020-07-04 20:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs



On 6/30/20 8:43 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add all the xfs_dquot fields to the tracepoint for that type; add a new
> tracepoint type for the qtrx structure (dquot transaction deltas); and
> use our new tracepoints.  This makes it easier for the author to trace
> changes to dquot counters for debugging.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Alrighty, seems helpful
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/xfs_trace.h       |  140 +++++++++++++++++++++++++++++++++++++++++++++-
>   fs/xfs/xfs_trans_dquot.c |   21 +++++++
>   2 files changed, 159 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 851f97dfe9e3..35b9dfd3984f 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -36,6 +36,7 @@ struct xfs_owner_info;
>   struct xfs_trans_res;
>   struct xfs_inobt_rec_incore;
>   union xfs_btree_ptr;
> +struct xfs_dqtrx;
>   
>   #define XFS_ATTR_FILTER_FLAGS \
>   	{ XFS_ATTR_ROOT,	"ROOT" }, \
> @@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>   		__field(unsigned, flags)
>   		__field(unsigned, nrefs)
>   		__field(unsigned long long, res_bcount)
> +		__field(unsigned long long, res_rtbcount)
> +		__field(unsigned long long, res_icount)
> +
>   		__field(unsigned long long, bcount)
> +		__field(unsigned long long, rtbcount)
>   		__field(unsigned long long, icount)
> +
>   		__field(unsigned long long, blk_hardlimit)
>   		__field(unsigned long long, blk_softlimit)
> +		__field(unsigned long long, rtb_hardlimit)
> +		__field(unsigned long long, rtb_softlimit)
>   		__field(unsigned long long, ino_hardlimit)
>   		__field(unsigned long long, ino_softlimit)
> -	), \
> +	),
>   	TP_fast_assign(
>   		__entry->dev = dqp->q_mount->m_super->s_dev;
>   		__entry->id = dqp->q_id;
>   		__entry->flags = dqp->dq_flags;
>   		__entry->nrefs = dqp->q_nrefs;
> +
>   		__entry->res_bcount = dqp->q_blk.reserved;
> +		__entry->res_rtbcount = dqp->q_rtb.reserved;
> +		__entry->res_icount = dqp->q_ino.reserved;
> +
>   		__entry->bcount = dqp->q_blk.count;
> +		__entry->rtbcount = dqp->q_rtb.count;
>   		__entry->icount = dqp->q_ino.count;
> +
>   		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
>   		__entry->blk_softlimit = dqp->q_blk.softlimit;
> +		__entry->rtb_hardlimit = dqp->q_rtb.hardlimit;
> +		__entry->rtb_softlimit = dqp->q_rtb.softlimit;
>   		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
>   		__entry->ino_softlimit = dqp->q_ino.softlimit;
>   	),
> -	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
> +	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u "
> +		  "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx "
>   		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
> +		  "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx "
>   		  "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]",
>   		  MAJOR(__entry->dev), MINOR(__entry->dev),
>   		  __entry->id,
>   		  __print_flags(__entry->flags, "|", XFS_DQ_FLAGS),
>   		  __entry->nrefs,
>   		  __entry->res_bcount,
> +		  __entry->res_rtbcount,
> +		  __entry->res_icount,
>   		  __entry->bcount,
>   		  __entry->blk_hardlimit,
>   		  __entry->blk_softlimit,
> +		  __entry->rtbcount,
> +		  __entry->rtb_hardlimit,
> +		  __entry->rtb_softlimit,
>   		  __entry->icount,
>   		  __entry->ino_hardlimit,
>   		  __entry->ino_softlimit)
> @@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele);
>   DEFINE_DQUOT_EVENT(xfs_dqflush);
>   DEFINE_DQUOT_EVENT(xfs_dqflush_force);
>   DEFINE_DQUOT_EVENT(xfs_dqflush_done);
> +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before);
> +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after);
> +
> +#define XFS_QMOPT_FLAGS \
> +	{ XFS_QMOPT_UQUOTA,		"UQUOTA" }, \
> +	{ XFS_QMOPT_PQUOTA,		"PQUOTA" }, \
> +	{ XFS_QMOPT_FORCE_RES,		"FORCE_RES" }, \
> +	{ XFS_QMOPT_SBVERSION,		"SBVERSION" }, \
> +	{ XFS_QMOPT_GQUOTA,		"GQUOTA" }, \
> +	{ XFS_QMOPT_INHERIT,		"INHERIT" }, \
> +	{ XFS_QMOPT_RES_REGBLKS,	"RES_REGBLKS" }, \
> +	{ XFS_QMOPT_RES_RTBLKS,		"RES_RTBLKS" }, \
> +	{ XFS_QMOPT_BCOUNT,		"BCOUNT" }, \
> +	{ XFS_QMOPT_ICOUNT,		"ICOUNT" }, \
> +	{ XFS_QMOPT_RTBCOUNT,		"RTBCOUNT" }, \
> +	{ XFS_QMOPT_DELBCOUNT,		"DELBCOUNT" }, \
> +	{ XFS_QMOPT_DELRTBCOUNT,	"DELRTBCOUNT" }, \
> +	{ XFS_QMOPT_RES_INOS,		"RES_INOS" }
> +
> +TRACE_EVENT(xfs_trans_mod_dquot,
> +	TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp,
> +		 unsigned int field, int64_t delta),
> +	TP_ARGS(tp, dqp, field, delta),
> +	TP_STRUCT__entry(
> +		__field(dev_t, dev)
> +		__field(unsigned int, dqflags)
> +		__field(unsigned int, dqid)
> +		__field(unsigned int, field)
> +		__field(int64_t, delta)
> +	),
> +	TP_fast_assign(
> +		__entry->dev = tp->t_mountp->m_super->s_dev;
> +		__entry->dqflags = dqp->dq_flags;
> +		__entry->dqid = dqp->q_id;
> +		__entry->field = field;
> +		__entry->delta = delta;
> +	),
> +	TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld",
> +		  MAJOR(__entry->dev), MINOR(__entry->dev),
> +		   __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
> +		  __entry->dqid,
> +		   __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS),
> +		  __entry->delta)
> +);
> +
> +DECLARE_EVENT_CLASS(xfs_dqtrx_class,
> +	TP_PROTO(struct xfs_dqtrx *qtrx),
> +	TP_ARGS(qtrx),
> +	TP_STRUCT__entry(
> +		__field(dev_t, dev)
> +		__field(unsigned int, dqflags)
> +		__field(u32, dqid)
> +
> +		__field(uint64_t, blk_res)
> +		__field(int64_t,  bcount_delta)
> +		__field(int64_t,  delbcnt_delta)
> +
> +		__field(uint64_t, rtblk_res)
> +		__field(uint64_t, rtblk_res_used)
> +		__field(int64_t,  rtbcount_delta)
> +		__field(int64_t,  delrtb_delta)
> +
> +		__field(uint64_t, ino_res)
> +		__field(uint64_t, ino_res_used)
> +		__field(int64_t,  icount_delta)
> +	),
> +	TP_fast_assign(
> +		__entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev;
> +		__entry->dqflags = qtrx->qt_dquot->dq_flags;
> +		__entry->dqid = qtrx->qt_dquot->q_id;
> +
> +		__entry->blk_res = qtrx->qt_blk_res;
> +		__entry->bcount_delta = qtrx->qt_bcount_delta;
> +		__entry->delbcnt_delta = qtrx->qt_delbcnt_delta;
> +
> +		__entry->rtblk_res = qtrx->qt_rtblk_res;
> +		__entry->rtblk_res_used = qtrx->qt_rtblk_res_used;
> +		__entry->rtbcount_delta = qtrx->qt_rtbcount_delta;
> +		__entry->delrtb_delta = qtrx->qt_delrtb_delta;
> +
> +		__entry->ino_res = qtrx->qt_ino_res;
> +		__entry->ino_res_used = qtrx->qt_ino_res_used;
> +		__entry->icount_delta = qtrx->qt_icount_delta;
> +	),
> +	TP_printk("dev %d:%d dquot %s id 0x%x "
> +		  "blk_res %llu bcount_delta %lld delbcnt_delta %lld "
> +		  "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld "
> +		  "ino_res %llu ino_res_used %llu icount_delta %lld",
> +		MAJOR(__entry->dev), MINOR(__entry->dev),
> +		__print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
> +		__entry->dqid,
> +
> +		__entry->blk_res,
> +		__entry->bcount_delta,
> +		__entry->delbcnt_delta,
> +
> +		__entry->rtblk_res,
> +		__entry->rtblk_res_used,
> +		__entry->rtbcount_delta,
> +		__entry->delrtb_delta,
> +
> +		__entry->ino_res,
> +		__entry->ino_res_used,
> +		__entry->icount_delta)
> +)
> +
> +#define DEFINE_DQTRX_EVENT(name) \
> +DEFINE_EVENT(xfs_dqtrx_class, name, \
> +	TP_PROTO(struct xfs_dqtrx *qtrx), \
> +	TP_ARGS(qtrx))
> +DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas);
> +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before);
> +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after);
>   
>   DECLARE_EVENT_CLASS(xfs_loggrant_class,
>   	TP_PROTO(struct xlog *log, struct xlog_ticket *tic),
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 701923ea6c04..5689d9f1b748 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -15,6 +15,7 @@
>   #include "xfs_trans_priv.h"
>   #include "xfs_quota.h"
>   #include "xfs_qm.h"
> +#include "xfs_trace.h"
>   
>   STATIC void	xfs_trans_alloc_dqinfo(xfs_trans_t *);
>   
> @@ -203,6 +204,11 @@ xfs_trans_mod_dquot(
>   	if (qtrx->qt_dquot == NULL)
>   		qtrx->qt_dquot = dqp;
>   
> +	if (delta) {
> +		trace_xfs_trans_mod_dquot_before(qtrx);
> +		trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
> +	}
> +
>   	switch (field) {
>   
>   		/*
> @@ -266,6 +272,10 @@ xfs_trans_mod_dquot(
>   	      default:
>   		ASSERT(0);
>   	}
> +
> +	if (delta)
> +		trace_xfs_trans_mod_dquot_after(qtrx);
> +
>   	tp->t_flags |= XFS_TRANS_DQ_DIRTY;
>   }
>   
> @@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas(
>   				qtrx->qt_delbcnt_delta;
>   			totalrtbdelta = qtrx->qt_rtbcount_delta +
>   				qtrx->qt_delrtb_delta;
> +
> +			if (totalbdelta != 0 || totalrtbdelta != 0 ||
> +			    qtrx->qt_icount_delta != 0) {
> +				trace_xfs_trans_apply_dquot_deltas_before(dqp);
> +				trace_xfs_trans_apply_dquot_deltas(qtrx);
> +			}
> +
>   #ifdef DEBUG
>   			if (totalbdelta < 0)
>   				ASSERT(dqp->q_blk.count >= -totalbdelta);
> @@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas(
>   			if (totalrtbdelta)
>   				dqp->q_rtb.count += totalrtbdelta;
>   
> +			if (totalbdelta != 0 || totalrtbdelta != 0 ||
> +			    qtrx->qt_icount_delta != 0)
> +				trace_xfs_trans_apply_dquot_deltas_after(dqp);
> +
>   			/*
>   			 * Get any default limits in use.
>   			 * Start/reset the timer(s) if needed.
> 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas
  2020-06-30 15:43 ` [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas Darrick J. Wong
  2020-07-04 20:41   ` Allison Collins
@ 2020-07-06 13:40   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-06 13:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:38 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Hoist the code that adjusts the incore quota reservation count
> adjustments into a separate function, both to reduce the level of
> indentation and also to reduce the amount of open-coded logic.
>

The changes are logically consistent with the previous behaviour.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_trans_dquot.c |  103 +++++++++++++++++++++-------------------------
>  1 file changed, 46 insertions(+), 57 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 30a011dc9828..701923ea6c04 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -293,6 +293,37 @@ xfs_trans_dqlockedjoin(
>  	}
>  }
>  
> +/* Apply dqtrx changes to the quota reservation counters. */
> +static inline void
> +xfs_apply_quota_reservation_deltas(
> +	struct xfs_dquot_res	*res,
> +	uint64_t		reserved,
> +	int64_t			res_used,
> +	int64_t			count_delta)
> +{
> +	if (reserved != 0) {
> +		/*
> +		 * Subtle math here: If reserved > res_used (the normal case),
> +		 * we're simply subtracting the unused transaction quota
> +		 * reservation from the dquot reservation.
> +		 *
> +		 * If, however, res_used > reserved, then we have allocated
> +		 * more quota blocks than were reserved for the transaction.
> +		 * We must add that excess to the dquot reservation since it
> +		 * tracks (usage + resv) and by definition we didn't reserve
> +		 * that excess.
> +		 */
> +		res->reserved -= abs(reserved - res_used);
> +	} else if (count_delta != 0) {
> +		/*
> +		 * These blks were never reserved, either inside a transaction
> +		 * or outside one (in a delayed allocation). Also, this isn't
> +		 * always a negative number since we sometimes deliberately
> +		 * skip quota reservations.
> +		 */
> +		res->reserved += count_delta;
> +	}
> +}
>  
>  /*
>   * Called by xfs_trans_commit() and similar in spirit to
> @@ -327,6 +358,8 @@ xfs_trans_apply_dquot_deltas(
>  		xfs_trans_dqlockedjoin(tp, qa);
>  
>  		for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
> +			uint64_t	blk_res_used;
> +
>  			qtrx = &qa[i];
>  			/*
>  			 * The array of dquots is filled
> @@ -396,71 +429,27 @@ xfs_trans_apply_dquot_deltas(
>  			 * In case of delayed allocations, there's no
>  			 * reservation that a transaction structure knows of.
>  			 */
> -			if (qtrx->qt_blk_res != 0) {
> -				uint64_t	blk_res_used = 0;
> +			blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
> +			xfs_apply_quota_reservation_deltas(&dqp->q_blk,
> +					qtrx->qt_blk_res, blk_res_used,
> +					qtrx->qt_bcount_delta);
>  
> -				if (qtrx->qt_bcount_delta > 0)
> -					blk_res_used = qtrx->qt_bcount_delta;
> -
> -				if (qtrx->qt_blk_res != blk_res_used) {
> -					if (qtrx->qt_blk_res > blk_res_used)
> -						dqp->q_blk.reserved -= (xfs_qcnt_t)
> -							(qtrx->qt_blk_res -
> -							 blk_res_used);
> -					else
> -						dqp->q_blk.reserved -= (xfs_qcnt_t)
> -							(blk_res_used -
> -							 qtrx->qt_blk_res);
> -				}
> -			} else {
> -				/*
> -				 * These blks were never reserved, either inside
> -				 * a transaction or outside one (in a delayed
> -				 * allocation). Also, this isn't always a
> -				 * negative number since we sometimes
> -				 * deliberately skip quota reservations.
> -				 */
> -				if (qtrx->qt_bcount_delta) {
> -					dqp->q_blk.reserved +=
> -					      (xfs_qcnt_t)qtrx->qt_bcount_delta;
> -				}
> -			}
>  			/*
>  			 * Adjust the RT reservation.
>  			 */
> -			if (qtrx->qt_rtblk_res != 0) {
> -				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
> -					if (qtrx->qt_rtblk_res >
> -					    qtrx->qt_rtblk_res_used)
> -					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
> -						       (qtrx->qt_rtblk_res -
> -							qtrx->qt_rtblk_res_used);
> -					else
> -					       dqp->q_rtb.reserved -= (xfs_qcnt_t)
> -						       (qtrx->qt_rtblk_res_used -
> -							qtrx->qt_rtblk_res);
> -				}
> -			} else {
> -				if (qtrx->qt_rtbcount_delta)
> -					dqp->q_rtb.reserved +=
> -					    (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
> -			}
> +			xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
> +					qtrx->qt_rtblk_res,
> +					qtrx->qt_rtblk_res_used,
> +					qtrx->qt_rtbcount_delta);
>  
>  			/*
>  			 * Adjust the inode reservation.
>  			 */
> -			if (qtrx->qt_ino_res != 0) {
> -				ASSERT(qtrx->qt_ino_res >=
> -				       qtrx->qt_ino_res_used);
> -				if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
> -					dqp->q_ino.reserved -= (xfs_qcnt_t)
> -						(qtrx->qt_ino_res -
> -						 qtrx->qt_ino_res_used);
> -			} else {
> -				if (qtrx->qt_icount_delta)
> -					dqp->q_ino.reserved +=
> -					    (xfs_qcnt_t)qtrx->qt_icount_delta;
> -			}
> +			ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
> +			xfs_apply_quota_reservation_deltas(&dqp->q_ino,
> +					qtrx->qt_ino_res,
> +					qtrx->qt_ino_res_used,
> +					qtrx->qt_icount_delta);
>  
>  			ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
>  			ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 18/18] xfs: add more dquot tracepoints
  2020-06-30 15:43 ` [PATCH 18/18] xfs: add more dquot tracepoints Darrick J. Wong
  2020-07-04 20:41   ` Allison Collins
@ 2020-07-06 13:42   ` Chandan Babu R
  1 sibling, 0 replies; 94+ messages in thread
From: Chandan Babu R @ 2020-07-06 13:42 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Tuesday 30 June 2020 9:13:45 PM IST Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Add all the xfs_dquot fields to the tracepoint for that type; add a new
> tracepoint type for the qtrx structure (dquot transaction deltas); and
> use our new tracepoints.  This makes it easier for the author to trace
> changes to dquot counters for debugging.
>

The changes look good to me.

Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_trace.h       |  140 +++++++++++++++++++++++++++++++++++++++++++++-
>  fs/xfs/xfs_trans_dquot.c |   21 +++++++
>  2 files changed, 159 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 851f97dfe9e3..35b9dfd3984f 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -36,6 +36,7 @@ struct xfs_owner_info;
>  struct xfs_trans_res;
>  struct xfs_inobt_rec_incore;
>  union xfs_btree_ptr;
> +struct xfs_dqtrx;
>  
>  #define XFS_ATTR_FILTER_FLAGS \
>  	{ XFS_ATTR_ROOT,	"ROOT" }, \
> @@ -867,37 +868,59 @@ DECLARE_EVENT_CLASS(xfs_dquot_class,
>  		__field(unsigned, flags)
>  		__field(unsigned, nrefs)
>  		__field(unsigned long long, res_bcount)
> +		__field(unsigned long long, res_rtbcount)
> +		__field(unsigned long long, res_icount)
> +
>  		__field(unsigned long long, bcount)
> +		__field(unsigned long long, rtbcount)
>  		__field(unsigned long long, icount)
> +
>  		__field(unsigned long long, blk_hardlimit)
>  		__field(unsigned long long, blk_softlimit)
> +		__field(unsigned long long, rtb_hardlimit)
> +		__field(unsigned long long, rtb_softlimit)
>  		__field(unsigned long long, ino_hardlimit)
>  		__field(unsigned long long, ino_softlimit)
> -	), \
> +	),
>  	TP_fast_assign(
>  		__entry->dev = dqp->q_mount->m_super->s_dev;
>  		__entry->id = dqp->q_id;
>  		__entry->flags = dqp->dq_flags;
>  		__entry->nrefs = dqp->q_nrefs;
> +
>  		__entry->res_bcount = dqp->q_blk.reserved;
> +		__entry->res_rtbcount = dqp->q_rtb.reserved;
> +		__entry->res_icount = dqp->q_ino.reserved;
> +
>  		__entry->bcount = dqp->q_blk.count;
> +		__entry->rtbcount = dqp->q_rtb.count;
>  		__entry->icount = dqp->q_ino.count;
> +
>  		__entry->blk_hardlimit = dqp->q_blk.hardlimit;
>  		__entry->blk_softlimit = dqp->q_blk.softlimit;
> +		__entry->rtb_hardlimit = dqp->q_rtb.hardlimit;
> +		__entry->rtb_softlimit = dqp->q_rtb.softlimit;
>  		__entry->ino_hardlimit = dqp->q_ino.hardlimit;
>  		__entry->ino_softlimit = dqp->q_ino.softlimit;
>  	),
> -	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u res_bc 0x%llx "
> +	TP_printk("dev %d:%d id 0x%x flags %s nrefs %u "
> +		  "res_bc 0x%llx res_rtbc 0x%llx res_ic 0x%llx "
>  		  "bcnt 0x%llx bhardlimit 0x%llx bsoftlimit 0x%llx "
> +		  "rtbcnt 0x%llx rtbhardlimit 0x%llx rtbsoftlimit 0x%llx "
>  		  "icnt 0x%llx ihardlimit 0x%llx isoftlimit 0x%llx]",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		  __entry->id,
>  		  __print_flags(__entry->flags, "|", XFS_DQ_FLAGS),
>  		  __entry->nrefs,
>  		  __entry->res_bcount,
> +		  __entry->res_rtbcount,
> +		  __entry->res_icount,
>  		  __entry->bcount,
>  		  __entry->blk_hardlimit,
>  		  __entry->blk_softlimit,
> +		  __entry->rtbcount,
> +		  __entry->rtb_hardlimit,
> +		  __entry->rtb_softlimit,
>  		  __entry->icount,
>  		  __entry->ino_hardlimit,
>  		  __entry->ino_softlimit)
> @@ -928,6 +951,119 @@ DEFINE_DQUOT_EVENT(xfs_dqrele);
>  DEFINE_DQUOT_EVENT(xfs_dqflush);
>  DEFINE_DQUOT_EVENT(xfs_dqflush_force);
>  DEFINE_DQUOT_EVENT(xfs_dqflush_done);
> +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_before);
> +DEFINE_DQUOT_EVENT(xfs_trans_apply_dquot_deltas_after);
> +
> +#define XFS_QMOPT_FLAGS \
> +	{ XFS_QMOPT_UQUOTA,		"UQUOTA" }, \
> +	{ XFS_QMOPT_PQUOTA,		"PQUOTA" }, \
> +	{ XFS_QMOPT_FORCE_RES,		"FORCE_RES" }, \
> +	{ XFS_QMOPT_SBVERSION,		"SBVERSION" }, \
> +	{ XFS_QMOPT_GQUOTA,		"GQUOTA" }, \
> +	{ XFS_QMOPT_INHERIT,		"INHERIT" }, \
> +	{ XFS_QMOPT_RES_REGBLKS,	"RES_REGBLKS" }, \
> +	{ XFS_QMOPT_RES_RTBLKS,		"RES_RTBLKS" }, \
> +	{ XFS_QMOPT_BCOUNT,		"BCOUNT" }, \
> +	{ XFS_QMOPT_ICOUNT,		"ICOUNT" }, \
> +	{ XFS_QMOPT_RTBCOUNT,		"RTBCOUNT" }, \
> +	{ XFS_QMOPT_DELBCOUNT,		"DELBCOUNT" }, \
> +	{ XFS_QMOPT_DELRTBCOUNT,	"DELRTBCOUNT" }, \
> +	{ XFS_QMOPT_RES_INOS,		"RES_INOS" }
> +
> +TRACE_EVENT(xfs_trans_mod_dquot,
> +	TP_PROTO(struct xfs_trans *tp, struct xfs_dquot *dqp,
> +		 unsigned int field, int64_t delta),
> +	TP_ARGS(tp, dqp, field, delta),
> +	TP_STRUCT__entry(
> +		__field(dev_t, dev)
> +		__field(unsigned int, dqflags)
> +		__field(unsigned int, dqid)
> +		__field(unsigned int, field)
> +		__field(int64_t, delta)
> +	),
> +	TP_fast_assign(
> +		__entry->dev = tp->t_mountp->m_super->s_dev;
> +		__entry->dqflags = dqp->dq_flags;
> +		__entry->dqid = dqp->q_id;
> +		__entry->field = field;
> +		__entry->delta = delta;
> +	),
> +	TP_printk("dev %d:%d dquot %s id 0x%x %s delta %lld",
> +		  MAJOR(__entry->dev), MINOR(__entry->dev),
> +		   __print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
> +		  __entry->dqid,
> +		   __print_flags(__entry->field, "|", XFS_QMOPT_FLAGS),
> +		  __entry->delta)
> +);
> +
> +DECLARE_EVENT_CLASS(xfs_dqtrx_class,
> +	TP_PROTO(struct xfs_dqtrx *qtrx),
> +	TP_ARGS(qtrx),
> +	TP_STRUCT__entry(
> +		__field(dev_t, dev)
> +		__field(unsigned int, dqflags)
> +		__field(u32, dqid)
> +
> +		__field(uint64_t, blk_res)
> +		__field(int64_t,  bcount_delta)
> +		__field(int64_t,  delbcnt_delta)
> +
> +		__field(uint64_t, rtblk_res)
> +		__field(uint64_t, rtblk_res_used)
> +		__field(int64_t,  rtbcount_delta)
> +		__field(int64_t,  delrtb_delta)
> +
> +		__field(uint64_t, ino_res)
> +		__field(uint64_t, ino_res_used)
> +		__field(int64_t,  icount_delta)
> +	),
> +	TP_fast_assign(
> +		__entry->dev = qtrx->qt_dquot->q_mount->m_super->s_dev;
> +		__entry->dqflags = qtrx->qt_dquot->dq_flags;
> +		__entry->dqid = qtrx->qt_dquot->q_id;
> +
> +		__entry->blk_res = qtrx->qt_blk_res;
> +		__entry->bcount_delta = qtrx->qt_bcount_delta;
> +		__entry->delbcnt_delta = qtrx->qt_delbcnt_delta;
> +
> +		__entry->rtblk_res = qtrx->qt_rtblk_res;
> +		__entry->rtblk_res_used = qtrx->qt_rtblk_res_used;
> +		__entry->rtbcount_delta = qtrx->qt_rtbcount_delta;
> +		__entry->delrtb_delta = qtrx->qt_delrtb_delta;
> +
> +		__entry->ino_res = qtrx->qt_ino_res;
> +		__entry->ino_res_used = qtrx->qt_ino_res_used;
> +		__entry->icount_delta = qtrx->qt_icount_delta;
> +	),
> +	TP_printk("dev %d:%d dquot %s id 0x%x "
> +		  "blk_res %llu bcount_delta %lld delbcnt_delta %lld "
> +		  "rtblk_res %llu rtblk_res_used %llu rtbcount_delta %lld delrtb_delta %lld "
> +		  "ino_res %llu ino_res_used %llu icount_delta %lld",
> +		MAJOR(__entry->dev), MINOR(__entry->dev),
> +		__print_flags(__entry->dqflags, "|", XFS_DQ_FLAGS),
> +		__entry->dqid,
> +
> +		__entry->blk_res,
> +		__entry->bcount_delta,
> +		__entry->delbcnt_delta,
> +
> +		__entry->rtblk_res,
> +		__entry->rtblk_res_used,
> +		__entry->rtbcount_delta,
> +		__entry->delrtb_delta,
> +
> +		__entry->ino_res,
> +		__entry->ino_res_used,
> +		__entry->icount_delta)
> +)
> +
> +#define DEFINE_DQTRX_EVENT(name) \
> +DEFINE_EVENT(xfs_dqtrx_class, name, \
> +	TP_PROTO(struct xfs_dqtrx *qtrx), \
> +	TP_ARGS(qtrx))
> +DEFINE_DQTRX_EVENT(xfs_trans_apply_dquot_deltas);
> +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_before);
> +DEFINE_DQTRX_EVENT(xfs_trans_mod_dquot_after);
>  
>  DECLARE_EVENT_CLASS(xfs_loggrant_class,
>  	TP_PROTO(struct xlog *log, struct xlog_ticket *tic),
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index 701923ea6c04..5689d9f1b748 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -15,6 +15,7 @@
>  #include "xfs_trans_priv.h"
>  #include "xfs_quota.h"
>  #include "xfs_qm.h"
> +#include "xfs_trace.h"
>  
>  STATIC void	xfs_trans_alloc_dqinfo(xfs_trans_t *);
>  
> @@ -203,6 +204,11 @@ xfs_trans_mod_dquot(
>  	if (qtrx->qt_dquot == NULL)
>  		qtrx->qt_dquot = dqp;
>  
> +	if (delta) {
> +		trace_xfs_trans_mod_dquot_before(qtrx);
> +		trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
> +	}
> +
>  	switch (field) {
>  
>  		/*
> @@ -266,6 +272,10 @@ xfs_trans_mod_dquot(
>  	      default:
>  		ASSERT(0);
>  	}
> +
> +	if (delta)
> +		trace_xfs_trans_mod_dquot_after(qtrx);
> +
>  	tp->t_flags |= XFS_TRANS_DQ_DIRTY;
>  }
>  
> @@ -391,6 +401,13 @@ xfs_trans_apply_dquot_deltas(
>  				qtrx->qt_delbcnt_delta;
>  			totalrtbdelta = qtrx->qt_rtbcount_delta +
>  				qtrx->qt_delrtb_delta;
> +
> +			if (totalbdelta != 0 || totalrtbdelta != 0 ||
> +			    qtrx->qt_icount_delta != 0) {
> +				trace_xfs_trans_apply_dquot_deltas_before(dqp);
> +				trace_xfs_trans_apply_dquot_deltas(qtrx);
> +			}
> +
>  #ifdef DEBUG
>  			if (totalbdelta < 0)
>  				ASSERT(dqp->q_blk.count >= -totalbdelta);
> @@ -410,6 +427,10 @@ xfs_trans_apply_dquot_deltas(
>  			if (totalrtbdelta)
>  				dqp->q_rtb.count += totalrtbdelta;
>  
> +			if (totalbdelta != 0 || totalrtbdelta != 0 ||
> +			    qtrx->qt_icount_delta != 0)
> +				trace_xfs_trans_apply_dquot_deltas_after(dqp);
> +
>  			/*
>  			 * Get any default limits in use.
>  			 * Start/reset the timer(s) if needed.
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 94+ messages in thread

end of thread, back to index

Thread overview: 94+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-30 15:41 [PATCH 00/18] xfs: remove xfs_disk_quot from incore dquot Darrick J. Wong
2020-06-30 15:41 ` [PATCH 01/18] xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush Darrick J. Wong
2020-06-30 21:35   ` Allison Collins
2020-07-01  8:32   ` Chandan Babu R
2020-07-01  8:33   ` Christoph Hellwig
2020-07-01 22:42     ` Dave Chinner
2020-06-30 15:42 ` [PATCH 02/18] xfs: fix inode quota reservation checks Darrick J. Wong
2020-06-30 21:35   ` Allison Collins
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:34   ` Christoph Hellwig
2020-06-30 15:42 ` [PATCH 03/18] xfs: validate ondisk/incore dquot flags Darrick J. Wong
2020-06-30 21:35   ` Allison Collins
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:42   ` Christoph Hellwig
2020-07-01 18:25     ` Darrick J. Wong
2020-07-02  6:30       ` Christoph Hellwig
2020-07-02 15:13         ` Darrick J. Wong
2020-07-01 22:41   ` Dave Chinner
2020-07-01 23:16     ` Darrick J. Wong
2020-06-30 15:42 ` [PATCH 04/18] xfs: stop using q_core.d_flags in the quota code Darrick J. Wong
2020-07-01  8:34   ` Chandan Babu R
2020-07-01  8:47   ` Christoph Hellwig
2020-07-01 19:02     ` Darrick J. Wong
2020-07-01 20:15   ` Allison Collins
2020-07-01 22:50   ` Dave Chinner
2020-07-01 23:19     ` Darrick J. Wong
2020-07-01 23:44       ` Dave Chinner
2020-07-01 23:50         ` Darrick J. Wong
2020-07-03  0:58           ` Dave Chinner
2020-07-03 18:01             ` Darrick J. Wong
2020-06-30 15:42 ` [PATCH 05/18] xfs: stop using q_core.d_id " Darrick J. Wong
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:48   ` Christoph Hellwig
2020-07-01 20:16   ` Allison Collins
2020-06-30 15:42 ` [PATCH 06/18] xfs: use a per-resource struct for incore dquot data Darrick J. Wong
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:49   ` Christoph Hellwig
2020-07-01 20:16   ` Allison Collins
2020-06-30 15:42 ` [PATCH 07/18] xfs: stop using q_core limits in the quota code Darrick J. Wong
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:50   ` Christoph Hellwig
2020-07-01 20:16   ` Allison Collins
2020-07-01 23:01   ` Dave Chinner
2020-07-01 23:13     ` Darrick J. Wong
2020-07-01 23:33       ` Darrick J. Wong
2020-07-01 23:45         ` Dave Chinner
2020-06-30 15:42 ` [PATCH 08/18] xfs: stop using q_core counters " Darrick J. Wong
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:51   ` Christoph Hellwig
2020-07-01 23:20   ` Allison Collins
2020-06-30 15:42 ` [PATCH 09/18] xfs: stop using q_core warning " Darrick J. Wong
2020-07-01  8:33   ` Chandan Babu R
2020-07-01  8:51   ` Christoph Hellwig
2020-07-01 23:20   ` Allison Collins
2020-06-30 15:42 ` [PATCH 10/18] xfs: stop using q_core timers " Darrick J. Wong
2020-07-01  8:34   ` Chandan Babu R
2020-07-01  8:51   ` Christoph Hellwig
2020-07-01 23:20   ` Allison Collins
2020-06-30 15:43 ` [PATCH 11/18] xfs: remove qcore from incore dquots Darrick J. Wong
2020-07-01  8:34   ` Chandan Babu R
2020-07-01  8:52   ` Christoph Hellwig
2020-07-01 23:07   ` Dave Chinner
2020-07-01 23:14     ` Darrick J. Wong
2020-07-02  2:06   ` Allison Collins
2020-06-30 15:43 ` [PATCH 12/18] xfs: refactor default quota limits by resource Darrick J. Wong
2020-07-01  8:52   ` Chandan Babu R
2020-07-01  8:53   ` Christoph Hellwig
2020-07-01 23:30   ` Dave Chinner
2020-07-02  0:07     ` Darrick J. Wong
2020-07-02  2:06   ` Allison Collins
2020-06-30 15:43 ` [PATCH 13/18] xfs: remove unnecessary arguments from quota adjust functions Darrick J. Wong
2020-07-01  8:53   ` Christoph Hellwig
2020-07-01  8:58   ` Chandan Babu R
2020-07-02  2:06   ` Allison Collins
2020-06-30 15:43 ` [PATCH 14/18] xfs: refactor quota exceeded test Darrick J. Wong
2020-07-01  8:56   ` Christoph Hellwig
2020-07-01 17:51     ` Darrick J. Wong
2020-07-01 18:48       ` Eric Sandeen
2020-07-01 23:34       ` Dave Chinner
2020-07-01 10:19   ` Chandan Babu R
2020-07-02 18:57   ` Allison Collins
2020-06-30 15:43 ` [PATCH 15/18] xfs: refactor xfs_qm_scall_setqlim Darrick J. Wong
2020-07-01  8:56   ` Christoph Hellwig
2020-07-03  4:11   ` Allison Collins
2020-07-03 12:39   ` Chandan Babu R
2020-06-30 15:43 ` [PATCH 16/18] xfs: refactor xfs_trans_dqresv Darrick J. Wong
2020-07-03  4:11   ` Allison Collins
2020-07-03 13:00   ` Chandan Babu R
2020-06-30 15:43 ` [PATCH 17/18] xfs: refactor xfs_trans_apply_dquot_deltas Darrick J. Wong
2020-07-04 20:41   ` Allison Collins
2020-07-06 13:40   ` Chandan Babu R
2020-06-30 15:43 ` [PATCH 18/18] xfs: add more dquot tracepoints Darrick J. Wong
2020-07-04 20:41   ` Allison Collins
2020-07-06 13:42   ` Chandan Babu R

Linux-XFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-xfs/0 linux-xfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-xfs linux-xfs/ https://lore.kernel.org/linux-xfs \
		linux-xfs@vger.kernel.org
	public-inbox-index linux-xfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-xfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git