diff mbox series

[16/18] xfs: refactor xfs_trans_dqresv

Message ID 159353181258.2864738.8355431623063896449.stgit@magnolia (mailing list archive)
State Superseded, archived
Headers show
Series xfs: remove xfs_disk_quot from incore dquot | expand

Commit Message

Darrick J. Wong June 30, 2020, 3:43 p.m. UTC
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(-)

Comments

Allison Henderson July 3, 2020, 4:11 a.m. UTC | #1
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,
>
Chandan Babu R July 3, 2020, 1 p.m. UTC | #2
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,
> 
>
diff mbox series

Patch

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,