Commit c8ad20ff authored by Nathan Scott's avatar Nathan Scott

[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: default avatarNathan Scott <nathans@sgi.com>
parent 8401e963
...@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) ...@@ -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 * field (see the QCMD macro in quota.h). These macros help keep the
* code portable - they are not visible from the syscall interface. * code portable - they are not visible from the syscall interface.
*/ */
#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ #define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
#define Q_XGETGQUOTA XQM_CMD(0x9) /* get 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) */ /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
/* we may well need to fine-tune this if it ever becomes an issue. */ /* we may well need to fine-tune this if it ever becomes an issue. */
......
...@@ -701,7 +701,8 @@ linvfs_getxquota( ...@@ -701,7 +701,8 @@ linvfs_getxquota(
struct vfs *vfsp = LINVFS_GET_VFS(sb); struct vfs *vfsp = LINVFS_GET_VFS(sb);
int error, getmode; 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); VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
return -error; return -error;
} }
...@@ -716,7 +717,8 @@ linvfs_setxquota( ...@@ -716,7 +717,8 @@ linvfs_setxquota(
struct vfs *vfsp = LINVFS_GET_VFS(sb); struct vfs *vfsp = LINVFS_GET_VFS(sb);
int error, setmode; 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); VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
return -error; return -error;
} }
......
...@@ -399,9 +399,9 @@ xfs_qm_init_dquot_blk( ...@@ -399,9 +399,9 @@ xfs_qm_init_dquot_blk(
for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
xfs_qm_dqinit_core(curid, type, d); xfs_qm_dqinit_core(curid, type, d);
xfs_trans_dquot_buf(tp, bp, xfs_trans_dquot_buf(tp, bp,
type & XFS_DQ_USER ? (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
XFS_BLI_UDQUOT_BUF : ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
XFS_BLI_GDQUOT_BUF); XFS_BLI_GDQUOT_BUF)));
xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
} }
...@@ -482,8 +482,7 @@ xfs_qm_dqalloc( ...@@ -482,8 +482,7 @@ xfs_qm_dqalloc(
* the entire thing. * the entire thing.
*/ */
xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), 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), dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
bp);
if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
goto error1; goto error1;
...@@ -613,8 +612,7 @@ xfs_qm_dqtobp( ...@@ -613,8 +612,7 @@ xfs_qm_dqtobp(
/* /*
* A simple sanity check in case we got a corrupted dquot... * A simple sanity check in case we got a corrupted dquot...
*/ */
if (xfs_qm_dqcheck(ddq, id, if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
"dqtobp")) { "dqtobp")) {
if (!(flags & XFS_QMOPT_DQREPAIR)) { if (!(flags & XFS_QMOPT_DQREPAIR)) {
...@@ -891,8 +889,8 @@ int ...@@ -891,8 +889,8 @@ int
xfs_qm_dqget( xfs_qm_dqget(
xfs_mount_t *mp, xfs_mount_t *mp,
xfs_inode_t *ip, /* locked inode (optional) */ xfs_inode_t *ip, /* locked inode (optional) */
xfs_dqid_t id, /* gid or uid, depending on type */ xfs_dqid_t id, /* uid/projid/gid depending on type */
uint type, /* UDQUOT or GDQUOT */ uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
{ {
...@@ -903,7 +901,9 @@ xfs_qm_dqget( ...@@ -903,7 +901,9 @@ xfs_qm_dqget(
ASSERT(XFS_IS_QUOTA_RUNNING(mp)); ASSERT(XFS_IS_QUOTA_RUNNING(mp));
if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || 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)) { (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
printk("XQM: ESRCH1\n");
return (ESRCH); return (ESRCH);
} }
h = XFS_DQ_HASH(mp, id, type); h = XFS_DQ_HASH(mp, id, type);
...@@ -921,7 +921,9 @@ xfs_qm_dqget( ...@@ -921,7 +921,9 @@ xfs_qm_dqget(
again: again:
#ifdef DEBUG #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) { if (ip) {
ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
if (type == XFS_DQ_USER) if (type == XFS_DQ_USER)
...@@ -979,6 +981,7 @@ xfs_qm_dqget( ...@@ -979,6 +981,7 @@ xfs_qm_dqget(
&dqp))) { &dqp))) {
if (ip) if (ip)
xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_ilock(ip, XFS_ILOCK_EXCL);
if (error == ESRCH) printk("XQM: ESRCH2\n");
return (error); return (error);
} }
...@@ -1004,6 +1007,7 @@ xfs_qm_dqget( ...@@ -1004,6 +1007,7 @@ xfs_qm_dqget(
if (! XFS_IS_DQTYPE_ON(mp, type)) { if (! XFS_IS_DQTYPE_ON(mp, type)) {
/* inode stays locked on return */ /* inode stays locked on return */
xfs_qm_dqdestroy(dqp); xfs_qm_dqdestroy(dqp);
printk("XQM: ESRCH3\n");
return XFS_ERROR(ESRCH); return XFS_ERROR(ESRCH);
} }
/* /*
...@@ -1244,8 +1248,8 @@ xfs_qm_dqflush( ...@@ -1244,8 +1248,8 @@ xfs_qm_dqflush(
return (error); return (error);
} }
if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
"dqflush (incore copy)")) { 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
...@@ -1397,7 +1401,8 @@ xfs_dqlock2( ...@@ -1397,7 +1401,8 @@ xfs_dqlock2(
{ {
if (d1 && d2) { if (d1 && d2) {
ASSERT(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(d2);
xfs_dqlock(d1); xfs_dqlock(d1);
} else { } else {
...@@ -1520,8 +1525,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp) ...@@ -1520,8 +1525,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
cmn_err(CE_DEBUG, "---- dquotID = %d", cmn_err(CE_DEBUG, "---- dquotID = %d",
(int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
cmn_err(CE_DEBUG, "---- type = %s", cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); 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, "---- blkno = 0x%x", (int) dqp->q_blkno);
cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
......
...@@ -114,25 +114,18 @@ typedef struct xfs_dquot { ...@@ -114,25 +114,18 @@ typedef struct xfs_dquot {
#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) #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_ACCT \
#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) #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_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) #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_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) #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 #ifdef DEBUG
static inline int static inline int
...@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) ...@@ -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_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) #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_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_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
...@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) ...@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
(XFS_IS_UQUOTA_ON((d)->q_mount)) : \ (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 #ifdef XFS_DQUOT_TRACE
/* /*
......
This diff is collapsed.
/* /*
* 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 * 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 * 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); ...@@ -202,7 +202,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
/* vop stuff */ /* vop stuff */
extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, 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 **); xfs_dquot_t **, xfs_dquot_t **);
extern void xfs_qm_vop_dqattach_and_dqmod_newinode( extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
xfs_trans_t *, xfs_inode_t *, xfs_trans_t *, xfs_inode_t *,
......
...@@ -71,10 +71,13 @@ ...@@ -71,10 +71,13 @@
#define MNTOPT_NOQUOTA "noquota" /* no quotas */ #define MNTOPT_NOQUOTA "noquota" /* no quotas */
#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
#define MNTOPT_GRPQUOTA "grpquota" /* group 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_UQUOTA "uquota" /* user quota (IRIX variant) */
#define MNTOPT_GQUOTA "gquota" /* group 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_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group 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 */ #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
STATIC int STATIC int
...@@ -109,6 +112,14 @@ xfs_qm_parseargs( ...@@ -109,6 +112,14 @@ xfs_qm_parseargs(
args->flags |= XFSMNT_UQUOTA; args->flags |= XFSMNT_UQUOTA;
args->flags &= ~XFSMNT_UQUOTAENF; args->flags &= ~XFSMNT_UQUOTAENF;
referenced = 1; 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) || } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
!strcmp(this_char, MNTOPT_GRPQUOTA)) { !strcmp(this_char, MNTOPT_GRPQUOTA)) {
args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
...@@ -127,6 +138,12 @@ xfs_qm_parseargs( ...@@ -127,6 +138,12 @@ xfs_qm_parseargs(
*this_char++ = ','; *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); PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
if (!error && !referenced) if (!error && !referenced)
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
...@@ -148,13 +165,19 @@ xfs_qm_showargs( ...@@ -148,13 +165,19 @@ xfs_qm_showargs(
seq_puts(m, "," MNTOPT_UQUOTANOENF); 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) { 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_GRPQUOTA) :
seq_puts(m, "," MNTOPT_GQUOTANOENF); 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); seq_puts(m, "," MNTOPT_NOQUOTA);
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
...@@ -171,7 +194,7 @@ xfs_qm_mount( ...@@ -171,7 +194,7 @@ xfs_qm_mount(
struct xfs_mount *mp = XFS_VFSTOM(vfsp); struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error; 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); xfs_qm_mount_quotainit(mp, args->flags);
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
return error; return error;
...@@ -255,16 +278,17 @@ xfs_qm_newmount( ...@@ -255,16 +278,17 @@ xfs_qm_newmount(
uint *quotaflags) uint *quotaflags)
{ {
uint quotaondisk; uint quotaondisk;
uint uquotaondisk = 0, gquotaondisk = 0; uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
*quotaflags = 0; *quotaflags = 0;
*needquotamount = B_FALSE; *needquotamount = B_FALSE;
quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && 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) { if (quotaondisk) {
uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; 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; gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
} }
...@@ -277,13 +301,16 @@ xfs_qm_newmount( ...@@ -277,13 +301,16 @@ xfs_qm_newmount(
if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
(!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_GQUOTA_ON(mp))) && (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
xfs_dev_is_read_only(mp, "changing quota state")) { xfs_dev_is_read_only(mp, "changing quota state")) {
cmn_err(CE_WARN, cmn_err(CE_WARN,
"XFS: please mount with%s%s%s.", "XFS: please mount with%s%s%s%s.",
(!quotaondisk ? "out quota" : ""), (!quotaondisk ? "out quota" : ""),
(uquotaondisk ? " usrquota" : ""), (uquotaondisk ? " usrquota" : ""),
(pquotaondisk ? " prjquota" : ""),
(gquotaondisk ? " grpquota" : "")); (gquotaondisk ? " grpquota" : ""));
return XFS_ERROR(EPERM); return XFS_ERROR(EPERM);
} }
......
This diff is collapsed.
...@@ -102,7 +102,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) ...@@ -102,7 +102,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
(xfs_Gqm->qm_grp_dqhtable + \ (xfs_Gqm->qm_grp_dqhtable + \
XFS_DQ_HASHVAL(mp, id))) XFS_DQ_HASHVAL(mp, id)))
#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ #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) ( \ #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
!dqp->q_core.d_blk_hardlimit && \ !dqp->q_core.d_blk_hardlimit && \
!dqp->q_core.d_blk_softlimit && \ !dqp->q_core.d_blk_softlimit && \
...@@ -180,7 +181,8 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ ...@@ -180,7 +181,8 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
IRELE(ip); IRELE(ip);
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ #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") #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
#endif /* __XFS_QUOTA_PRIV_H__ */ #endif /* __XFS_QUOTA_PRIV_H__ */
...@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino( ...@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
if (tp->t_dqinfo == NULL) if (tp->t_dqinfo == NULL)
xfs_trans_alloc_dqinfo(tp); 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); (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
} if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
}
} }
STATIC xfs_dqtrx_t * STATIC xfs_dqtrx_t *
......
...@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t { ...@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t {
* user or group dquots and may require special recovery handling. * user or group dquots and may require special recovery handling.
*/ */
#define XFS_BLI_UDQUOT_BUF 0x4 #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_GDQUOT_BUF 0x10
#define XFS_BLI_CHUNK 128 #define XFS_BLI_CHUNK 128
......
...@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer( ...@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer(
* probably a good thing to do for other buf types also. * probably a good thing to do for other buf types also.
*/ */
error = 0; 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 *) error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
item->ri_buf[i].i_addr, item->ri_buf[i].i_addr,
-1, 0, XFS_QMOPT_DOWARN, -1, 0, XFS_QMOPT_DOWARN,
...@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck( ...@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck(
} }
if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && 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) { INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
if (flags & XFS_QMOPT_DOWARN) if (flags & XFS_QMOPT_DOWARN)
cmn_err(CE_ALERT, cmn_err(CE_ALERT,
...@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer( ...@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer(
type = 0; type = 0;
if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
type |= XFS_DQ_USER; 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) if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
type |= XFS_DQ_GROUP; type |= XFS_DQ_GROUP;
/* /*
...@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans( ...@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans(
error = 0; error = 0;
if (flags & XFS_BLI_INODE_BUF) { if (flags & XFS_BLI_INODE_BUF) {
error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); 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); xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
} else { } else {
xlog_recover_do_reg_buffer(mp, item, bp, buf_f); xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
...@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans( ...@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans(
* This type of quotas was turned off, so ignore this record. * This type of quotas was turned off, so ignore this record.
*/ */
type = INT_GET(recddq->d_flags, ARCH_CONVERT) & 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); ASSERT(type);
if (log->l_quotaoffs_flag & type) if (log->l_quotaoffs_flag & type)
return (0); return (0);
......
...@@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); ...@@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
typedef void (*xfs_dqdetach_t)(struct xfs_inode *); typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, 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 **); struct xfs_dquot **, struct xfs_dquot **);
typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
struct xfs_dquot *, struct xfs_dquot *); struct xfs_dquot *, struct xfs_dquot *);
...@@ -185,8 +185,8 @@ typedef struct xfs_qmops { ...@@ -185,8 +185,8 @@ typedef struct xfs_qmops {
(*(mp)->m_qm_ops.xfs_dqdetach)(ip) (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
#define XFS_QM_DQPURGEALL(mp, fl) \ #define XFS_QM_DQPURGEALL(mp, fl) \
(*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
#define XFS_QM_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, 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) \ #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
(*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
#define XFS_QM_DQVOPRENAME(mp, ip) \ #define XFS_QM_DQVOPRENAME(mp, ip) \
......
...@@ -96,7 +96,7 @@ typedef struct xfs_dqblk { ...@@ -96,7 +96,7 @@ typedef struct xfs_dqblk {
* flags for q_flags field in the dquot. * flags for q_flags field in the dquot.
*/ */
#define XFS_DQ_USER 0x0001 /* a user quota */ #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_GROUP 0x0004 /* a group quota */
#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ #define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ #define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
...@@ -104,6 +104,8 @@ typedef struct xfs_dqblk { ...@@ -104,6 +104,8 @@ typedef struct xfs_dqblk {
#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ #define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
#define XFS_DQ_MARKER 0x0080 /* sentinel */ #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, * 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. * we can have a max of three dquots changing in a single transaction.
...@@ -124,7 +126,7 @@ typedef struct xfs_dqblk { ...@@ -124,7 +126,7 @@ typedef struct xfs_dqblk {
typedef struct xfs_dq_logformat { typedef struct xfs_dq_logformat {
__uint16_t qlf_type; /* dquot log item type */ __uint16_t qlf_type; /* dquot log item type */
__uint16_t qlf_size; /* size of this item */ __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 */ __int64_t qlf_blkno; /* blkno of dquot buffer */
__int32_t qlf_len; /* len of dquot buffer */ __int32_t qlf_len; /* len of dquot buffer */
__uint32_t qlf_boffset; /* off of dquot in buffer */ __uint32_t qlf_boffset; /* off of dquot in buffer */
...@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat { ...@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat {
#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ #define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ #define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ #define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
#define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */ #define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
#define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */ #define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
#define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */ #define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
/* /*
...@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat { ...@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat {
* are in the process of getting turned off. These flags are in m_qflags but * are in the process of getting turned off. These flags are in m_qflags but
* never in sb_qflags. * never in sb_qflags.
*/ */
#define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */ #define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
#define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas 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 * 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. * 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 | \ #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_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_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 * Flags to tell various functions what to do. Not all of these are meaningful
...@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat { ...@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat {
#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ #define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ #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_FORCE_RES 0x0000010 /* ignore quota limits */
#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ #define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */
#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ #define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
...@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat { ...@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat {
#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */
#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ #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 */
/* /*
* flags to xfs_trans_mod_dquot to indicate which field needs to be * flags to xfs_trans_mod_dquot to indicate which field needs to be
...@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat { ...@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat {
#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT #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) #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat { ...@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat {
*/ */
#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
(ip)->i_udquot == NULL) || \ (ip)->i_udquot == NULL) || \
(XFS_IS_GQUOTA_ON(mp) && \ (XFS_IS_OQUOTA_ON(mp) && \
(ip)->i_gdquot == NULL)) (ip)->i_gdquot == NULL))
#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \ #define XFS_QM_NEED_QUOTACHECK(mp) \
(mp->m_sb.sb_qflags & \ ((XFS_IS_UQUOTA_ON(mp) && \
XFS_UQUOTA_CHKD) == 0) || \ (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
(XFS_IS_GQUOTA_ON(mp) && \ (XFS_IS_GQUOTA_ON(mp) && \
(mp->m_sb.sb_qflags & \ ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
XFS_GQUOTA_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|\ #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD) XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
XFS_GQUOTA_ACCT)
#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ #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( ...@@ -976,6 +976,7 @@ xfs_trans_dquot_buf(
ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
ASSERT(type == XFS_BLI_UDQUOT_BUF || ASSERT(type == XFS_BLI_UDQUOT_BUF ||
type == XFS_BLI_PDQUOT_BUF ||
type == XFS_BLI_GDQUOT_BUF); type == XFS_BLI_GDQUOT_BUF);
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
......
...@@ -428,7 +428,7 @@ xfs_truncate_file( ...@@ -428,7 +428,7 @@ xfs_truncate_file(
if (ip->i_ino != mp->m_sb.sb_uquotino) if (ip->i_ino != mp->m_sb.sb_uquotino)
ASSERT(ip->i_udquot); 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) if (ip->i_ino != mp->m_sb.sb_gquotino)
ASSERT(ip->i_gdquot); ASSERT(ip->i_gdquot);
} }
......
...@@ -367,16 +367,6 @@ xfs_finish_flags( ...@@ -367,16 +367,6 @@ xfs_finish_flags(
return XFS_ERROR(EROFS); 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. * check for shared mount.
*/ */
......
...@@ -351,21 +351,28 @@ xfs_setattr( ...@@ -351,21 +351,28 @@ xfs_setattr(
* If the IDs do change before we take the ilock, we're covered * If the IDs do change before we take the ilock, we're covered
* because the i_*dquot fields will get updated anyway. * 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; uint qflags = 0;
if (mask & XFS_AT_UID) { if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
uid = vap->va_uid; uid = vap->va_uid;
qflags |= XFS_QMOPT_UQUOTA; qflags |= XFS_QMOPT_UQUOTA;
} else { } else {
uid = ip->i_d.di_uid; 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; gid = vap->va_gid;
qflags |= XFS_QMOPT_GQUOTA; qflags |= XFS_QMOPT_GQUOTA;
} else { } else {
gid = ip->i_d.di_gid; 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, * We take a reference when we initialize udqp and gdqp,
* so it is important that we never blindly double trip on * so it is important that we never blindly double trip on
...@@ -373,7 +380,8 @@ xfs_setattr( ...@@ -373,7 +380,8 @@ xfs_setattr(
*/ */
ASSERT(udqp == NULL); ASSERT(udqp == NULL);
ASSERT(gdqp == 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) if (code)
return (code); return (code);
} }
...@@ -510,10 +518,11 @@ xfs_setattr( ...@@ -510,10 +518,11 @@ xfs_setattr(
goto error_return; 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. * going to change.
*/ */
if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
(XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
(XFS_IS_GQUOTA_ON(mp) && igid != gid)) { (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
ASSERT(tp); ASSERT(tp);
code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
...@@ -774,6 +783,7 @@ xfs_setattr( ...@@ -774,6 +783,7 @@ xfs_setattr(
} }
if (igid != gid) { if (igid != gid) {
if (XFS_IS_GQUOTA_ON(mp)) { if (XFS_IS_GQUOTA_ON(mp)) {
ASSERT(!XFS_IS_PQUOTA_ON(mp));
ASSERT(mask & XFS_AT_GID); ASSERT(mask & XFS_AT_GID);
ASSERT(gdqp); ASSERT(gdqp);
olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
...@@ -782,6 +792,13 @@ xfs_setattr( ...@@ -782,6 +792,13 @@ xfs_setattr(
ip->i_d.di_gid = gid; ip->i_d.di_gid = gid;
} }
if (iprojid != projid) { 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; ip->i_d.di_projid = projid;
/* /*
* We may have to rev the inode as well as * We may have to rev the inode as well as
...@@ -1907,7 +1924,7 @@ xfs_create( ...@@ -1907,7 +1924,7 @@ xfs_create(
* Make sure that we have allocated dquot(s) on disk. * Make sure that we have allocated dquot(s) on disk.
*/ */
error = XFS_QM_DQVOPALLOC(mp, dp, 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); XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error) if (error)
goto std_return; goto std_return;
...@@ -2812,7 +2829,7 @@ xfs_mkdir( ...@@ -2812,7 +2829,7 @@ xfs_mkdir(
* Make sure that we have allocated dquot(s) on disk. * Make sure that we have allocated dquot(s) on disk.
*/ */
error = XFS_QM_DQVOPALLOC(mp, dp, 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); XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error) if (error)
goto std_return; goto std_return;
...@@ -3366,7 +3383,7 @@ xfs_symlink( ...@@ -3366,7 +3383,7 @@ xfs_symlink(
* Make sure that we have allocated dquot(s) on disk. * Make sure that we have allocated dquot(s) on disk.
*/ */
error = XFS_QM_DQVOPALLOC(mp, dp, 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); XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
if (error) if (error)
goto std_return; goto std_return;
......
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