Commit 2125f957 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://oss.sgi.com:8090/xfs-linux-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 5bc4b4bd 4f2063ff
......@@ -116,17 +116,10 @@ __linvfs_write(
ssize_t rval;
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT)) {
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, rval);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos,
ioflags, NULL, rval);
up(&inode->i_sem);
}
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
}
......@@ -214,17 +207,10 @@ __linvfs_writev(
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = *ppos;
if (unlikely(file->f_flags & O_DIRECT)) {
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, rval);
} else {
down(&inode->i_sem);
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos,
ioflags, NULL, rval);
up(&inode->i_sem);
}
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
if (rval == -EIOCBQUEUED)
rval = wait_on_sync_kiocb(&kiocb);
......
......@@ -45,8 +45,7 @@
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
#define BROKEN_X86_ALIGNMENT
#endif
#else
typedef struct xfs_fsop_bulkreq32 {
compat_uptr_t lastip; /* last inode # pointer */
......@@ -77,6 +76,7 @@ xfs_ioctl32_bulkstat(
return sys_ioctl(fd, cmd, (unsigned long)p);
}
#endif
struct ioctl_trans xfs_ioctl32_trans[] = {
{ XFS_IOC_DIOINFO, },
......
This diff is collapsed.
......@@ -187,9 +187,9 @@ xfs_qm_dqdestroy(
*/
STATIC void
xfs_qm_dqinit_core(
xfs_dqid_t id,
uint type,
xfs_dqblk_t *d)
xfs_dqid_t id,
uint type,
xfs_dqblk_t *d)
{
/*
* Caller has zero'd the entire dquot 'chunk' already.
......@@ -249,6 +249,36 @@ __xfs_dqtrace_entry(
#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
* if necessary.
......@@ -265,53 +295,81 @@ xfs_qm_adjust_dqtimers(
xfs_mount_t *mp,
xfs_disk_dquot_t *d)
{
/*
* 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;
ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));
#ifdef QUOTADEBUG
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))
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
if (INT_ISZERO(d->d_btimer, 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_bcount, ARCH_CONVERT) >= INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_btimer, ARCH_CONVERT, get_seconds() + XFS_QI_BTIMELIMIT(mp));
(INT_GET(d->d_bcount, ARCH_CONVERT) >=
INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_btimer, ARCH_CONVERT,
get_seconds() + XFS_QI_BTIMELIMIT(mp));
}
} else {
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_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);
}
}
if (INT_ISZERO(d->d_itimer, 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_icount, ARCH_CONVERT) >= INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_itimer, ARCH_CONVERT, get_seconds() + XFS_QI_ITIMELIMIT(mp));
(INT_GET(d->d_icount, ARCH_CONVERT) >=
INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
INT_SET(d->d_itimer, ARCH_CONVERT,
get_seconds() + XFS_QI_ITIMELIMIT(mp));
}
} else {
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_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);
}
}
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 *);
extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp);
extern void xfs_qm_adjust_dqtimers(xfs_mount_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_dqget(xfs_mount_t *, xfs_inode_t *,
xfs_dqid_t, uint, uint, xfs_dquot_t **);
......
......@@ -1213,22 +1213,46 @@ xfs_qm_init_quotainfo(
XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
&dqp);
if (! error) {
xfs_disk_dquot_t *ddqp = &dqp->q_core;
/*
* The warnings and timers set the grace period given to
* a user or group before he or she can not perform any
* more writing. If it is zero, a default is used.
*/
qinf->qi_btimelimit = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) ?
INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT) : XFS_QM_BTIMELIMIT;
qinf->qi_itimelimit = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) ?
INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT) : XFS_QM_ITIMELIMIT;
qinf->qi_rtbtimelimit = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) ?
INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT) : XFS_QM_RTBTIMELIMIT;
qinf->qi_bwarnlimit = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) ?
INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) : XFS_QM_BWARNLIMIT;
qinf->qi_iwarnlimit = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) ?
INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) : XFS_QM_IWARNLIMIT;
qinf->qi_btimelimit =
INT_GET(ddqp->d_btimer, ARCH_CONVERT) ?
INT_GET(ddqp->d_btimer, ARCH_CONVERT) :
XFS_QM_BTIMELIMIT;
qinf->qi_itimelimit =
INT_GET(ddqp->d_itimer, ARCH_CONVERT) ?
INT_GET(ddqp->d_itimer, ARCH_CONVERT) :
XFS_QM_ITIMELIMIT;
qinf->qi_rtbtimelimit =
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 don't want this dquot cached. We haven't done a
......@@ -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);
}
dqp->dq_flags |= XFS_DQ_DIRTY;
}
......
......@@ -136,9 +136,14 @@ typedef struct xfs_quotainfo {
xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */
xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */
mutex_t qi_quotaofflock;/* to serialize quotaoff */
/* Some useful precalculated constants */
xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
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;
......
......@@ -648,8 +648,11 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
INT_SET(ddq->d_blk_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_blk_softlimit, ARCH_CONVERT, soft);
}
else {
if (id == 0) {
mp->m_quotainfo->qi_bhardlimit = hard;
mp->m_quotainfo->qi_bsoftlimit = soft;
}
} else {
qdprintk("blkhard %Ld < blksoft %Ld\n", hard, soft);
}
hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ?
......@@ -661,40 +664,49 @@ xfs_qm_scall_setqlim(
if (hard == 0 || hard >= soft) {
INT_SET(ddq->d_rtb_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_rtb_softlimit, ARCH_CONVERT, soft);
}
else
if (id == 0) {
mp->m_quotainfo->qi_rtbhardlimit = hard;
mp->m_quotainfo->qi_rtbsoftlimit = soft;
}
} else {
qdprintk("rtbhard %Ld < rtbsoft %Ld\n", hard, soft);
}
hard = (newlim->d_fieldmask & FS_DQ_IHARD) ?
(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) ?
(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) {
INT_SET(ddq->d_ino_hardlimit, ARCH_CONVERT, hard);
INT_SET(ddq->d_ino_softlimit, ARCH_CONVERT, soft);
}
else
if (id == 0) {
mp->m_quotainfo->qi_ihardlimit = hard;
mp->m_quotainfo->qi_isoftlimit = soft;
}
} else {
qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
}
if (id == 0) {
/*
* Timelimits for the super user set the relative time
* 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) {
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) {
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) {
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)) */ {
/*
......
......@@ -452,9 +452,13 @@ xfs_trans_apply_dquot_deltas(
INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta);
/*
* Get any default limits in use.
* 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;
/*
......@@ -625,6 +629,7 @@ xfs_trans_unreserve_and_mod_dquots(
STATIC int
xfs_trans_dqresv(
xfs_trans_t *tp,
xfs_mount_t *mp,
xfs_dquot_t *dqp,
long nblks,
long ninos,
......@@ -635,6 +640,7 @@ xfs_trans_dqresv(
xfs_qcnt_t softlimit;
time_t btimer;
xfs_qcnt_t *resbcountp;
xfs_quotainfo_t *q = mp->m_quotainfo;
if (! (flags & XFS_QMOPT_DQLOCK)) {
xfs_dqlock(dqp);
......@@ -642,13 +648,21 @@ xfs_trans_dqresv(
ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (flags & XFS_TRANS_DQ_RES_BLKS) {
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);
if (!softlimit)
softlimit = q->qi_bsoftlimit;
btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
resbcountp = &dqp->q_res_bcount;
} else {
ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
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);
if (!softlimit)
softlimit = q->qi_rtbsoftlimit;
btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
resbcountp = &dqp->q_res_rtbcount;
}
......@@ -689,14 +703,18 @@ xfs_trans_dqresv(
}
}
if (ninos > 0) {
if (INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT) > 0ULL &&
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT)) {
hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
if (!hardlimit)
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;
goto error_return;
} else if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) > 0ULL &&
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
} else if (softlimit > 0ULL &&
INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
/*
* If timer or warnings has expired,
* return EDQUOT
......@@ -786,19 +804,20 @@ xfs_trans_reserve_quota_bydquots(
resvd = 0;
if (udqp) {
if (xfs_trans_dqresv(tp, udqp, nblks, ninos, flags))
if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags))
return (EDQUOT);
resvd = 1;
}
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
*/
if (resvd) {
xfs_trans_dqresv(tp, udqp, -nblks, -ninos,
flags);
flags |= XFS_QMOPT_FORCE_RES;
xfs_trans_dqresv(tp, mp, udqp,
-nblks, -ninos, flags);
}
return (EDQUOT);
}
......
......@@ -3427,19 +3427,20 @@ xfs_bmap_do_search_extents(
int high; /* high index of binary search */
int low; /* low index of binary search */
/* Initialize the extent entry structure to catch access to
* uninitialized br_startblock field.
*/
got.br_startoff = 0xffa5a5a5a5a5a5a5;
got.br_blockcount = 0xa55a5a5a5a5a5a5a;
got.br_state = XFS_EXT_INVALID;
#if XFS_BIG_BLKNOS
got.br_startblock = 0xffffa5a5a5a5a5a5;
#else
got.br_startblock = 0xffffa5a5;
#endif
/*
* Initialize the extent entry structure to catch access to
* uninitialized br_startblock field.
*/
got.br_startoff = 0xffa5a5a5a5a5a5a5LL;
got.br_blockcount = 0xa55a5a5a5a5a5a5aLL;
got.br_state = XFS_EXT_INVALID;
#if XFS_BIG_BLKNOS
got.br_startblock = 0xffffa5a5a5a5a5a5LL;
#else
got.br_startblock = 0xffffa5a5;
#endif
if (lastx != NULLEXTNUM && lastx < nextents)
ep = base + lastx;
else
......
......@@ -142,6 +142,7 @@ xfs_growfs_data_private(
int dpct;
int error;
xfs_agnumber_t nagcount;
xfs_agnumber_t nagimax = 0;
xfs_rfsblock_t nb, nb_mod;
xfs_rfsblock_t new;
xfs_rfsblock_t nfree;
......@@ -183,7 +184,7 @@ xfs_growfs_data_private(
memset(&mp->m_perag[oagcount], 0,
(nagcount - oagcount) * sizeof(xfs_perag_t));
mp->m_flags |= XFS_MOUNT_32BITINODES;
xfs_initialize_perag(mp, nagcount);
nagimax = xfs_initialize_perag(mp, nagcount);
up_write(&mp->m_peraglock);
}
tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
......@@ -372,6 +373,9 @@ xfs_growfs_data_private(
if (error) {
return error;
}
/* New allocation groups fully initialized, so update mount struct */
if (nagimax)
mp->m_maxagi = nagimax;
if (mp->m_sb.sb_imax_pct) {
__uint64_t icount = mp->m_sb.sb_dblocks * mp->m_sb.sb_imax_pct;
do_div(icount, 100);
......
......@@ -2047,12 +2047,11 @@ xfs_qm_dqcheck(
errs++;
}
if (! errs) {
if (! errs && !INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT) &&
INT_GET(ddq->d_bcount, ARCH_CONVERT) >=
INT_GET(ddq->d_blk_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT) &&
!INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_btimer, ARCH_CONVERT)) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
......@@ -2065,8 +2064,7 @@ xfs_qm_dqcheck(
if (INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT) &&
INT_GET(ddq->d_icount, ARCH_CONVERT) >=
INT_GET(ddq->d_ino_softlimit, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT) &&
!INT_ISZERO(ddq->d_id, ARCH_CONVERT)) {
if (INT_ISZERO(ddq->d_itimer, ARCH_CONVERT)) {
if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT,
"%s : Dquot ID 0x%x (0x%p) "
......@@ -2076,6 +2074,19 @@ xfs_qm_dqcheck(
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))
......
......@@ -318,10 +318,10 @@ xfs_mount_validate_sb(
return 0;
}
void
xfs_initialize_perag(xfs_mount_t *mp, int agcount)
xfs_agnumber_t
xfs_initialize_perag(xfs_mount_t *mp, xfs_agnumber_t agcount)
{
int index, max_metadata;
xfs_agnumber_t index, max_metadata;
xfs_perag_t *pag;
xfs_agino_t agino;
xfs_ino_t ino;
......@@ -377,7 +377,7 @@ xfs_initialize_perag(xfs_mount_t *mp, int agcount)
pag->pagi_inodeok = 1;
}
}
mp->m_maxagi = index;
return index;
}
/*
......@@ -951,7 +951,7 @@ xfs_mountfs(
mp->m_perag =
kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP);
xfs_initialize_perag(mp, sbp->sb_agcount);
mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
/*
* log's mount-time initialization. Perform 1st part recovery if needed
......
......@@ -551,7 +551,7 @@ extern int xfs_readsb(xfs_mount_t *mp);
extern void xfs_freesb(xfs_mount_t *);
extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
extern void xfs_initialize_perag(xfs_mount_t *, int);
extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t);
extern void xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t,
__int64_t);
......
......@@ -283,7 +283,7 @@ xfs_getattr(
/*
* xfs_setattr
*/
STATIC int
int
xfs_setattr(
bhv_desc_t *bdp,
vattr_t *vap,
......@@ -305,6 +305,7 @@ xfs_setattr(
int mandlock_before, mandlock_after;
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
int file_owner;
int need_iolock = (flags & ATTR_DMI) == 0;
vp = BHV_TO_VNODE(bdp);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
......@@ -406,7 +407,8 @@ xfs_setattr(
goto error_return;
}
}
lock_flags |= XFS_IOLOCK_EXCL;
if (need_iolock)
lock_flags |= XFS_IOLOCK_EXCL;
}
xfs_ilock(ip, lock_flags);
......@@ -678,7 +680,8 @@ xfs_setattr(
XFS_TRANS_PERM_LOG_RES,
XFS_ITRUNCATE_LOG_COUNT))) {
xfs_trans_cancel(tp, 0);
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
if (need_iolock)
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return code;
}
commit_flags = XFS_TRANS_RELEASE_LOG_RES;
......@@ -4297,6 +4300,7 @@ xfs_free_file_space(
int rt;
xfs_fileoff_t startoffset_fsb;
xfs_trans_t *tp;
int need_iolock = (attr_flags & ATTR_DMI) == 0;
vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
mp = ip->i_mount;
......@@ -4324,7 +4328,8 @@ xfs_free_file_space(
return(error);
}
xfs_ilock(ip, XFS_IOLOCK_EXCL);
if (need_iolock)
xfs_ilock(ip, XFS_IOLOCK_EXCL);
rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
(__uint8_t)NBPP);
ilen = len + (offset & (rounding - 1));
......@@ -4342,10 +4347,8 @@ xfs_free_file_space(
nimap = 1;
error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0,
&imap, &nimap, NULL);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
if (error)
goto out_unlock_iolock;
ASSERT(nimap == 0 || nimap == 1);
if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
xfs_daddr_t block;
......@@ -4359,10 +4362,8 @@ xfs_free_file_space(
nimap = 1;
error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0,
&imap, &nimap, NULL);
if (error) {
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
if (error)
goto out_unlock_iolock;
ASSERT(nimap == 0 || nimap == 1);
if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
......@@ -4451,14 +4452,17 @@ xfs_free_file_space(
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
out_unlock_iolock:
if (need_iolock)
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
error0:
xfs_bmap_cancel(&free_list);
error1:
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_iunlock(ip, need_iolock ? (XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL) :
XFS_ILOCK_EXCL);
return error;
}
......@@ -4615,20 +4619,21 @@ xfs_change_file_space(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
ip->i_d.di_mode &= ~S_ISUID;
/*
* Note that we don't have to worry about mandatory
* file locking being disabled here because we only
* clear the S_ISGID bit if the Group execute bit is
* on, but if it was on then mandatory locking wouldn't
* have been enabled.
*/
if (ip->i_d.di_mode & S_IXGRP)
ip->i_d.di_mode &= ~S_ISGID;
if ((attr_flags & ATTR_DMI) == 0) {
ip->i_d.di_mode &= ~S_ISUID;
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
* Note that we don't have to worry about mandatory
* file locking being disabled here because we only
* clear the S_ISGID bit if the Group execute bit is
* on, but if it was on then mandatory locking wouldn't
* have been enabled.
*/
if (ip->i_d.di_mode & S_IXGRP)
ip->i_d.di_mode &= ~S_ISGID;
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
}
if (setprealloc)
ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
else if (clrprealloc)
......
......@@ -277,6 +277,7 @@ int sync_page_range(struct inode *inode, struct address_space *mapping,
ret = wait_on_page_writeback_range(mapping, start, end);
return ret;
}
EXPORT_SYMBOL(sync_page_range);
/**
* filemap_fdatawait - walk the list of under-writeback pages of the given
......
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