@@ -101,13 +101,16 @@ xfs_qm_adjust_dqlimits(
static inline bool
xfs_quota_exceeded(
- const __be64 *count,
+ const __be64 *dcount,
+ xfs_qcnt_t ina_count,
const __be64 *softlimit,
- const __be64 *hardlimit) {
+ const __be64 *hardlimit)
+{
+ uint64_t count = be64_to_cpup(dcount) - ina_count;
- if (*softlimit && be64_to_cpup(count) > be64_to_cpup(softlimit))
+ if (*softlimit && count > be64_to_cpup(softlimit))
return true;
- return *hardlimit && be64_to_cpup(count) > be64_to_cpup(hardlimit);
+ return *hardlimit && count > be64_to_cpup(hardlimit);
}
/*
@@ -126,8 +129,9 @@ xfs_quota_exceeded(
void
xfs_qm_adjust_dqtimers(
struct xfs_mount *mp,
- struct xfs_disk_dquot *d)
+ struct xfs_dquot *dqp)
{
+ struct xfs_disk_dquot *d = &dqp->q_core;
bool over;
ASSERT(d->d_id);
@@ -144,8 +148,8 @@ xfs_qm_adjust_dqtimers(
be64_to_cpu(d->d_rtb_hardlimit));
#endif
- over = xfs_quota_exceeded(&d->d_bcount, &d->d_blk_softlimit,
- &d->d_blk_hardlimit);
+ over = xfs_quota_exceeded(&d->d_bcount, dqp->q_ina_bcount,
+ &d->d_blk_softlimit, &d->d_blk_hardlimit);
if (!d->d_btimer) {
if (over) {
d->d_btimer = cpu_to_be32(get_seconds() +
@@ -159,8 +163,8 @@ xfs_qm_adjust_dqtimers(
}
}
- over = xfs_quota_exceeded(&d->d_icount, &d->d_ino_softlimit,
- &d->d_ino_hardlimit);
+ over = xfs_quota_exceeded(&d->d_icount, dqp->q_ina_icount,
+ &d->d_ino_softlimit, &d->d_ino_hardlimit);
if (!d->d_itimer) {
if (over) {
d->d_itimer = cpu_to_be32(get_seconds() +
@@ -174,8 +178,8 @@ xfs_qm_adjust_dqtimers(
}
}
- over = xfs_quota_exceeded(&d->d_rtbcount, &d->d_rtb_softlimit,
- &d->d_rtb_hardlimit);
+ over = xfs_quota_exceeded(&d->d_rtbcount, dqp->q_ina_rtbcount,
+ &d->d_rtb_softlimit, &d->d_rtb_hardlimit);
if (!d->d_rtbtimer) {
if (over) {
d->d_rtbtimer = cpu_to_be32(get_seconds() +
@@ -1279,6 +1283,8 @@ xfs_dquot_adjust(
dqp->q_ina_icount += inodes;
dqp->q_ina_bcount += dblocks;
dqp->q_ina_rtbcount += rblocks;
+ if (dqp->q_core.d_id)
+ xfs_qm_adjust_dqtimers(dqp->q_mount, dqp);
xfs_dqunlock(dqp);
}
@@ -164,7 +164,7 @@ 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_disk_dquot *d);
+ struct xfs_dquot *dqp);
void xfs_qm_adjust_dqlimits(struct xfs_mount *mp,
struct xfs_dquot *d);
xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, uint type);
@@ -1141,7 +1141,7 @@ xfs_qm_quotacheck_dqadjust(
*/
if (dqp->q_core.d_id) {
xfs_qm_adjust_dqlimits(mp, dqp);
- xfs_qm_adjust_dqtimers(mp, &dqp->q_core);
+ xfs_qm_adjust_dqtimers(mp, dqp);
}
dqp->dq_flags |= XFS_DQ_DIRTY;
@@ -593,7 +593,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, ddq);
+ xfs_qm_adjust_dqtimers(mp, dqp);
}
dqp->dq_flags |= XFS_DQ_DIRTY;
xfs_trans_log_dquot(tp, dqp);
@@ -388,7 +388,7 @@ xfs_trans_apply_dquot_deltas(
*/
if (d->d_id) {
xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
- xfs_qm_adjust_dqtimers(tp->t_mountp, d);
+ xfs_qm_adjust_dqtimers(tp->t_mountp, dqp);
}
dqp->dq_flags |= XFS_DQ_DIRTY;