Commit 11d8a919 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: refactor quota expiration timer modification



Define explicit limits on the range of quota grace period expiration
timeouts and refactor the code that modifies the timeouts into helpers
that clamp the values appropriately.  Note that we'll refactor the
default grace period timer separately.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarAllison Collins <allison.henderson@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 876fdc7c
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1199,6 +1199,30 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)

#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK)

/*
 * XFS Quota Timers
 * ================
 *
 * Traditional quota grace period expiration timers are an unsigned 32-bit
 * seconds counter; time zero is the Unix epoch, Jan  1 00:00:01 UTC 1970.
 * Note that an expiration value of zero means that the quota limit has not
 * been reached, and therefore no expiration has been set.  Therefore, the
 * ondisk min and max defined here can be used directly to constrain the incore
 * quota expiration timestamps on a Unix system.
 */

/*
 * Smallest possible ondisk quota expiration value with traditional timestamps.
 * This corresponds exactly with the incore expiration Jan  1 00:00:01 UTC 1970.
 */
#define XFS_DQ_LEGACY_EXPIRY_MIN	((int64_t)1)

/*
 * Largest possible ondisk quota expiration value with traditional timestamps.
 * This corresponds exactly with the incore expiration Feb  7 06:28:15 UTC 2106.
 */
#define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)

/*
 * This is the main portion of the on-disk representation of quota information
 * for a user.  We pad this with some more expansion room to construct the on
+18 −4
Original line number Diff line number Diff line
@@ -98,12 +98,25 @@ xfs_qm_adjust_dqlimits(
		xfs_dquot_set_prealloc_limits(dq);
}

/* Set the expiration time of a quota's grace period. */
time64_t
xfs_dquot_set_timeout(
	struct xfs_mount	*mp,
	time64_t		timeout)
{
	struct xfs_quotainfo	*qi = mp->m_quotainfo;

	return clamp_t(time64_t, timeout, qi->qi_expiry_min,
					  qi->qi_expiry_max);
}

/*
 * 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_mount	*mp,
	struct xfs_dquot_res	*res,
	struct xfs_quota_limits	*qlim)
{
@@ -112,7 +125,8 @@ xfs_qm_adjust_res_timer(
	if ((res->softlimit && res->count > res->softlimit) ||
	    (res->hardlimit && res->count > res->hardlimit)) {
		if (res->timer == 0)
			res->timer = ktime_get_real_seconds() + qlim->time;
			res->timer = xfs_dquot_set_timeout(mp,
					ktime_get_real_seconds() + qlim->time);
	} else {
		if (res->timer == 0)
			res->warnings = 0;
@@ -145,9 +159,9 @@ xfs_qm_adjust_dqtimers(
	ASSERT(dq->q_id);
	defq = xfs_get_defquota(qi, xfs_dquot_type(dq));

	xfs_qm_adjust_res_timer(&dq->q_blk, &defq->blk);
	xfs_qm_adjust_res_timer(&dq->q_ino, &defq->ino);
	xfs_qm_adjust_res_timer(&dq->q_rtb, &defq->rtb);
	xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_blk, &defq->blk);
	xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_ino, &defq->ino);
	xfs_qm_adjust_res_timer(dq->q_mount, &dq->q_rtb, &defq->rtb);
}

/*
+2 −0
Original line number Diff line number Diff line
@@ -237,4 +237,6 @@ typedef int (*xfs_qm_dqiterate_fn)(struct xfs_dquot *dq,
int xfs_qm_dqiterate(struct xfs_mount *mp, xfs_dqtype_t type,
		xfs_qm_dqiterate_fn iter_fn, void *priv);

time64_t xfs_dquot_set_timeout(struct xfs_mount *mp, time64_t timeout);

#endif /* __XFS_DQUOT_H__ */
+2 −0
Original line number Diff line number Diff line
@@ -661,6 +661,8 @@ xfs_qm_init_quotainfo(
	/* Precalc some constants */
	qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
	qinf->qi_dqperchunk = xfs_calc_dquots_per_chunk(qinf->qi_dqchunklen);
	qinf->qi_expiry_min = XFS_DQ_LEGACY_EXPIRY_MIN;
	qinf->qi_expiry_max = XFS_DQ_LEGACY_EXPIRY_MAX;

	mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD);

+4 −0
Original line number Diff line number Diff line
@@ -65,6 +65,10 @@ struct xfs_quotainfo {
	struct xfs_def_quota	qi_grp_default;
	struct xfs_def_quota	qi_prj_default;
	struct shrinker		qi_shrinker;

	/* Minimum and maximum quota expiration timestamp values. */
	time64_t		qi_expiry_min;
	time64_t		qi_expiry_max;
};

static inline struct radix_tree_root *
Loading