Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 25273
b: refs/heads/master
c: 9a2a7de
h: refs/heads/master
i:
  25271: 559ef16
v: v3
  • Loading branch information
Nathan Scott committed Mar 31, 2006
1 parent 5d753fe commit a198e68
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 764d1f89a5f2b914bc13b1b8b8920a600a5fba10
refs/heads/master: 9a2a7de268f67fea0c450ed3e99a2d31f43d7166
17 changes: 10 additions & 7 deletions trunk/fs/xfs/quota/xfs_qm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2624,7 +2624,7 @@ xfs_qm_vop_chown_reserve(
{
int error;
xfs_mount_t *mp;
uint delblks, blkflags;
uint delblks, blkflags, prjflags = 0;
xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;

ASSERT(XFS_ISLOCKED_INODE(ip));
Expand All @@ -2650,10 +2650,13 @@ xfs_qm_vop_chown_reserve(
}
}
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
if ((XFS_IS_GQUOTA_ON(ip->i_mount) &&
ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) ||
(XFS_IS_PQUOTA_ON(ip->i_mount) &&
ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) {
if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
prjflags = XFS_QMOPT_ENOSPC;

if (prjflags ||
(XFS_IS_GQUOTA_ON(ip->i_mount) &&
ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
delblksgdq = gdqp;
if (delblks) {
ASSERT(ip->i_gdquot);
Expand All @@ -2664,7 +2667,7 @@ xfs_qm_vop_chown_reserve(

if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
flags | blkflags)))
flags | blkflags | prjflags)))
return (error);

/*
Expand All @@ -2681,7 +2684,7 @@ xfs_qm_vop_chown_reserve(
ASSERT(unresudq || unresgdq);
if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
flags | blkflags)))
flags | blkflags | prjflags)))
return (error);
xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
Expand Down
68 changes: 36 additions & 32 deletions trunk/fs/xfs/quota/xfs_trans_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots(
}
}

STATIC int
xfs_quota_error(uint flags)
{
if (flags & XFS_QMOPT_ENOSPC)
return ENOSPC;
return EDQUOT;
}

/*
* This reserves disk blocks and inodes against a dquot.
* Flags indicate if the dquot is to be locked here and also
* if the blk reservation is for RT or regular blocks.
* Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
* Returns EDQUOT if quota is exceeded.
*/
STATIC int
xfs_trans_dqresv(
Expand Down Expand Up @@ -666,19 +673,15 @@ xfs_trans_dqresv(
*/
if (hardlimit > 0ULL &&
(hardlimit <= nblks + *resbcountp)) {
error = EDQUOT;
error = xfs_quota_error(flags);
goto error_return;
}

if (softlimit > 0ULL &&
(softlimit <= nblks + *resbcountp)) {
/*
* If timer or warnings has expired,
* return EDQUOT
*/
if ((timer != 0 && get_seconds() > timer) ||
(warns != 0 && warns >= warnlimit)) {
error = EDQUOT;
error = xfs_quota_error(flags);
goto error_return;
}
}
Expand All @@ -695,16 +698,12 @@ xfs_trans_dqresv(
if (!softlimit)
softlimit = q->qi_isoftlimit;
if (hardlimit > 0ULL && count >= hardlimit) {
error = EDQUOT;
error = xfs_quota_error(flags);
goto error_return;
} else if (softlimit > 0ULL && count >= softlimit) {
/*
* If timer or warnings has expired,
* return EDQUOT
*/
if ((timer != 0 && get_seconds() > timer) ||
(warns != 0 && warns >= warnlimit)) {
error = EDQUOT;
error = xfs_quota_error(flags);
goto error_return;
}
}
Expand Down Expand Up @@ -751,13 +750,14 @@ xfs_trans_dqresv(


/*
* Given a dquot(s), make disk block and/or inode reservations against them.
* Given dquot(s), make disk block and/or inode reservations against them.
* The fact that this does the reservation against both the usr and
* grp quotas is important, because this follows a both-or-nothing
* grp/prj quotas is important, because this follows a both-or-nothing
* approach.
*
* flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
* XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
* XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
* XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
* XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
* dquots are unlocked on return, if they were not locked by caller.
Expand All @@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots(
long ninos,
uint flags)
{
int resvd;
int resvd = 0, error;

if (! XFS_IS_QUOTA_ON(mp))
return (0);
if (!XFS_IS_QUOTA_ON(mp))
return 0;

if (tp && tp->t_dqinfo == NULL)
xfs_trans_alloc_dqinfo(tp);

ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
resvd = 0;

if (udqp) {
if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags))
return (EDQUOT);
error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
(flags & ~XFS_QMOPT_ENOSPC));
if (error)
return error;
resvd = 1;
}

if (gdqp) {
if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) {
error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
if (error) {
/*
* can't do it, so backout previous reservation
*/
Expand All @@ -799,23 +801,21 @@ xfs_trans_reserve_quota_bydquots(
xfs_trans_dqresv(tp, mp, udqp,
-nblks, -ninos, flags);
}
return (EDQUOT);
return error;
}
}

/*
* Didn't change anything critical, so, no need to log
*/
return (0);
return 0;
}


/*
* Lock the dquot and change the reservation if we can.
* This doesn't change the actual usage, just the reservation.
* The inode sent in is locked.
*
* Returns 0 on success, EDQUOT or other errors otherwise
*/
STATIC int
xfs_trans_reserve_quota_nblks(
Expand All @@ -824,29 +824,33 @@ xfs_trans_reserve_quota_nblks(
xfs_inode_t *ip,
long nblks,
long ninos,
uint type)
uint flags)
{
int error;

if (!XFS_IS_QUOTA_ON(mp))
return (0);
return 0;
if (XFS_IS_PQUOTA_ON(mp))
flags |= XFS_QMOPT_ENOSPC;

ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);

ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS ||
(type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS);
ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
XFS_TRANS_DQ_RES_RTBLKS ||
(flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
XFS_TRANS_DQ_RES_BLKS);

/*
* Reserve nblks against these dquots, with trans as the mediator.
*/
error = xfs_trans_reserve_quota_bydquots(tp, mp,
ip->i_udquot, ip->i_gdquot,
nblks, ninos,
type);
return (error);
flags);
return error;
}

/*
Expand Down
11 changes: 5 additions & 6 deletions trunk/fs/xfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -4719,18 +4719,17 @@ xfs_bmapi(
/*
* Make a transaction-less quota reservation for
* delayed allocation blocks. This number gets
* adjusted later.
* We return EDQUOT if we haven't allocated
* blks already inside this loop;
* adjusted later. We return if we haven't
* allocated blocks already inside this loop.
*/
if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
mp, NULL, ip, (long)alen, 0,
rt ? XFS_QMOPT_RES_RTBLKS :
XFS_QMOPT_RES_REGBLKS)) {
XFS_QMOPT_RES_REGBLKS))) {
if (n == 0) {
*nmap = 0;
ASSERT(cur == NULL);
return XFS_ERROR(EDQUOT);
return error;
}
break;
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/fs/xfs/xfs_quota.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,11 @@ typedef struct xfs_qoff_logformat {
#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */
#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */
#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */
#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */
#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */

/*
* flags to xfs_trans_mod_dquot to indicate which field needs to be
Expand Down

0 comments on commit a198e68

Please sign in to comment.