mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
[XFS] Add support for project quota, based on Dan Knappes earlier work.
SGI-PV: 932952 SGI-Modid: xfs-linux:xfs-kern:22805a Signed-off-by: Nathan Scott <nathans@sgi.com>
This commit is contained in:
parent
8401e9631c
commit
c8ad20ffeb
@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
|
||||
* field (see the QCMD macro in quota.h). These macros help keep the
|
||||
* code portable - they are not visible from the syscall interface.
|
||||
*/
|
||||
#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */
|
||||
#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */
|
||||
#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
|
||||
#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */
|
||||
#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
|
||||
#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
|
||||
|
||||
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
|
||||
/* we may well need to fine-tune this if it ever becomes an issue. */
|
||||
|
@ -701,7 +701,8 @@ linvfs_getxquota(
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
int error, getmode;
|
||||
|
||||
getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
|
||||
getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
|
||||
((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
|
||||
VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
}
|
||||
@ -716,7 +717,8 @@ linvfs_setxquota(
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
int error, setmode;
|
||||
|
||||
setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
|
||||
setmode = (type == USRQUOTA) ? Q_XSETQLIM :
|
||||
((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
|
||||
VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
}
|
||||
|
@ -399,9 +399,9 @@ xfs_qm_init_dquot_blk(
|
||||
for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
|
||||
xfs_qm_dqinit_core(curid, type, d);
|
||||
xfs_trans_dquot_buf(tp, bp,
|
||||
type & XFS_DQ_USER ?
|
||||
XFS_BLI_UDQUOT_BUF :
|
||||
XFS_BLI_GDQUOT_BUF);
|
||||
(type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
|
||||
((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
|
||||
XFS_BLI_GDQUOT_BUF)));
|
||||
xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
|
||||
}
|
||||
|
||||
@ -482,8 +482,7 @@ xfs_qm_dqalloc(
|
||||
* the entire thing.
|
||||
*/
|
||||
xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
|
||||
dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
|
||||
bp);
|
||||
dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
|
||||
|
||||
if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
|
||||
goto error1;
|
||||
@ -613,8 +612,7 @@ xfs_qm_dqtobp(
|
||||
/*
|
||||
* A simple sanity check in case we got a corrupted dquot...
|
||||
*/
|
||||
if (xfs_qm_dqcheck(ddq, id,
|
||||
dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
|
||||
if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
|
||||
flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
|
||||
"dqtobp")) {
|
||||
if (!(flags & XFS_QMOPT_DQREPAIR)) {
|
||||
@ -891,8 +889,8 @@ int
|
||||
xfs_qm_dqget(
|
||||
xfs_mount_t *mp,
|
||||
xfs_inode_t *ip, /* locked inode (optional) */
|
||||
xfs_dqid_t id, /* gid or uid, depending on type */
|
||||
uint type, /* UDQUOT or GDQUOT */
|
||||
xfs_dqid_t id, /* uid/projid/gid depending on type */
|
||||
uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
|
||||
uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
|
||||
xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
|
||||
{
|
||||
@ -903,7 +901,9 @@ xfs_qm_dqget(
|
||||
|
||||
ASSERT(XFS_IS_QUOTA_RUNNING(mp));
|
||||
if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
|
||||
(! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
|
||||
(! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
|
||||
printk("XQM: ESRCH1\n");
|
||||
return (ESRCH);
|
||||
}
|
||||
h = XFS_DQ_HASH(mp, id, type);
|
||||
@ -921,7 +921,9 @@ xfs_qm_dqget(
|
||||
again:
|
||||
|
||||
#ifdef DEBUG
|
||||
ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP);
|
||||
ASSERT(type == XFS_DQ_USER ||
|
||||
type == XFS_DQ_PROJ ||
|
||||
type == XFS_DQ_GROUP);
|
||||
if (ip) {
|
||||
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
|
||||
if (type == XFS_DQ_USER)
|
||||
@ -979,6 +981,7 @@ xfs_qm_dqget(
|
||||
&dqp))) {
|
||||
if (ip)
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
if (error == ESRCH) printk("XQM: ESRCH2\n");
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1004,6 +1007,7 @@ xfs_qm_dqget(
|
||||
if (! XFS_IS_DQTYPE_ON(mp, type)) {
|
||||
/* inode stays locked on return */
|
||||
xfs_qm_dqdestroy(dqp);
|
||||
printk("XQM: ESRCH3\n");
|
||||
return XFS_ERROR(ESRCH);
|
||||
}
|
||||
/*
|
||||
@ -1244,8 +1248,8 @@ xfs_qm_dqflush(
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN,
|
||||
"dqflush (incore copy)")) {
|
||||
if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
|
||||
0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
|
||||
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
@ -1397,7 +1401,8 @@ xfs_dqlock2(
|
||||
{
|
||||
if (d1 && d2) {
|
||||
ASSERT(d1 != d2);
|
||||
if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
|
||||
if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
|
||||
INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
|
||||
xfs_dqlock(d2);
|
||||
xfs_dqlock(d1);
|
||||
} else {
|
||||
@ -1520,8 +1525,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
|
||||
cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
|
||||
cmn_err(CE_DEBUG, "---- dquotID = %d",
|
||||
(int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
|
||||
cmn_err(CE_DEBUG, "---- type = %s",
|
||||
XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
|
||||
cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
|
||||
cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
|
||||
cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
|
||||
cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
|
||||
|
@ -114,25 +114,18 @@ typedef struct xfs_dquot {
|
||||
#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
|
||||
|
||||
/*
|
||||
* Quota Accounting flags
|
||||
* Quota Accounting/Enforcement flags
|
||||
*/
|
||||
#define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT)
|
||||
#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD)
|
||||
#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
|
||||
#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
|
||||
XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_ACCT \
|
||||
(XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
|
||||
#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
|
||||
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
|
||||
|
||||
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
|
||||
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
|
||||
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
|
||||
|
||||
/*
|
||||
* Quota Limit Enforcement flags
|
||||
*/
|
||||
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
|
||||
#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
|
||||
#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
|
||||
#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD)
|
||||
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
|
||||
#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
|
||||
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline int
|
||||
@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
||||
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
|
||||
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
|
||||
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
|
||||
#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
|
||||
#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
|
||||
#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
|
||||
#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
|
||||
XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
|
||||
@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
||||
|
||||
#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
|
||||
(XFS_IS_UQUOTA_ON((d)->q_mount)) : \
|
||||
(XFS_IS_GQUOTA_ON((d)->q_mount))))
|
||||
(XFS_IS_OQUOTA_ON((d)->q_mount))))
|
||||
|
||||
#ifdef XFS_DQUOT_TRACE
|
||||
/*
|
||||
|
@ -310,9 +310,9 @@ xfs_qm_mount_quotainit(
|
||||
uint flags)
|
||||
{
|
||||
/*
|
||||
* User or group quotas has to be on.
|
||||
* User, projects or group quotas has to be on.
|
||||
*/
|
||||
ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA));
|
||||
ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
|
||||
|
||||
/*
|
||||
* Initialize the flags in the mount structure. From this point
|
||||
@ -330,7 +330,11 @@ xfs_qm_mount_quotainit(
|
||||
if (flags & XFSMNT_GQUOTA) {
|
||||
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
|
||||
if (flags & XFSMNT_GQUOTAENF)
|
||||
mp->m_qflags |= XFS_GQUOTA_ENFD;
|
||||
mp->m_qflags |= XFS_OQUOTA_ENFD;
|
||||
} else if (flags & XFSMNT_PQUOTA) {
|
||||
mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
|
||||
if (flags & XFSMNT_PQUOTAENF)
|
||||
mp->m_qflags |= XFS_OQUOTA_ENFD;
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,11 +367,11 @@ xfs_qm_mount_quotas(
|
||||
|
||||
/*
|
||||
* If a file system had quotas running earlier, but decided to
|
||||
* mount without -o quota/uquota/gquota options, revoke the
|
||||
* mount without -o uquota/pquota/gquota options, revoke the
|
||||
* quotachecked license, and bail out.
|
||||
*/
|
||||
if (! XFS_IS_QUOTA_ON(mp) &&
|
||||
(mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
|
||||
(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
|
||||
mp->m_qflags = 0;
|
||||
goto write_changes;
|
||||
}
|
||||
@ -619,7 +623,7 @@ xfs_qm_detach_gdquots(
|
||||
STATIC int
|
||||
xfs_qm_dqpurge_int(
|
||||
xfs_mount_t *mp,
|
||||
uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */
|
||||
uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */
|
||||
{
|
||||
xfs_dquot_t *dqp;
|
||||
uint dqtype;
|
||||
@ -631,6 +635,7 @@ xfs_qm_dqpurge_int(
|
||||
return (0);
|
||||
|
||||
dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
|
||||
dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0;
|
||||
dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
|
||||
|
||||
xfs_qm_mplist_lock(mp);
|
||||
@ -740,11 +745,11 @@ xfs_qm_dqattach_one(
|
||||
|
||||
/*
|
||||
* udqhint is the i_udquot field in inode, and is non-NULL only
|
||||
* when the type arg is XFS_DQ_GROUP. Its purpose is to save a
|
||||
* when the type arg is group/project. Its purpose is to save a
|
||||
* lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
|
||||
* the user dquot.
|
||||
*/
|
||||
ASSERT(!udqhint || type == XFS_DQ_GROUP);
|
||||
ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
|
||||
if (udqhint && !dolock)
|
||||
xfs_dqlock(udqhint);
|
||||
|
||||
@ -903,8 +908,8 @@ xfs_qm_dqattach_grouphint(
|
||||
|
||||
|
||||
/*
|
||||
* Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON
|
||||
* in to account.
|
||||
* Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
|
||||
* into account.
|
||||
* If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
|
||||
* If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
|
||||
* much made this code a complete mess, but it has been pretty useful.
|
||||
@ -943,8 +948,13 @@ xfs_qm_dqattach(
|
||||
nquotas++;
|
||||
}
|
||||
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
error = XFS_IS_GQUOTA_ON(mp) ?
|
||||
xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
|
||||
flags & XFS_QMOPT_DQALLOC,
|
||||
flags & XFS_QMOPT_DQLOCK,
|
||||
ip->i_udquot, &ip->i_gdquot) :
|
||||
xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
|
||||
flags & XFS_QMOPT_DQALLOC,
|
||||
flags & XFS_QMOPT_DQLOCK,
|
||||
ip->i_udquot, &ip->i_gdquot);
|
||||
@ -995,7 +1005,7 @@ xfs_qm_dqattach(
|
||||
}
|
||||
if (XFS_IS_UQUOTA_ON(mp))
|
||||
ASSERT(ip->i_udquot);
|
||||
if (XFS_IS_GQUOTA_ON(mp))
|
||||
if (XFS_IS_OQUOTA_ON(mp))
|
||||
ASSERT(ip->i_gdquot);
|
||||
}
|
||||
#endif
|
||||
@ -1024,13 +1034,13 @@ xfs_qm_dqdetach(
|
||||
|
||||
ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
|
||||
ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
|
||||
if (ip->i_udquot)
|
||||
xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
|
||||
if (ip->i_udquot) {
|
||||
xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
|
||||
xfs_qm_dqrele(ip->i_udquot);
|
||||
ip->i_udquot = NULL;
|
||||
}
|
||||
if (ip->i_gdquot) {
|
||||
xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip);
|
||||
xfs_qm_dqrele(ip->i_gdquot);
|
||||
ip->i_gdquot = NULL;
|
||||
}
|
||||
@ -1208,8 +1218,9 @@ xfs_qm_init_quotainfo(
|
||||
* and group quotas, at least not at this point.
|
||||
*/
|
||||
error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
|
||||
(XFS_IS_UQUOTA_RUNNING(mp)) ?
|
||||
XFS_DQ_USER : XFS_DQ_GROUP,
|
||||
XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
|
||||
(XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
|
||||
XFS_DQ_PROJ),
|
||||
XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
|
||||
&dqp);
|
||||
if (! error) {
|
||||
@ -1372,13 +1383,20 @@ xfs_qm_dqget_noattach(
|
||||
ASSERT(udqp);
|
||||
}
|
||||
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
ASSERT(ip->i_gdquot == NULL);
|
||||
if (udqp)
|
||||
xfs_dqunlock(udqp);
|
||||
if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP,
|
||||
XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
|
||||
&gdqp))) {
|
||||
error = XFS_IS_GQUOTA_ON(mp) ?
|
||||
xfs_qm_dqget(mp, ip,
|
||||
ip->i_d.di_gid, XFS_DQ_GROUP,
|
||||
XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
|
||||
&gdqp) :
|
||||
xfs_qm_dqget(mp, ip,
|
||||
ip->i_d.di_projid, XFS_DQ_PROJ,
|
||||
XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
|
||||
&gdqp);
|
||||
if (error) {
|
||||
if (udqp)
|
||||
xfs_qm_dqrele(udqp);
|
||||
ASSERT(error != ESRCH);
|
||||
@ -1547,11 +1565,14 @@ xfs_qm_dqiter_bufs(
|
||||
int error;
|
||||
int notcommitted;
|
||||
int incr;
|
||||
int type;
|
||||
|
||||
ASSERT(blkcnt > 0);
|
||||
notcommitted = 0;
|
||||
incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
|
||||
XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
|
||||
type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER :
|
||||
(flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP);
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
@ -1570,9 +1591,7 @@ xfs_qm_dqiter_bufs(
|
||||
if (error)
|
||||
break;
|
||||
|
||||
(void) xfs_qm_reset_dqcounts(mp, bp, firstid,
|
||||
flags & XFS_QMOPT_UQUOTA ?
|
||||
XFS_DQ_USER : XFS_DQ_GROUP);
|
||||
(void) xfs_qm_reset_dqcounts(mp, bp, firstid, type);
|
||||
xfs_bdwrite(mp, bp);
|
||||
/*
|
||||
* goto the next block.
|
||||
@ -1584,7 +1603,7 @@ xfs_qm_dqiter_bufs(
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over all allocated USR/GRP dquots in the system, calling a
|
||||
* Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a
|
||||
* caller supplied function for every chunk of dquots that we find.
|
||||
*/
|
||||
STATIC int
|
||||
@ -1855,7 +1874,7 @@ xfs_qm_dqusage_adjust(
|
||||
xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
|
||||
xfs_qm_dqput(udqp);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
ASSERT(gdqp);
|
||||
xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
|
||||
xfs_qm_dqput(gdqp);
|
||||
@ -1904,7 +1923,7 @@ xfs_qm_quotacheck(
|
||||
cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
|
||||
|
||||
/*
|
||||
* First we go thru all the dquots on disk, USR and GRP, and reset
|
||||
* First we go thru all the dquots on disk, USR and GRP/PRJ, and reset
|
||||
* their counters to zero. We need a clean slate.
|
||||
* We don't log our changes till later.
|
||||
*/
|
||||
@ -1915,9 +1934,10 @@ xfs_qm_quotacheck(
|
||||
}
|
||||
|
||||
if ((gip = XFS_QI_GQIP(mp))) {
|
||||
if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA)))
|
||||
if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
|
||||
XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA)))
|
||||
goto error_return;
|
||||
flags |= XFS_GQUOTA_CHKD;
|
||||
flags |= XFS_OQUOTA_CHKD;
|
||||
}
|
||||
|
||||
do {
|
||||
@ -1944,7 +1964,7 @@ xfs_qm_quotacheck(
|
||||
if (error) {
|
||||
xfs_qm_dqpurge_all(mp,
|
||||
XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
|
||||
XFS_QMOPT_QUOTAOFF);
|
||||
XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
|
||||
goto error_return;
|
||||
}
|
||||
/*
|
||||
@ -1967,7 +1987,7 @@ xfs_qm_quotacheck(
|
||||
* quotachecked status, since we won't be doing accounting for
|
||||
* that type anymore.
|
||||
*/
|
||||
mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD);
|
||||
mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
|
||||
mp->m_qflags |= flags;
|
||||
|
||||
XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
|
||||
@ -2019,7 +2039,7 @@ xfs_qm_init_quotainos(
|
||||
0, 0, &uip, 0)))
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp) &&
|
||||
if (XFS_IS_OQUOTA_ON(mp) &&
|
||||
mp->m_sb.sb_gquotino != NULLFSINO) {
|
||||
ASSERT(mp->m_sb.sb_gquotino > 0);
|
||||
if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
|
||||
@ -2049,10 +2069,12 @@ xfs_qm_init_quotainos(
|
||||
|
||||
flags &= ~XFS_QMOPT_SBVERSION;
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
|
||||
if ((error = xfs_qm_qino_alloc(mp, &gip,
|
||||
sbflags | XFS_SB_GQUOTINO,
|
||||
flags | XFS_QMOPT_GQUOTA))) {
|
||||
if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
|
||||
flags |= (XFS_IS_GQUOTA_ON(mp) ?
|
||||
XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
|
||||
error = xfs_qm_qino_alloc(mp, &gip,
|
||||
sbflags | XFS_SB_GQUOTINO, flags);
|
||||
if (error) {
|
||||
if (uip)
|
||||
VN_RELE(XFS_ITOV(uip));
|
||||
|
||||
@ -2458,6 +2480,7 @@ xfs_qm_vop_dqalloc(
|
||||
xfs_inode_t *ip,
|
||||
uid_t uid,
|
||||
gid_t gid,
|
||||
prid_t prid,
|
||||
uint flags,
|
||||
xfs_dquot_t **O_udqpp,
|
||||
xfs_dquot_t **O_gdqpp)
|
||||
@ -2489,8 +2512,7 @@ xfs_qm_vop_dqalloc(
|
||||
}
|
||||
|
||||
uq = gq = NULL;
|
||||
if ((flags & XFS_QMOPT_UQUOTA) &&
|
||||
XFS_IS_UQUOTA_ON(mp)) {
|
||||
if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
|
||||
if (ip->i_d.di_uid != uid) {
|
||||
/*
|
||||
* What we need is the dquot that has this uid, and
|
||||
@ -2528,8 +2550,7 @@ xfs_qm_vop_dqalloc(
|
||||
xfs_dqunlock(uq);
|
||||
}
|
||||
}
|
||||
if ((flags & XFS_QMOPT_GQUOTA) &&
|
||||
XFS_IS_GQUOTA_ON(mp)) {
|
||||
if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (ip->i_d.di_gid != gid) {
|
||||
xfs_iunlock(ip, lockflags);
|
||||
if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
|
||||
@ -2552,6 +2573,29 @@ xfs_qm_vop_dqalloc(
|
||||
XFS_DQHOLD(gq);
|
||||
xfs_dqunlock(gq);
|
||||
}
|
||||
} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
|
||||
if (ip->i_d.di_projid != prid) {
|
||||
xfs_iunlock(ip, lockflags);
|
||||
if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
|
||||
XFS_DQ_PROJ,
|
||||
XFS_QMOPT_DQALLOC |
|
||||
XFS_QMOPT_DOWARN,
|
||||
&gq))) {
|
||||
if (uq)
|
||||
xfs_qm_dqrele(uq);
|
||||
ASSERT(error != ENOENT);
|
||||
return (error);
|
||||
}
|
||||
xfs_dqunlock(gq);
|
||||
lockflags = XFS_ILOCK_SHARED;
|
||||
xfs_ilock(ip, lockflags);
|
||||
} else {
|
||||
ASSERT(ip->i_gdquot);
|
||||
gq = ip->i_gdquot;
|
||||
xfs_dqlock(gq);
|
||||
XFS_DQHOLD(gq);
|
||||
xfs_dqunlock(gq);
|
||||
}
|
||||
}
|
||||
if (uq)
|
||||
xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
|
||||
@ -2617,7 +2661,7 @@ xfs_qm_vop_chown(
|
||||
}
|
||||
|
||||
/*
|
||||
* Quota reservations for setattr(AT_UID|AT_GID).
|
||||
* Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID).
|
||||
*/
|
||||
int
|
||||
xfs_qm_vop_chown_reserve(
|
||||
@ -2652,12 +2696,16 @@ xfs_qm_vop_chown_reserve(
|
||||
unresudq = ip->i_udquot;
|
||||
}
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
|
||||
ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) {
|
||||
delblksgdq = gdqp;
|
||||
if (delblks) {
|
||||
ASSERT(ip->i_gdquot);
|
||||
unresgdq = ip->i_gdquot;
|
||||
if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
|
||||
if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
|
||||
INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
|
||||
(XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
|
||||
INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
|
||||
delblksgdq = gdqp;
|
||||
if (delblks) {
|
||||
ASSERT(ip->i_gdquot);
|
||||
unresgdq = ip->i_gdquot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -202,7 +202,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
|
||||
|
||||
/* vop stuff */
|
||||
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
|
||||
uid_t, gid_t, uint,
|
||||
uid_t, gid_t, prid_t, uint,
|
||||
xfs_dquot_t **, xfs_dquot_t **);
|
||||
extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
|
||||
xfs_trans_t *, xfs_inode_t *,
|
||||
|
@ -71,10 +71,13 @@
|
||||
#define MNTOPT_NOQUOTA "noquota" /* no quotas */
|
||||
#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
|
||||
#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
|
||||
#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
|
||||
#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
|
||||
#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
|
||||
#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
|
||||
#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
|
||||
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
|
||||
#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
|
||||
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
|
||||
|
||||
STATIC int
|
||||
@ -109,6 +112,14 @@ xfs_qm_parseargs(
|
||||
args->flags |= XFSMNT_UQUOTA;
|
||||
args->flags &= ~XFSMNT_UQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
|
||||
!strcmp(this_char, MNTOPT_PRJQUOTA)) {
|
||||
args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
|
||||
args->flags |= XFSMNT_PQUOTA;
|
||||
args->flags &= ~XFSMNT_PQUOTAENF;
|
||||
referenced = 1;
|
||||
} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
|
||||
!strcmp(this_char, MNTOPT_GRPQUOTA)) {
|
||||
args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
|
||||
@ -127,6 +138,12 @@ xfs_qm_parseargs(
|
||||
*this_char++ = ',';
|
||||
}
|
||||
|
||||
if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
|
||||
cmn_err(CE_WARN,
|
||||
"XFS: cannot mount with both project and group quota");
|
||||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
|
||||
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
|
||||
if (!error && !referenced)
|
||||
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
|
||||
@ -148,13 +165,19 @@ xfs_qm_showargs(
|
||||
seq_puts(m, "," MNTOPT_UQUOTANOENF);
|
||||
}
|
||||
|
||||
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
|
||||
(mp->m_qflags & XFS_OQUOTA_ENFD) ?
|
||||
seq_puts(m, "," MNTOPT_PRJQUOTA) :
|
||||
seq_puts(m, "," MNTOPT_PQUOTANOENF);
|
||||
}
|
||||
|
||||
if (mp->m_qflags & XFS_GQUOTA_ACCT) {
|
||||
(mp->m_qflags & XFS_GQUOTA_ENFD) ?
|
||||
(mp->m_qflags & XFS_OQUOTA_ENFD) ?
|
||||
seq_puts(m, "," MNTOPT_GRPQUOTA) :
|
||||
seq_puts(m, "," MNTOPT_GQUOTANOENF);
|
||||
}
|
||||
|
||||
if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT)))
|
||||
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
|
||||
seq_puts(m, "," MNTOPT_NOQUOTA);
|
||||
|
||||
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
|
||||
@ -171,7 +194,7 @@ xfs_qm_mount(
|
||||
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
|
||||
int error;
|
||||
|
||||
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
|
||||
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
|
||||
xfs_qm_mount_quotainit(mp, args->flags);
|
||||
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
|
||||
return error;
|
||||
@ -255,16 +278,17 @@ xfs_qm_newmount(
|
||||
uint *quotaflags)
|
||||
{
|
||||
uint quotaondisk;
|
||||
uint uquotaondisk = 0, gquotaondisk = 0;
|
||||
uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
|
||||
|
||||
*quotaflags = 0;
|
||||
*needquotamount = B_FALSE;
|
||||
|
||||
quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
|
||||
mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT);
|
||||
(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
|
||||
|
||||
if (quotaondisk) {
|
||||
uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
|
||||
pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
|
||||
gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
|
||||
}
|
||||
|
||||
@ -277,13 +301,16 @@ xfs_qm_newmount(
|
||||
|
||||
if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
|
||||
(!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
|
||||
(pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
|
||||
(!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) ||
|
||||
(gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
|
||||
(!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) &&
|
||||
(!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
|
||||
xfs_dev_is_read_only(mp, "changing quota state")) {
|
||||
cmn_err(CE_WARN,
|
||||
"XFS: please mount with%s%s%s.",
|
||||
"XFS: please mount with%s%s%s%s.",
|
||||
(!quotaondisk ? "out quota" : ""),
|
||||
(uquotaondisk ? " usrquota" : ""),
|
||||
(pquotaondisk ? " prjquota" : ""),
|
||||
(gquotaondisk ? " grpquota" : ""));
|
||||
return XFS_ERROR(EPERM);
|
||||
}
|
||||
|
@ -118,40 +118,41 @@ xfs_qm_quotactl(
|
||||
* The following commands are valid even when quotaoff.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case Q_XQUOTARM:
|
||||
/*
|
||||
* truncate quota files. quota must be off.
|
||||
* Truncate quota files. quota must be off.
|
||||
*/
|
||||
case Q_XQUOTARM:
|
||||
if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
|
||||
return XFS_ERROR(EINVAL);
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
return (xfs_qm_scall_trunc_qfiles(mp,
|
||||
xfs_qm_import_qtype_flags(*(uint *)addr)));
|
||||
|
||||
case Q_XGETQSTAT:
|
||||
/*
|
||||
* Get quota status information.
|
||||
*/
|
||||
case Q_XGETQSTAT:
|
||||
return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
|
||||
|
||||
case Q_XQUOTAON:
|
||||
/*
|
||||
* QUOTAON for root f/s and quota enforcement on others..
|
||||
* Quota accounting for non-root f/s's must be turned on
|
||||
* at mount time.
|
||||
* QUOTAON - enabling quota enforcement.
|
||||
* Quota accounting must be turned on at mount time.
|
||||
*/
|
||||
case Q_XQUOTAON:
|
||||
if (addr == NULL)
|
||||
return XFS_ERROR(EINVAL);
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
return (xfs_qm_scall_quotaon(mp,
|
||||
xfs_qm_import_flags(*(uint *)addr)));
|
||||
case Q_XQUOTAOFF:
|
||||
|
||||
case Q_XQUOTAOFF:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ xfs_qm_quotactl(
|
||||
return XFS_ERROR(ESRCH);
|
||||
|
||||
switch (cmd) {
|
||||
case Q_XQUOTAOFF:
|
||||
case Q_XQUOTAOFF:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_quotaoff(mp,
|
||||
@ -167,42 +168,39 @@ xfs_qm_quotactl(
|
||||
B_FALSE);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Defaults to XFS_GETUQUOTA.
|
||||
*/
|
||||
case Q_XGETQUOTA:
|
||||
case Q_XGETQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
/*
|
||||
* Set limits, both hard and soft. Defaults to Q_SETUQLIM.
|
||||
*/
|
||||
case Q_XSETQLIM:
|
||||
case Q_XGETGQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
case Q_XGETPQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
case Q_XSETQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
case Q_XSETGQLIM:
|
||||
case Q_XSETGQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
|
||||
case Q_XGETGQUOTA:
|
||||
error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
|
||||
(fs_disk_quota_t *)addr);
|
||||
case Q_XSETPQLIM:
|
||||
if (vfsp->vfs_flag & VFS_RDONLY)
|
||||
return XFS_ERROR(EROFS);
|
||||
error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
|
||||
(fs_disk_quota_t *)addr);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Quotas are entirely undefined after quotaoff in XFS quotas.
|
||||
* For instance, there's no way to set limits when quotaoff.
|
||||
*/
|
||||
|
||||
default:
|
||||
default:
|
||||
error = XFS_ERROR(EINVAL);
|
||||
break;
|
||||
}
|
||||
@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff(
|
||||
}
|
||||
if (flags & XFS_GQUOTA_ACCT) {
|
||||
dqtype |= XFS_QMOPT_GQUOTA;
|
||||
flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
|
||||
flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
|
||||
inactivate_flags |= XFS_GQUOTA_ACTIVE;
|
||||
} else if (flags & XFS_PQUOTA_ACCT) {
|
||||
dqtype |= XFS_QMOPT_PQUOTA;
|
||||
flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
|
||||
inactivate_flags |= XFS_PQUOTA_ACTIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff(
|
||||
/*
|
||||
* If quotas is completely disabled, close shop.
|
||||
*/
|
||||
if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) {
|
||||
if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
|
||||
((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
|
||||
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
|
||||
xfs_qm_destroy_quotainfo(mp);
|
||||
return (0);
|
||||
@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff(
|
||||
XFS_PURGE_INODE(XFS_QI_UQIP(mp));
|
||||
XFS_QI_UQIP(mp) = NULL;
|
||||
}
|
||||
if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) {
|
||||
if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
|
||||
XFS_PURGE_INODE(XFS_QI_GQIP(mp));
|
||||
XFS_QI_GQIP(mp) = NULL;
|
||||
}
|
||||
@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles(
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) {
|
||||
if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
|
||||
mp->m_sb.sb_gquotino != NULLFSINO) {
|
||||
error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
|
||||
if (! error) {
|
||||
(void) xfs_truncate_file(mp, qip);
|
||||
@ -434,7 +438,7 @@ xfs_qm_scall_quotaon(
|
||||
uint flags)
|
||||
{
|
||||
int error;
|
||||
unsigned long s;
|
||||
unsigned long s;
|
||||
uint qf;
|
||||
uint accflags;
|
||||
__int64_t sbflags;
|
||||
@ -468,9 +472,13 @@ xfs_qm_scall_quotaon(
|
||||
(mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_UQUOTA_ENFD))
|
||||
||
|
||||
((flags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_OQUOTA_ENFD))
|
||||
||
|
||||
((flags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
|
||||
(flags & XFS_GQUOTA_ENFD))) {
|
||||
(flags & XFS_OQUOTA_ENFD))) {
|
||||
qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
|
||||
flags, mp->m_sb.sb_qflags);
|
||||
return XFS_ERROR(EINVAL);
|
||||
@ -504,6 +512,10 @@ xfs_qm_scall_quotaon(
|
||||
*/
|
||||
if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_UQUOTA_ACCT)) ||
|
||||
((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_PQUOTA_ACCT)) ||
|
||||
((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
|
||||
(mp->m_qflags & XFS_GQUOTA_ACCT)) ||
|
||||
(flags & XFS_ALL_QUOTA_ENFD) == 0)
|
||||
return (0);
|
||||
|
||||
@ -521,7 +533,6 @@ xfs_qm_scall_quotaon(
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return quota status information, such as uquota-off, enforcements, etc.
|
||||
*/
|
||||
@ -776,9 +787,9 @@ xfs_qm_log_quotaoff_end(
|
||||
xfs_qoff_logitem_t *startqoff,
|
||||
uint flags)
|
||||
{
|
||||
xfs_trans_t *tp;
|
||||
xfs_trans_t *tp;
|
||||
int error;
|
||||
xfs_qoff_logitem_t *qoffi;
|
||||
xfs_qoff_logitem_t *qoffi;
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
|
||||
|
||||
@ -928,18 +939,26 @@ xfs_qm_export_dquot(
|
||||
|
||||
STATIC uint
|
||||
xfs_qm_import_qtype_flags(
|
||||
uint uflags)
|
||||
uint uflags)
|
||||
{
|
||||
uint oflags = 0;
|
||||
|
||||
/*
|
||||
* Can't be both at the same time.
|
||||
* Can't be more than one, or none.
|
||||
*/
|
||||
if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0))
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
|
||||
(XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
|
||||
((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
|
||||
(XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
|
||||
((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
|
||||
return (0);
|
||||
|
||||
return (uflags & XFS_USER_QUOTA) ?
|
||||
XFS_DQ_USER : XFS_DQ_GROUP;
|
||||
oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
|
||||
oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
|
||||
oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
|
||||
return oflags;
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
@ -947,14 +966,19 @@ xfs_qm_export_qtype_flags(
|
||||
uint flags)
|
||||
{
|
||||
/*
|
||||
* Can't be both at the same time.
|
||||
* Can't be more than one, or none.
|
||||
*/
|
||||
ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) !=
|
||||
(XFS_GROUP_QUOTA | XFS_USER_QUOTA));
|
||||
ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0);
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
|
||||
(XFS_PROJ_QUOTA | XFS_USER_QUOTA));
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
|
||||
(XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
|
||||
ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
|
||||
(XFS_USER_QUOTA | XFS_GROUP_QUOTA));
|
||||
ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
|
||||
|
||||
return (flags & XFS_DQ_USER) ?
|
||||
XFS_USER_QUOTA : XFS_GROUP_QUOTA;
|
||||
XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
|
||||
XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
@ -965,12 +989,14 @@ xfs_qm_import_flags(
|
||||
|
||||
if (uflags & XFS_QUOTA_UDQ_ACCT)
|
||||
flags |= XFS_UQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_PDQ_ACCT)
|
||||
flags |= XFS_PQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_GDQ_ACCT)
|
||||
flags |= XFS_GQUOTA_ACCT;
|
||||
if (uflags & XFS_QUOTA_UDQ_ENFD)
|
||||
flags |= XFS_UQUOTA_ENFD;
|
||||
if (uflags & XFS_QUOTA_GDQ_ENFD)
|
||||
flags |= XFS_GQUOTA_ENFD;
|
||||
if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
|
||||
flags |= XFS_OQUOTA_ENFD;
|
||||
return (flags);
|
||||
}
|
||||
|
||||
@ -984,12 +1010,16 @@ xfs_qm_export_flags(
|
||||
uflags = 0;
|
||||
if (flags & XFS_UQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_UDQ_ACCT;
|
||||
if (flags & XFS_PQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_PDQ_ACCT;
|
||||
if (flags & XFS_GQUOTA_ACCT)
|
||||
uflags |= XFS_QUOTA_GDQ_ACCT;
|
||||
if (flags & XFS_UQUOTA_ENFD)
|
||||
uflags |= XFS_QUOTA_UDQ_ENFD;
|
||||
if (flags & XFS_GQUOTA_ENFD)
|
||||
uflags |= XFS_QUOTA_GDQ_ENFD;
|
||||
if (flags & (XFS_OQUOTA_ENFD)) {
|
||||
uflags |= (flags & XFS_GQUOTA_ACCT) ?
|
||||
XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
|
||||
}
|
||||
return (uflags);
|
||||
}
|
||||
|
||||
@ -1070,7 +1100,7 @@ again:
|
||||
xfs_qm_dqrele(ip->i_udquot);
|
||||
ip->i_udquot = NULL;
|
||||
}
|
||||
if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
|
||||
if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
|
||||
xfs_qm_dqrele(ip->i_gdquot);
|
||||
ip->i_gdquot = NULL;
|
||||
}
|
||||
@ -1160,7 +1190,6 @@ xfs_qm_dqtest_print(
|
||||
{
|
||||
cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
|
||||
cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
|
||||
cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
|
||||
cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount);
|
||||
cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
|
||||
d->d_bcount, (int)d->d_bcount);
|
||||
@ -1231,7 +1260,7 @@ xfs_dqtest_cmp2(
|
||||
#ifdef QUOTADEBUG
|
||||
if (!err) {
|
||||
cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
|
||||
d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount);
|
||||
d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
|
||||
}
|
||||
#endif
|
||||
return (err);
|
||||
@ -1287,6 +1316,7 @@ STATIC void
|
||||
xfs_qm_internalqcheck_get_dquots(
|
||||
xfs_mount_t *mp,
|
||||
xfs_dqid_t uid,
|
||||
xfs_dqid_t projid,
|
||||
xfs_dqid_t gid,
|
||||
xfs_dqtest_t **ud,
|
||||
xfs_dqtest_t **gd)
|
||||
@ -1295,6 +1325,8 @@ xfs_qm_internalqcheck_get_dquots(
|
||||
xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
|
||||
if (XFS_IS_GQUOTA_ON(mp))
|
||||
xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
|
||||
else if (XFS_IS_PQUOTA_ON(mp))
|
||||
xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
|
||||
}
|
||||
|
||||
|
||||
@ -1362,13 +1394,14 @@ xfs_qm_internalqcheck_adjust(
|
||||
}
|
||||
xfs_qm_internalqcheck_get_dquots(mp,
|
||||
(xfs_dqid_t) ip->i_d.di_uid,
|
||||
(xfs_dqid_t) ip->i_d.di_projid,
|
||||
(xfs_dqid_t) ip->i_d.di_gid,
|
||||
&ud, &gd);
|
||||
if (XFS_IS_UQUOTA_ON(mp)) {
|
||||
ASSERT(ud);
|
||||
xfs_qm_internalqcheck_dqadjust(ip, ud);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
ASSERT(gd);
|
||||
xfs_qm_internalqcheck_dqadjust(ip, gd);
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
|
||||
(xfs_Gqm->qm_grp_dqhtable + \
|
||||
XFS_DQ_HASHVAL(mp, id)))
|
||||
#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \
|
||||
XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp))
|
||||
XFS_IS_UQUOTA_ON(mp) : \
|
||||
XFS_IS_OQUOTA_ON(mp))
|
||||
#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
|
||||
!dqp->q_core.d_blk_hardlimit && \
|
||||
!dqp->q_core.d_blk_softlimit && \
|
||||
@ -180,7 +181,8 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
|
||||
IRELE(ip);
|
||||
|
||||
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
|
||||
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???"))
|
||||
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
|
||||
(((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
|
||||
#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
|
||||
|
||||
#endif /* __XFS_QUOTA_PRIV_H__ */
|
||||
|
@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
|
||||
if (tp->t_dqinfo == NULL)
|
||||
xfs_trans_alloc_dqinfo(tp);
|
||||
|
||||
if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) {
|
||||
if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
|
||||
(void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
|
||||
if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
|
||||
(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC xfs_dqtrx_t *
|
||||
|
@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t {
|
||||
* user or group dquots and may require special recovery handling.
|
||||
*/
|
||||
#define XFS_BLI_UDQUOT_BUF 0x4
|
||||
/* #define XFS_BLI_PDQUOT_BUF 0x8 */
|
||||
#define XFS_BLI_PDQUOT_BUF 0x8
|
||||
#define XFS_BLI_GDQUOT_BUF 0x10
|
||||
|
||||
#define XFS_BLI_CHUNK 128
|
||||
|
@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer(
|
||||
* probably a good thing to do for other buf types also.
|
||||
*/
|
||||
error = 0;
|
||||
if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
|
||||
if (buf_f->blf_flags &
|
||||
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
|
||||
error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
|
||||
item->ri_buf[i].i_addr,
|
||||
-1, 0, XFS_QMOPT_DOWARN,
|
||||
@ -2030,6 +2031,7 @@ xfs_qm_dqcheck(
|
||||
}
|
||||
|
||||
if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
|
||||
INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
|
||||
INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
|
||||
if (flags & XFS_QMOPT_DOWARN)
|
||||
cmn_err(CE_ALERT,
|
||||
@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer(
|
||||
type = 0;
|
||||
if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
|
||||
type |= XFS_DQ_USER;
|
||||
if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
|
||||
type |= XFS_DQ_PROJ;
|
||||
if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
|
||||
type |= XFS_DQ_GROUP;
|
||||
/*
|
||||
@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans(
|
||||
error = 0;
|
||||
if (flags & XFS_BLI_INODE_BUF) {
|
||||
error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
|
||||
} else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) {
|
||||
} else if (flags &
|
||||
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
|
||||
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
|
||||
} else {
|
||||
xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
|
||||
@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans(
|
||||
* This type of quotas was turned off, so ignore this record.
|
||||
*/
|
||||
type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
|
||||
(XFS_DQ_USER | XFS_DQ_GROUP);
|
||||
(XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
|
||||
ASSERT(type);
|
||||
if (log->l_quotaoffs_flag & type)
|
||||
return (0);
|
||||
|
@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
|
||||
typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
|
||||
typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
|
||||
typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
|
||||
struct xfs_inode *, uid_t, gid_t, uint,
|
||||
struct xfs_inode *, uid_t, gid_t, prid_t, uint,
|
||||
struct xfs_dquot **, struct xfs_dquot **);
|
||||
typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
|
||||
struct xfs_dquot *, struct xfs_dquot *);
|
||||
@ -185,8 +185,8 @@ typedef struct xfs_qmops {
|
||||
(*(mp)->m_qm_ops.xfs_dqdetach)(ip)
|
||||
#define XFS_QM_DQPURGEALL(mp, fl) \
|
||||
(*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
|
||||
#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \
|
||||
(*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2)
|
||||
#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
|
||||
(*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
|
||||
#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
|
||||
(*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
|
||||
#define XFS_QM_DQVOPRENAME(mp, ip) \
|
||||
|
@ -96,7 +96,7 @@ typedef struct xfs_dqblk {
|
||||
* flags for q_flags field in the dquot.
|
||||
*/
|
||||
#define XFS_DQ_USER 0x0001 /* a user quota */
|
||||
/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */
|
||||
#define XFS_DQ_PROJ 0x0002 /* project quota */
|
||||
#define XFS_DQ_GROUP 0x0004 /* a group quota */
|
||||
#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
|
||||
#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
|
||||
@ -104,6 +104,8 @@ typedef struct xfs_dqblk {
|
||||
#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
|
||||
#define XFS_DQ_MARKER 0x0080 /* sentinel */
|
||||
|
||||
#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
|
||||
|
||||
/*
|
||||
* In the worst case, when both user and group quotas are on,
|
||||
* we can have a max of three dquots changing in a single transaction.
|
||||
@ -124,7 +126,7 @@ typedef struct xfs_dqblk {
|
||||
typedef struct xfs_dq_logformat {
|
||||
__uint16_t qlf_type; /* dquot log item type */
|
||||
__uint16_t qlf_size; /* size of this item */
|
||||
xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */
|
||||
xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
|
||||
__int64_t qlf_blkno; /* blkno of dquot buffer */
|
||||
__int32_t qlf_len; /* len of dquot buffer */
|
||||
__uint32_t qlf_boffset; /* off of dquot in buffer */
|
||||
@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat {
|
||||
#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
|
||||
#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
|
||||
#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
|
||||
#define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */
|
||||
#define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */
|
||||
#define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */
|
||||
#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
|
||||
#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
|
||||
#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
|
||||
#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
|
||||
|
||||
/*
|
||||
@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat {
|
||||
* are in the process of getting turned off. These flags are in m_qflags but
|
||||
* never in sb_qflags.
|
||||
*/
|
||||
#define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */
|
||||
#define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas are being turned off */
|
||||
#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
|
||||
#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
|
||||
#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
|
||||
|
||||
/*
|
||||
* Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
|
||||
* quota will be not be switched off as long as that inode lock is held.
|
||||
*/
|
||||
#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
|
||||
XFS_GQUOTA_ACTIVE))
|
||||
XFS_GQUOTA_ACTIVE | \
|
||||
XFS_PQUOTA_ACTIVE))
|
||||
#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
|
||||
XFS_PQUOTA_ACTIVE))
|
||||
#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
|
||||
#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
|
||||
#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
|
||||
|
||||
/*
|
||||
* Flags to tell various functions what to do. Not all of these are meaningful
|
||||
@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat {
|
||||
#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
|
||||
#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
|
||||
#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
|
||||
#define XFS_QMOPT_GQUOTA 0x0000008 /* group dquot requested */
|
||||
#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
|
||||
#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
|
||||
#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */
|
||||
#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
|
||||
@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat {
|
||||
#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */
|
||||
#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
|
||||
#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */
|
||||
#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
|
||||
|
||||
/*
|
||||
* flags to xfs_trans_mod_dquot to indicate which field needs to be
|
||||
@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat {
|
||||
#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
|
||||
|
||||
|
||||
#define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA)
|
||||
#define XFS_QMOPT_QUOTALL \
|
||||
(XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
|
||||
#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat {
|
||||
*/
|
||||
#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
|
||||
(ip)->i_udquot == NULL) || \
|
||||
(XFS_IS_GQUOTA_ON(mp) && \
|
||||
(XFS_IS_OQUOTA_ON(mp) && \
|
||||
(ip)->i_gdquot == NULL))
|
||||
|
||||
#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \
|
||||
(mp->m_sb.sb_qflags & \
|
||||
XFS_UQUOTA_CHKD) == 0) || \
|
||||
(XFS_IS_GQUOTA_ON(mp) && \
|
||||
(mp->m_sb.sb_qflags & \
|
||||
XFS_GQUOTA_CHKD) == 0))
|
||||
#define XFS_QM_NEED_QUOTACHECK(mp) \
|
||||
((XFS_IS_UQUOTA_ON(mp) && \
|
||||
(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
|
||||
(XFS_IS_GQUOTA_ON(mp) && \
|
||||
((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
|
||||
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
|
||||
(XFS_IS_PQUOTA_ON(mp) && \
|
||||
((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
|
||||
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
|
||||
|
||||
#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
|
||||
XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
|
||||
XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
|
||||
|
||||
#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
|
||||
XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
|
||||
XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
|
||||
|
||||
#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
|
||||
XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
|
||||
XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)
|
||||
XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
|
||||
XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
|
||||
XFS_GQUOTA_ACCT)
|
||||
#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
|
||||
XFS_GQUOTA_ACTIVE)
|
||||
XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -976,6 +976,7 @@ xfs_trans_dquot_buf(
|
||||
ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
|
||||
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
|
||||
ASSERT(type == XFS_BLI_UDQUOT_BUF ||
|
||||
type == XFS_BLI_PDQUOT_BUF ||
|
||||
type == XFS_BLI_GDQUOT_BUF);
|
||||
|
||||
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
|
||||
|
@ -428,7 +428,7 @@ xfs_truncate_file(
|
||||
if (ip->i_ino != mp->m_sb.sb_uquotino)
|
||||
ASSERT(ip->i_udquot);
|
||||
}
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
if (XFS_IS_OQUOTA_ON(mp)) {
|
||||
if (ip->i_ino != mp->m_sb.sb_gquotino)
|
||||
ASSERT(ip->i_gdquot);
|
||||
}
|
||||
|
@ -367,16 +367,6 @@ xfs_finish_flags(
|
||||
return XFS_ERROR(EROFS);
|
||||
}
|
||||
|
||||
/*
|
||||
* disallow mount attempts with (IRIX) project quota enabled
|
||||
*/
|
||||
if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
|
||||
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
|
||||
cmn_err(CE_WARN,
|
||||
"XFS: cannot mount a filesystem with IRIX project quota enabled");
|
||||
return XFS_ERROR(ENOSYS);
|
||||
}
|
||||
|
||||
/*
|
||||
* check for shared mount.
|
||||
*/
|
||||
|
@ -351,21 +351,28 @@ xfs_setattr(
|
||||
* If the IDs do change before we take the ilock, we're covered
|
||||
* because the i_*dquot fields will get updated anyway.
|
||||
*/
|
||||
if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) {
|
||||
if (XFS_IS_QUOTA_ON(mp) &&
|
||||
(mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
|
||||
uint qflags = 0;
|
||||
|
||||
if (mask & XFS_AT_UID) {
|
||||
if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
|
||||
uid = vap->va_uid;
|
||||
qflags |= XFS_QMOPT_UQUOTA;
|
||||
} else {
|
||||
uid = ip->i_d.di_uid;
|
||||
}
|
||||
if (mask & XFS_AT_GID) {
|
||||
if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
|
||||
gid = vap->va_gid;
|
||||
qflags |= XFS_QMOPT_GQUOTA;
|
||||
} else {
|
||||
gid = ip->i_d.di_gid;
|
||||
}
|
||||
if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
|
||||
projid = vap->va_projid;
|
||||
qflags |= XFS_QMOPT_PQUOTA;
|
||||
} else {
|
||||
projid = ip->i_d.di_projid;
|
||||
}
|
||||
/*
|
||||
* We take a reference when we initialize udqp and gdqp,
|
||||
* so it is important that we never blindly double trip on
|
||||
@ -373,7 +380,8 @@ xfs_setattr(
|
||||
*/
|
||||
ASSERT(udqp == NULL);
|
||||
ASSERT(gdqp == NULL);
|
||||
code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp);
|
||||
code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
|
||||
&udqp, &gdqp);
|
||||
if (code)
|
||||
return (code);
|
||||
}
|
||||
@ -510,10 +518,11 @@ xfs_setattr(
|
||||
goto error_return;
|
||||
}
|
||||
/*
|
||||
* Do a quota reservation only if uid or gid is actually
|
||||
* Do a quota reservation only if uid/projid/gid is actually
|
||||
* going to change.
|
||||
*/
|
||||
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
|
||||
(XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
|
||||
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
|
||||
ASSERT(tp);
|
||||
code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
|
||||
@ -774,6 +783,7 @@ xfs_setattr(
|
||||
}
|
||||
if (igid != gid) {
|
||||
if (XFS_IS_GQUOTA_ON(mp)) {
|
||||
ASSERT(!XFS_IS_PQUOTA_ON(mp));
|
||||
ASSERT(mask & XFS_AT_GID);
|
||||
ASSERT(gdqp);
|
||||
olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
|
||||
@ -782,6 +792,13 @@ xfs_setattr(
|
||||
ip->i_d.di_gid = gid;
|
||||
}
|
||||
if (iprojid != projid) {
|
||||
if (XFS_IS_PQUOTA_ON(mp)) {
|
||||
ASSERT(!XFS_IS_GQUOTA_ON(mp));
|
||||
ASSERT(mask & XFS_AT_PROJID);
|
||||
ASSERT(gdqp);
|
||||
olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
|
||||
&ip->i_gdquot, gdqp);
|
||||
}
|
||||
ip->i_d.di_projid = projid;
|
||||
/*
|
||||
* We may have to rev the inode as well as
|
||||
@ -1907,7 +1924,7 @@ xfs_create(
|
||||
* Make sure that we have allocated dquot(s) on disk.
|
||||
*/
|
||||
error = XFS_QM_DQVOPALLOC(mp, dp,
|
||||
current_fsuid(credp), current_fsgid(credp),
|
||||
current_fsuid(credp), current_fsgid(credp), prid,
|
||||
XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
|
||||
if (error)
|
||||
goto std_return;
|
||||
@ -2812,7 +2829,7 @@ xfs_mkdir(
|
||||
* Make sure that we have allocated dquot(s) on disk.
|
||||
*/
|
||||
error = XFS_QM_DQVOPALLOC(mp, dp,
|
||||
current_fsuid(credp), current_fsgid(credp),
|
||||
current_fsuid(credp), current_fsgid(credp), prid,
|
||||
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
|
||||
if (error)
|
||||
goto std_return;
|
||||
@ -3366,7 +3383,7 @@ xfs_symlink(
|
||||
* Make sure that we have allocated dquot(s) on disk.
|
||||
*/
|
||||
error = XFS_QM_DQVOPALLOC(mp, dp,
|
||||
current_fsuid(credp), current_fsgid(credp),
|
||||
current_fsuid(credp), current_fsgid(credp), prid,
|
||||
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
|
||||
if (error)
|
||||
goto std_return;
|
||||
|
Loading…
Reference in New Issue
Block a user