Commit 898e768a authored by Nathan Scott's avatar Nathan Scott Committed by Nathan Scott

[XFS] Support for default quota limits via the zero dquot (ala grace times).

SGI Modid: xfs-linux:xfs-kern:177627a
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 60502d56
...@@ -187,9 +187,9 @@ xfs_qm_dqdestroy( ...@@ -187,9 +187,9 @@ xfs_qm_dqdestroy(
*/ */
STATIC void STATIC void
xfs_qm_dqinit_core( xfs_qm_dqinit_core(
xfs_dqid_t id, xfs_dqid_t id,
uint type, uint type,
xfs_dqblk_t *d) xfs_dqblk_t *d)
{ {
/* /*
* Caller has zero'd the entire dquot 'chunk' already. * Caller has zero'd the entire dquot 'chunk' already.
...@@ -249,6 +249,36 @@ __xfs_dqtrace_entry( ...@@ -249,6 +249,36 @@ __xfs_dqtrace_entry(
#endif #endif
/*
* If default limits are in force, push them into the dquot now.
* We overwrite the dquot limits only if they are zero and this
* is not the root dquot.
*/
void
xfs_qm_adjust_dqlimits(
xfs_mount_t *mp,
xfs_disk_dquot_t *d)
{
xfs_quotainfo_t *q = mp->m_quotainfo;
ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));
if (q->qi_bsoftlimit && INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT))
INT_SET(d->d_blk_softlimit, ARCH_CONVERT, q->qi_bsoftlimit);
if (q->qi_bhardlimit && INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT))
INT_SET(d->d_blk_hardlimit, ARCH_CONVERT, q->qi_bhardlimit);
if (q->qi_isoftlimit && INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT))
INT_SET(d->d_ino_softlimit, ARCH_CONVERT, q->qi_isoftlimit);
if (q->qi_ihardlimit && INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT))
INT_SET(d->d_ino_hardlimit, ARCH_CONVERT, q->qi_ihardlimit);
if (q->qi_rtbsoftlimit &&
INT_ISZERO(d->d_rtb_softlimit, ARCH_CONVERT))
INT_SET(d->d_rtb_softlimit, ARCH_CONVERT, q->qi_rtbsoftlimit);
if (q->qi_rtbhardlimit &&
INT_ISZERO(d->d_rtb_hardlimit, ARCH_CONVERT))
INT_SET(d->d_rtb_hardlimit, ARCH_CONVERT, q->qi_rtbhardlimit);
}
/* /*
* Check the limits and timers of a dquot and start or reset timers * Check the limits and timers of a dquot and start or reset timers
* if necessary. * if necessary.
...@@ -265,53 +295,81 @@ xfs_qm_adjust_dqtimers( ...@@ -265,53 +295,81 @@ xfs_qm_adjust_dqtimers(
xfs_mount_t *mp, xfs_mount_t *mp,
xfs_disk_dquot_t *d) xfs_disk_dquot_t *d)
{ {
/* ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));
* The dquot had better be locked. We are modifying it here.
*/
/*
* root's limits are not real limits.
*/
if (INT_ISZERO(d->d_id, ARCH_CONVERT))
return;
#ifdef QUOTADEBUG #ifdef QUOTADEBUG
if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)) if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT))
ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <= INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)); ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <=
INT_GET(d->d_blk_hardlimit, ARCH_CONVERT));
if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)) if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT))
ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <= INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)); ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <=
INT_GET(d->d_ino_hardlimit, ARCH_CONVERT));
if (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT))
ASSERT(INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) <=
INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT));
#endif #endif
if (INT_ISZERO(d->d_btimer, ARCH_CONVERT)) { if (INT_ISZERO(d->d_btimer, ARCH_CONVERT)) {
if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) && if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
(INT_GET(d->d_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) || (INT_GET(d->d_bcount, ARCH_CONVERT) >=
INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) ||
(INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) && (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) &&
(INT_GET(d->d_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { (INT_GET(d->d_bcount, ARCH_CONVERT) >=
INT_SET(d->d_btimer, ARCH_CONVERT, get_seconds() + XFS_QI_BTIMELIMIT(mp)); INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_btimer, ARCH_CONVERT,
get_seconds() + XFS_QI_BTIMELIMIT(mp));
} }
} else { } else {
if ((INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) || if ((INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
(INT_GET(d->d_bcount, ARCH_CONVERT) < INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) && (INT_GET(d->d_bcount, ARCH_CONVERT) <
INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) &&
(INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT) || (INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT) ||
(INT_GET(d->d_bcount, ARCH_CONVERT) < INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { (INT_GET(d->d_bcount, ARCH_CONVERT) <
INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
INT_ZERO(d->d_btimer, ARCH_CONVERT); INT_ZERO(d->d_btimer, ARCH_CONVERT);
} }
} }
if (INT_ISZERO(d->d_itimer, ARCH_CONVERT)) { if (INT_ISZERO(d->d_itimer, ARCH_CONVERT)) {
if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) && if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) &&
(INT_GET(d->d_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) || (INT_GET(d->d_icount, ARCH_CONVERT) >=
INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) ||
(INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) && (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) &&
(INT_GET(d->d_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { (INT_GET(d->d_icount, ARCH_CONVERT) >=
INT_SET(d->d_itimer, ARCH_CONVERT, get_seconds() + XFS_QI_ITIMELIMIT(mp)); INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_itimer, ARCH_CONVERT,
get_seconds() + XFS_QI_ITIMELIMIT(mp));
} }
} else { } else {
if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT) || if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT) ||
(INT_GET(d->d_icount, ARCH_CONVERT) < INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) && (INT_GET(d->d_icount, ARCH_CONVERT) <
INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) &&
(INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT) || (INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT) ||
(INT_GET(d->d_icount, ARCH_CONVERT) < INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { (INT_GET(d->d_icount, ARCH_CONVERT) <
INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
INT_ZERO(d->d_itimer, ARCH_CONVERT); INT_ZERO(d->d_itimer, ARCH_CONVERT);
} }
} }
if (INT_ISZERO(d->d_rtbtimer, ARCH_CONVERT)) {
if ((INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) &&
(INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) ||
(INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT) &&
(INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_rtbtimer, ARCH_CONVERT,
get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
}
} else {
if ((INT_ISZERO(d->d_rtb_softlimit, ARCH_CONVERT) ||
(INT_GET(d->d_rtbcount, ARCH_CONVERT) <
INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) &&
(INT_ISZERO(d->d_rtb_hardlimit, ARCH_CONVERT) ||
(INT_GET(d->d_rtbcount, ARCH_CONVERT) <
INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
INT_ZERO(d->d_rtbtimer, ARCH_CONVERT);
}
}
} }
/* /*
......
...@@ -209,6 +209,8 @@ extern int xfs_qm_dqflock_nowait(xfs_dquot_t *); ...@@ -209,6 +209,8 @@ extern int xfs_qm_dqflock_nowait(xfs_dquot_t *);
extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp); extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp);
extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
xfs_disk_dquot_t *); xfs_disk_dquot_t *);
extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
xfs_disk_dquot_t *);
extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint); extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
xfs_dqid_t, uint, uint, xfs_dquot_t **); xfs_dqid_t, uint, uint, xfs_dquot_t **);
......
...@@ -1213,22 +1213,46 @@ xfs_qm_init_quotainfo( ...@@ -1213,22 +1213,46 @@ xfs_qm_init_quotainfo(
XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
&dqp); &dqp);
if (! error) { if (! error) {
xfs_disk_dquot_t *ddqp = &dqp->q_core;
/* /*
* The warnings and timers set the grace period given to * The warnings and timers set the grace period given to
* a user or group before he or she can not perform any * a user or group before he or she can not perform any
* more writing. If it is zero, a default is used. * more writing. If it is zero, a default is used.
*/ */
qinf->qi_btimelimit = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) ? qinf->qi_btimelimit =
INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) : XFS_QM_BTIMELIMIT; INT_GET(ddqp->d_btimer, ARCH_CONVERT) ?
qinf->qi_itimelimit = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) ? INT_GET(ddqp->d_btimer, ARCH_CONVERT) :
INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) : XFS_QM_ITIMELIMIT; XFS_QM_BTIMELIMIT;
qinf->qi_rtbtimelimit = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) ? qinf->qi_itimelimit =
INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) : XFS_QM_RTBTIMELIMIT; INT_GET(ddqp->d_itimer, ARCH_CONVERT) ?
qinf->qi_bwarnlimit = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) ? INT_GET(ddqp->d_itimer, ARCH_CONVERT) :
INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) : XFS_QM_BWARNLIMIT; XFS_QM_ITIMELIMIT;
qinf->qi_iwarnlimit = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) ? qinf->qi_rtbtimelimit =
INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) : XFS_QM_IWARNLIMIT; INT_GET(ddqp->d_rtbtimer, ARCH_CONVERT) ?
INT_GET(ddqp->d_rtbtimer, ARCH_CONVERT) :
XFS_QM_RTBTIMELIMIT;
qinf->qi_bwarnlimit =
INT_GET(ddqp->d_bwarns, ARCH_CONVERT) ?
INT_GET(ddqp->d_bwarns, ARCH_CONVERT) :
XFS_QM_BWARNLIMIT;
qinf->qi_iwarnlimit =
INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
XFS_QM_IWARNLIMIT;
qinf->qi_bhardlimit =
INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
qinf->qi_bsoftlimit =
INT_GET(ddqp->d_blk_softlimit, ARCH_CONVERT);
qinf->qi_ihardlimit =
INT_GET(ddqp->d_ino_hardlimit, ARCH_CONVERT);
qinf->qi_isoftlimit =
INT_GET(ddqp->d_ino_softlimit, ARCH_CONVERT);
qinf->qi_rtbhardlimit =
INT_GET(ddqp->d_rtb_hardlimit, ARCH_CONVERT);
qinf->qi_rtbsoftlimit =
INT_GET(ddqp->d_rtb_softlimit, ARCH_CONVERT);
/* /*
* We sent the XFS_QMOPT_DQSUSER flag to dqget because * We sent the XFS_QMOPT_DQSUSER flag to dqget because
* we don't want this dquot cached. We haven't done a * we don't want this dquot cached. We haven't done a
...@@ -1688,10 +1712,12 @@ xfs_qm_quotacheck_dqadjust( ...@@ -1688,10 +1712,12 @@ xfs_qm_quotacheck_dqadjust(
} }
/* /*
* Adjust the timers since we just changed usages * Set default limits, adjust timers (since we changed usages)
*/ */
if (! XFS_IS_SUSER_DQUOT(dqp)) if (! XFS_IS_SUSER_DQUOT(dqp)) {
xfs_qm_adjust_dqlimits(dqp->q_mount, &dqp->q_core);
xfs_qm_adjust_dqtimers(dqp->q_mount, &dqp->q_core); xfs_qm_adjust_dqtimers(dqp->q_mount, &dqp->q_core);
}
dqp->dq_flags |= XFS_DQ_DIRTY; dqp->dq_flags |= XFS_DQ_DIRTY;
} }
......
...@@ -136,9 +136,14 @@ typedef struct xfs_quotainfo { ...@@ -136,9 +136,14 @@ typedef struct xfs_quotainfo {
xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */
xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */
mutex_t qi_quotaofflock;/* to serialize quotaoff */ mutex_t qi_quotaofflock;/* to serialize quotaoff */
/* Some useful precalculated constants */
xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
uint qi_dqperchunk; /* # ondisk dqs in above chunk */ uint qi_dqperchunk; /* # ondisk dqs in above chunk */
xfs_qcnt_t qi_bhardlimit; /* default data blk hard limit */
xfs_qcnt_t qi_bsoftlimit; /* default data blk soft limit */
xfs_qcnt_t qi_ihardlimit; /* default inode count hard limit */
xfs_qcnt_t qi_isoftlimit; /* default inode count soft limit */
xfs_qcnt_t qi_rtbhardlimit;/* default realtime blk hard limit */
xfs_qcnt_t qi_rtbsoftlimit;/* default realtime blk soft limit */
} xfs_quotainfo_t; } xfs_quotainfo_t;
......
...@@ -648,8 +648,11 @@ xfs_qm_scall_setqlim( ...@@ -648,8 +648,11 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) { if (hard == 0 || hard >= soft) {
INT_SET(ddq->d_blk_hardlimit, ARCH_CONVERT, hard); INT_SET(ddq->d_blk_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_blk_softlimit, ARCH_CONVERT, soft); INT_SET(ddq->d_blk_softlimit, ARCH_CONVERT, soft);
} if (id == 0) {
else { mp->m_quotainfo->qi_bhardlimit = hard;
mp->m_quotainfo->qi_bsoftlimit = soft;
}
} else {
qdprintk("blkhard %Ld < blksoft %Ld\n", hard, soft); qdprintk("blkhard %Ld < blksoft %Ld\n", hard, soft);
} }
hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ? hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ?
...@@ -661,40 +664,49 @@ xfs_qm_scall_setqlim( ...@@ -661,40 +664,49 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) { if (hard == 0 || hard >= soft) {
INT_SET(ddq->d_rtb_hardlimit, ARCH_CONVERT, hard); INT_SET(ddq->d_rtb_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_rtb_softlimit, ARCH_CONVERT, soft); INT_SET(ddq->d_rtb_softlimit, ARCH_CONVERT, soft);
} if (id == 0) {
else mp->m_quotainfo->qi_rtbhardlimit = hard;
mp->m_quotainfo->qi_rtbsoftlimit = soft;
}
} else {
qdprintk("rtbhard %Ld < rtbsoft %Ld\n", hard, soft); qdprintk("rtbhard %Ld < rtbsoft %Ld\n", hard, soft);
}
hard = (newlim->d_fieldmask & FS_DQ_IHARD) ? hard = (newlim->d_fieldmask & FS_DQ_IHARD) ?
(xfs_qcnt_t) newlim->d_ino_hardlimit : (xfs_qcnt_t) newlim->d_ino_hardlimit :
INT_GET(ddq->d_ino_hardlimit, ARCH_CONVERT); INT_GET(ddq->d_ino_hardlimit, ARCH_CONVERT);
soft = (newlim->d_fieldmask & FS_DQ_ISOFT) ? soft = (newlim->d_fieldmask & FS_DQ_ISOFT) ?
(xfs_qcnt_t) newlim->d_ino_softlimit : (xfs_qcnt_t) newlim->d_ino_softlimit :
INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT); INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT);
if (hard == 0 || hard >= soft) { if (hard == 0 || hard >= soft) {
INT_SET(ddq->d_ino_hardlimit, ARCH_CONVERT, hard); INT_SET(ddq->d_ino_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_ino_softlimit, ARCH_CONVERT, soft); INT_SET(ddq->d_ino_softlimit, ARCH_CONVERT, soft);
} if (id == 0) {
else mp->m_quotainfo->qi_ihardlimit = hard;
mp->m_quotainfo->qi_isoftlimit = soft;
}
} else {
qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
}
if (id == 0) { if (id == 0) {
/* /*
* Timelimits for the super user set the relative time * Timelimits for the super user set the relative time
* the other users can be over quota for this file system. * the other users can be over quota for this file system.
* If it is zero a default is used. * If it is zero a default is used. Ditto for the default
* soft and hard limit values (already done, above).
*/ */
if (newlim->d_fieldmask & FS_DQ_BTIMER) { if (newlim->d_fieldmask & FS_DQ_BTIMER) {
mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
INT_SET(dqp->q_core.d_btimer, ARCH_CONVERT, newlim->d_btimer); INT_SET(ddq->d_btimer, ARCH_CONVERT, newlim->d_btimer);
} }
if (newlim->d_fieldmask & FS_DQ_ITIMER) { if (newlim->d_fieldmask & FS_DQ_ITIMER) {
mp->m_quotainfo->qi_itimelimit = newlim->d_itimer; mp->m_quotainfo->qi_itimelimit = newlim->d_itimer;
INT_SET(dqp->q_core.d_itimer, ARCH_CONVERT, newlim->d_itimer); INT_SET(ddq->d_itimer, ARCH_CONVERT, newlim->d_itimer);
} }
if (newlim->d_fieldmask & FS_DQ_RTBTIMER) { if (newlim->d_fieldmask & FS_DQ_RTBTIMER) {
mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
INT_SET(dqp->q_core.d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
} }
} else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ { } else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ {
/* /*
......
...@@ -452,9 +452,13 @@ xfs_trans_apply_dquot_deltas( ...@@ -452,9 +452,13 @@ xfs_trans_apply_dquot_deltas(
INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta); INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta);
/* /*
* Get any default limits in use.
* Start/reset the timer(s) if needed. * Start/reset the timer(s) if needed.
*/ */
xfs_qm_adjust_dqtimers(tp->t_mountp, d); if (!INT_ISZERO(d->d_id, ARCH_CONVERT)) {
xfs_qm_adjust_dqlimits(tp->t_mountp, d);
xfs_qm_adjust_dqtimers(tp->t_mountp, d);
}
dqp->dq_flags |= XFS_DQ_DIRTY; dqp->dq_flags |= XFS_DQ_DIRTY;
/* /*
...@@ -625,6 +629,7 @@ xfs_trans_unreserve_and_mod_dquots( ...@@ -625,6 +629,7 @@ xfs_trans_unreserve_and_mod_dquots(
STATIC int STATIC int
xfs_trans_dqresv( xfs_trans_dqresv(
xfs_trans_t *tp, xfs_trans_t *tp,
xfs_mount_t *mp,
xfs_dquot_t *dqp, xfs_dquot_t *dqp,
long nblks, long nblks,
long ninos, long ninos,
...@@ -635,6 +640,7 @@ xfs_trans_dqresv( ...@@ -635,6 +640,7 @@ xfs_trans_dqresv(
xfs_qcnt_t softlimit; xfs_qcnt_t softlimit;
time_t btimer; time_t btimer;
xfs_qcnt_t *resbcountp; xfs_qcnt_t *resbcountp;
xfs_quotainfo_t *q = mp->m_quotainfo;
if (! (flags & XFS_QMOPT_DQLOCK)) { if (! (flags & XFS_QMOPT_DQLOCK)) {
xfs_dqlock(dqp); xfs_dqlock(dqp);
...@@ -642,13 +648,21 @@ xfs_trans_dqresv( ...@@ -642,13 +648,21 @@ xfs_trans_dqresv(
ASSERT(XFS_DQ_IS_LOCKED(dqp)); ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (flags & XFS_TRANS_DQ_RES_BLKS) { if (flags & XFS_TRANS_DQ_RES_BLKS) {
hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT); hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
if (!hardlimit)
hardlimit = q->qi_bhardlimit;
softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
if (!softlimit)
softlimit = q->qi_bsoftlimit;
btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
resbcountp = &dqp->q_res_bcount; resbcountp = &dqp->q_res_bcount;
} else { } else {
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit, ARCH_CONVERT); hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
if (!hardlimit)
hardlimit = q->qi_rtbhardlimit;
softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
if (!softlimit)
softlimit = q->qi_rtbsoftlimit;
btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
resbcountp = &dqp->q_res_rtbcount; resbcountp = &dqp->q_res_rtbcount;
} }
...@@ -689,14 +703,18 @@ xfs_trans_dqresv( ...@@ -689,14 +703,18 @@ xfs_trans_dqresv(
} }
} }
if (ninos > 0) { if (ninos > 0) {
if (INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT) > 0ULL && hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= if (!hardlimit)
INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT)) { hardlimit = q->qi_ihardlimit;
softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
if (!softlimit)
softlimit = q->qi_isoftlimit;
if (hardlimit > 0ULL &&
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
error = EDQUOT; error = EDQUOT;
goto error_return; goto error_return;
} else if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) > 0ULL && } else if (softlimit > 0ULL &&
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
/* /*
* If timer or warnings has expired, * If timer or warnings has expired,
* return EDQUOT * return EDQUOT
...@@ -786,19 +804,20 @@ xfs_trans_reserve_quota_bydquots( ...@@ -786,19 +804,20 @@ xfs_trans_reserve_quota_bydquots(
resvd = 0; resvd = 0;
if (udqp) { if (udqp) {
if (xfs_trans_dqresv(tp, udqp, nblks, ninos, flags)) if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags))
return (EDQUOT); return (EDQUOT);
resvd = 1; resvd = 1;
} }
if (gdqp) { if (gdqp) {
if (xfs_trans_dqresv(tp, gdqp, nblks, ninos, flags)) { if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) {
/* /*
* can't do it, so backout previous reservation * can't do it, so backout previous reservation
*/ */
if (resvd) { if (resvd) {
xfs_trans_dqresv(tp, udqp, -nblks, -ninos, flags |= XFS_QMOPT_FORCE_RES;
flags); xfs_trans_dqresv(tp, mp, udqp,
-nblks, -ninos, flags);
} }
return (EDQUOT); return (EDQUOT);
} }
......
...@@ -2047,12 +2047,11 @@ xfs_qm_dqcheck( ...@@ -2047,12 +2047,11 @@ xfs_qm_dqcheck(
errs++; errs++;
} }
if (! errs) { if (! errs && !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) && if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
INT_GET(ddq->d_bcount, ARCH_CONVERT) >= INT_GET(ddq->d_bcount, ARCH_CONVERT) >=
INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) { INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT) && if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT)) {
!INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (flags & XFS_QMOPT_DOWARN) if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT, cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) " "%s : Dquot ID 0x%x (0x%p) "
...@@ -2065,8 +2064,7 @@ xfs_qm_dqcheck( ...@@ -2065,8 +2064,7 @@ xfs_qm_dqcheck(
if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) && if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
INT_GET(ddq->d_icount, ARCH_CONVERT) >= INT_GET(ddq->d_icount, ARCH_CONVERT) >=
INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) { INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT) && if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT)) {
!INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (flags & XFS_QMOPT_DOWARN) if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT, cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) " "%s : Dquot ID 0x%x (0x%p) "
...@@ -2076,6 +2074,19 @@ xfs_qm_dqcheck( ...@@ -2076,6 +2074,19 @@ xfs_qm_dqcheck(
errs++; errs++;
} }
} }
if (INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT) &&
INT_GET(ddq->d_rtbcount, ARCH_CONVERT) >=
INT_GET(ddq->d_rtb_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_rtbtimer, ARCH_CONVERT)) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
"RTBLK TIMER NOT STARTED",
str, (int)
INT_GET(ddq->d_id, ARCH_CONVERT), ddq);
errs++;
}
}
} }
if (!errs || !(flags & XFS_QMOPT_DQREPAIR)) if (!errs || !(flags & XFS_QMOPT_DQREPAIR))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment