xfs: refactor xfs_trans_dqresv
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> Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com> Reviewed-by: Allison Collins <allison.henderson@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
d1520deab0
commit
292b47b4fc
|
@ -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_quota_limits *qlim,
|
||||
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 = qlim->hard;
|
||||
if (!softlimit)
|
||||
softlimit = qlim->soft;
|
||||
|
||||
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 >= qlim->warn)) {
|
||||
*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_quota_limits *qlim;
|
||||
|
||||
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->blk.hard;
|
||||
softlimit = dqp->q_blk.softlimit;
|
||||
if (!softlimit)
|
||||
softlimit = defq->blk.soft;
|
||||
timer = dqp->q_blk.timer;
|
||||
warns = dqp->q_blk.warnings;
|
||||
warnlimit = defq->blk.warn;
|
||||
resbcountp = &dqp->q_blk.reserved;
|
||||
blkres = &dqp->q_blk;
|
||||
qlim = &defq->blk;
|
||||
} else {
|
||||
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
|
||||
hardlimit = dqp->q_rtb.hardlimit;
|
||||
if (!hardlimit)
|
||||
hardlimit = defq->rtb.hard;
|
||||
softlimit = dqp->q_rtb.softlimit;
|
||||
if (!softlimit)
|
||||
softlimit = defq->rtb.soft;
|
||||
timer = dqp->q_rtb.timer;
|
||||
warns = dqp->q_rtb.warnings;
|
||||
warnlimit = defq->rtb.warn;
|
||||
resbcountp = &dqp->q_rtb.reserved;
|
||||
blkres = &dqp->q_rtb;
|
||||
qlim = &defq->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, qlim, 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->ino.warn;
|
||||
hardlimit = dqp->q_ino.hardlimit;
|
||||
if (!hardlimit)
|
||||
hardlimit = defq->ino.hard;
|
||||
softlimit = dqp->q_ino.softlimit;
|
||||
if (!softlimit)
|
||||
softlimit = defq->ino.soft;
|
||||
|
||||
if (hardlimit && total_count > hardlimit) {
|
||||
xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
|
||||
quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->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,
|
||||
|
|
Loading…
Reference in New Issue