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);
|
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.
|
* This reserves disk blocks and inodes against a dquot.
|
||||||
* Flags indicate if the dquot is to be locked here and also
|
* Flags indicate if the dquot is to be locked here and also
|
||||||
@ -569,108 +621,59 @@ xfs_trans_dqresv(
|
|||||||
long ninos,
|
long ninos,
|
||||||
uint flags)
|
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_quotainfo *q = mp->m_quotainfo;
|
||||||
struct xfs_def_quota *defq;
|
struct xfs_def_quota *defq;
|
||||||
|
struct xfs_dquot_res *blkres;
|
||||||
|
struct xfs_quota_limits *qlim;
|
||||||
|
|
||||||
xfs_dqlock(dqp);
|
xfs_dqlock(dqp);
|
||||||
|
|
||||||
defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
|
defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
|
||||||
|
|
||||||
if (flags & XFS_TRANS_DQ_RES_BLKS) {
|
if (flags & XFS_TRANS_DQ_RES_BLKS) {
|
||||||
hardlimit = dqp->q_blk.hardlimit;
|
blkres = &dqp->q_blk;
|
||||||
if (!hardlimit)
|
qlim = &defq->blk;
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
|
blkres = &dqp->q_rtb;
|
||||||
hardlimit = dqp->q_rtb.hardlimit;
|
qlim = &defq->rtb;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
|
if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
|
||||||
((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
|
((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
|
||||||
(XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
|
(XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
|
||||||
(XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(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
|
* dquot is locked already. See if we'd go over the hardlimit
|
||||||
* hardlimit or exceed the timelimit if we allocate
|
* or exceed the timelimit if we'd reserve resources.
|
||||||
* nblks.
|
|
||||||
*/
|
*/
|
||||||
total_count = *resbcountp + nblks;
|
quota_nl = xfs_dqresv_check(blkres, qlim, nblks, &fatal);
|
||||||
if (hardlimit && total_count > hardlimit) {
|
if (quota_nl != QUOTA_NL_NOWARN) {
|
||||||
xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
|
/*
|
||||||
goto error_return;
|
* Quota block warning codes are 3 more than the inode
|
||||||
}
|
* codes, which we check above.
|
||||||
if (softlimit && total_count > softlimit) {
|
*/
|
||||||
if ((timer != 0 &&
|
xfs_quota_warn(mp, dqp, quota_nl + 3);
|
||||||
ktime_get_real_seconds() > timer) ||
|
if (fatal)
|
||||||
(warns != 0 && warns >= warnlimit)) {
|
|
||||||
xfs_quota_warn(mp, dqp,
|
|
||||||
QUOTA_NL_BSOFTLONGWARN);
|
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
|
quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->ino, ninos,
|
||||||
}
|
&fatal);
|
||||||
}
|
if (quota_nl != QUOTA_NL_NOWARN) {
|
||||||
if (ninos > 0) {
|
xfs_quota_warn(mp, dqp, quota_nl);
|
||||||
total_count = dqp->q_ino.reserved + ninos;
|
if (fatal)
|
||||||
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);
|
|
||||||
goto error_return;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the reservation, but not the actual usage.
|
* Change the reservation, but not the actual usage.
|
||||||
* Note that q_blk.reserved = q_blk.count + resv
|
* Note that q_blk.reserved = q_blk.count + resv
|
||||||
*/
|
*/
|
||||||
(*resbcountp) += (xfs_qcnt_t)nblks;
|
blkres->reserved += (xfs_qcnt_t)nblks;
|
||||||
if (ninos != 0)
|
|
||||||
dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
|
dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user