diff options
author | Nathan Scott <nathans@sgi.com> | 2005-06-21 01:38:48 -0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-06-21 01:38:48 -0400 |
commit | c8ad20ffeb592d66ea869c57f8c525a9d727c67b (patch) | |
tree | 3306edfe984170bc881a1d7fbeab29b4b59f0305 | |
parent | 8401e9631c26dca9ebbc6997ac445fd49b06c79e (diff) |
[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>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_linux.h | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 34 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.h | 29 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 142 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.h | 4 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 41 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 151 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_quota_priv.h | 6 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_quota.h | 61 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_utils.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 33 |
18 files changed, 348 insertions, 203 deletions
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 71bb41019a12..44eb313f22b9 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) | |||
230 | * field (see the QCMD macro in quota.h). These macros help keep the | 230 | * field (see the QCMD macro in quota.h). These macros help keep the |
231 | * code portable - they are not visible from the syscall interface. | 231 | * code portable - they are not visible from the syscall interface. |
232 | */ | 232 | */ |
233 | #define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ | 233 | #define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */ |
234 | #define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */ | 234 | #define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */ |
235 | #define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */ | ||
236 | #define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */ | ||
235 | 237 | ||
236 | /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ | 238 | /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ |
237 | /* we may well need to fine-tune this if it ever becomes an issue. */ | 239 | /* we may well need to fine-tune this if it ever becomes an issue. */ |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 455e2b2fb964..d5f0340ddcd9 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -701,7 +701,8 @@ linvfs_getxquota( | |||
701 | struct vfs *vfsp = LINVFS_GET_VFS(sb); | 701 | struct vfs *vfsp = LINVFS_GET_VFS(sb); |
702 | int error, getmode; | 702 | int error, getmode; |
703 | 703 | ||
704 | getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA; | 704 | getmode = (type == USRQUOTA) ? Q_XGETQUOTA : |
705 | ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA); | ||
705 | VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); | 706 | VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); |
706 | return -error; | 707 | return -error; |
707 | } | 708 | } |
@@ -716,7 +717,8 @@ linvfs_setxquota( | |||
716 | struct vfs *vfsp = LINVFS_GET_VFS(sb); | 717 | struct vfs *vfsp = LINVFS_GET_VFS(sb); |
717 | int error, setmode; | 718 | int error, setmode; |
718 | 719 | ||
719 | setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM; | 720 | setmode = (type == USRQUOTA) ? Q_XSETQLIM : |
721 | ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM); | ||
720 | VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); | 722 | VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); |
721 | return -error; | 723 | return -error; |
722 | } | 724 | } |
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 9ce471430a0e..68089f56d5cd 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -399,9 +399,9 @@ xfs_qm_init_dquot_blk( | |||
399 | for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) | 399 | for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) |
400 | xfs_qm_dqinit_core(curid, type, d); | 400 | xfs_qm_dqinit_core(curid, type, d); |
401 | xfs_trans_dquot_buf(tp, bp, | 401 | xfs_trans_dquot_buf(tp, bp, |
402 | type & XFS_DQ_USER ? | 402 | (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF : |
403 | XFS_BLI_UDQUOT_BUF : | 403 | ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF : |
404 | XFS_BLI_GDQUOT_BUF); | 404 | XFS_BLI_GDQUOT_BUF))); |
405 | xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); | 405 | xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); |
406 | } | 406 | } |
407 | 407 | ||
@@ -482,8 +482,7 @@ xfs_qm_dqalloc( | |||
482 | * the entire thing. | 482 | * the entire thing. |
483 | */ | 483 | */ |
484 | xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), | 484 | xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), |
485 | dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), | 485 | dqp->dq_flags & XFS_DQ_ALLTYPES, bp); |
486 | bp); | ||
487 | 486 | ||
488 | if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { | 487 | if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { |
489 | goto error1; | 488 | goto error1; |
@@ -613,8 +612,7 @@ xfs_qm_dqtobp( | |||
613 | /* | 612 | /* |
614 | * A simple sanity check in case we got a corrupted dquot... | 613 | * A simple sanity check in case we got a corrupted dquot... |
615 | */ | 614 | */ |
616 | if (xfs_qm_dqcheck(ddq, id, | 615 | if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES, |
617 | dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), | ||
618 | flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), | 616 | flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), |
619 | "dqtobp")) { | 617 | "dqtobp")) { |
620 | if (!(flags & XFS_QMOPT_DQREPAIR)) { | 618 | if (!(flags & XFS_QMOPT_DQREPAIR)) { |
@@ -891,8 +889,8 @@ int | |||
891 | xfs_qm_dqget( | 889 | xfs_qm_dqget( |
892 | xfs_mount_t *mp, | 890 | xfs_mount_t *mp, |
893 | xfs_inode_t *ip, /* locked inode (optional) */ | 891 | xfs_inode_t *ip, /* locked inode (optional) */ |
894 | xfs_dqid_t id, /* gid or uid, depending on type */ | 892 | xfs_dqid_t id, /* uid/projid/gid depending on type */ |
895 | uint type, /* UDQUOT or GDQUOT */ | 893 | uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */ |
896 | uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ | 894 | uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ |
897 | xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ | 895 | xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ |
898 | { | 896 | { |
@@ -903,7 +901,9 @@ xfs_qm_dqget( | |||
903 | 901 | ||
904 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | 902 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); |
905 | if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || | 903 | if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || |
904 | (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) || | ||
906 | (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { | 905 | (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { |
906 | printk("XQM: ESRCH1\n"); | ||
907 | return (ESRCH); | 907 | return (ESRCH); |
908 | } | 908 | } |
909 | h = XFS_DQ_HASH(mp, id, type); | 909 | h = XFS_DQ_HASH(mp, id, type); |
@@ -921,7 +921,9 @@ xfs_qm_dqget( | |||
921 | again: | 921 | again: |
922 | 922 | ||
923 | #ifdef DEBUG | 923 | #ifdef DEBUG |
924 | ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP); | 924 | ASSERT(type == XFS_DQ_USER || |
925 | type == XFS_DQ_PROJ || | ||
926 | type == XFS_DQ_GROUP); | ||
925 | if (ip) { | 927 | if (ip) { |
926 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 928 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); |
927 | if (type == XFS_DQ_USER) | 929 | if (type == XFS_DQ_USER) |
@@ -979,6 +981,7 @@ xfs_qm_dqget( | |||
979 | &dqp))) { | 981 | &dqp))) { |
980 | if (ip) | 982 | if (ip) |
981 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 983 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
984 | if (error == ESRCH) printk("XQM: ESRCH2\n"); | ||
982 | return (error); | 985 | return (error); |
983 | } | 986 | } |
984 | 987 | ||
@@ -1004,6 +1007,7 @@ xfs_qm_dqget( | |||
1004 | if (! XFS_IS_DQTYPE_ON(mp, type)) { | 1007 | if (! XFS_IS_DQTYPE_ON(mp, type)) { |
1005 | /* inode stays locked on return */ | 1008 | /* inode stays locked on return */ |
1006 | xfs_qm_dqdestroy(dqp); | 1009 | xfs_qm_dqdestroy(dqp); |
1010 | printk("XQM: ESRCH3\n"); | ||
1007 | return XFS_ERROR(ESRCH); | 1011 | return XFS_ERROR(ESRCH); |
1008 | } | 1012 | } |
1009 | /* | 1013 | /* |
@@ -1244,8 +1248,8 @@ xfs_qm_dqflush( | |||
1244 | return (error); | 1248 | return (error); |
1245 | } | 1249 | } |
1246 | 1250 | ||
1247 | if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, | 1251 | if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), |
1248 | "dqflush (incore copy)")) { | 1252 | 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { |
1249 | xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); | 1253 | xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); |
1250 | return XFS_ERROR(EIO); | 1254 | return XFS_ERROR(EIO); |
1251 | } | 1255 | } |
@@ -1397,7 +1401,8 @@ xfs_dqlock2( | |||
1397 | { | 1401 | { |
1398 | if (d1 && d2) { | 1402 | if (d1 && d2) { |
1399 | ASSERT(d1 != d2); | 1403 | ASSERT(d1 != d2); |
1400 | if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { | 1404 | if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > |
1405 | INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { | ||
1401 | xfs_dqlock(d2); | 1406 | xfs_dqlock(d2); |
1402 | xfs_dqlock(d1); | 1407 | xfs_dqlock(d1); |
1403 | } else { | 1408 | } else { |
@@ -1520,8 +1525,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp) | |||
1520 | cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); | 1525 | cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); |
1521 | cmn_err(CE_DEBUG, "---- dquotID = %d", | 1526 | cmn_err(CE_DEBUG, "---- dquotID = %d", |
1522 | (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); | 1527 | (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); |
1523 | cmn_err(CE_DEBUG, "---- type = %s", | 1528 | cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp)); |
1524 | XFS_QM_ISUDQ(dqp) ? "USR" : "GRP"); | ||
1525 | cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); | 1529 | cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); |
1526 | cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); | 1530 | cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); |
1527 | cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); | 1531 | cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); |
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 35aeeafe4799..39175103c8e0 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -114,25 +114,18 @@ typedef struct xfs_dquot { | |||
114 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) | 114 | #define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * Quota Accounting flags | 117 | * Quota Accounting/Enforcement flags |
118 | */ | 118 | */ |
119 | #define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT) | 119 | #define XFS_ALL_QUOTA_ACCT \ |
120 | #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) | 120 | (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT) |
121 | #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) | 121 | #define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD) |
122 | #define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) | 122 | #define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD) |
123 | #define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ | ||
124 | XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD) | ||
125 | 123 | ||
126 | #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) | 124 | #define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) |
127 | #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) | ||
128 | #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) | ||
129 | |||
130 | /* | ||
131 | * Quota Limit Enforcement flags | ||
132 | */ | ||
133 | #define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) | 125 | #define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) |
134 | #define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) | 126 | #define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) |
135 | #define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) | 127 | #define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) |
128 | #define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) | ||
136 | 129 | ||
137 | #ifdef DEBUG | 130 | #ifdef DEBUG |
138 | static inline int | 131 | static inline int |
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
167 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) | 160 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) |
168 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 161 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
169 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) | 162 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) |
163 | #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) | ||
164 | #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) | ||
170 | #define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) | 165 | #define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) |
171 | #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ | 166 | #define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ |
172 | XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ | 167 | XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ |
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
174 | 169 | ||
175 | #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ | 170 | #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ |
176 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ | 171 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ |
177 | (XFS_IS_GQUOTA_ON((d)->q_mount)))) | 172 | (XFS_IS_OQUOTA_ON((d)->q_mount)))) |
178 | 173 | ||
179 | #ifdef XFS_DQUOT_TRACE | 174 | #ifdef XFS_DQUOT_TRACE |
180 | /* | 175 | /* |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 41bbc49d535e..3ea75972767c 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -310,9 +310,9 @@ xfs_qm_mount_quotainit( | |||
310 | uint flags) | 310 | uint flags) |
311 | { | 311 | { |
312 | /* | 312 | /* |
313 | * User or group quotas has to be on. | 313 | * User, projects or group quotas has to be on. |
314 | */ | 314 | */ |
315 | ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)); | 315 | ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)); |
316 | 316 | ||
317 | /* | 317 | /* |
318 | * Initialize the flags in the mount structure. From this point | 318 | * Initialize the flags in the mount structure. From this point |
@@ -330,7 +330,11 @@ xfs_qm_mount_quotainit( | |||
330 | if (flags & XFSMNT_GQUOTA) { | 330 | if (flags & XFSMNT_GQUOTA) { |
331 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 331 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
332 | if (flags & XFSMNT_GQUOTAENF) | 332 | if (flags & XFSMNT_GQUOTAENF) |
333 | mp->m_qflags |= XFS_GQUOTA_ENFD; | 333 | mp->m_qflags |= XFS_OQUOTA_ENFD; |
334 | } else if (flags & XFSMNT_PQUOTA) { | ||
335 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
336 | if (flags & XFSMNT_PQUOTAENF) | ||
337 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
@@ -363,11 +367,11 @@ xfs_qm_mount_quotas( | |||
363 | 367 | ||
364 | /* | 368 | /* |
365 | * If a file system had quotas running earlier, but decided to | 369 | * If a file system had quotas running earlier, but decided to |
366 | * mount without -o quota/uquota/gquota options, revoke the | 370 | * mount without -o uquota/pquota/gquota options, revoke the |
367 | * quotachecked license, and bail out. | 371 | * quotachecked license, and bail out. |
368 | */ | 372 | */ |
369 | if (! XFS_IS_QUOTA_ON(mp) && | 373 | if (! XFS_IS_QUOTA_ON(mp) && |
370 | (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { | 374 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) { |
371 | mp->m_qflags = 0; | 375 | mp->m_qflags = 0; |
372 | goto write_changes; | 376 | goto write_changes; |
373 | } | 377 | } |
@@ -619,7 +623,7 @@ xfs_qm_detach_gdquots( | |||
619 | STATIC int | 623 | STATIC int |
620 | xfs_qm_dqpurge_int( | 624 | xfs_qm_dqpurge_int( |
621 | xfs_mount_t *mp, | 625 | xfs_mount_t *mp, |
622 | uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */ | 626 | uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */ |
623 | { | 627 | { |
624 | xfs_dquot_t *dqp; | 628 | xfs_dquot_t *dqp; |
625 | uint dqtype; | 629 | uint dqtype; |
@@ -631,6 +635,7 @@ xfs_qm_dqpurge_int( | |||
631 | return (0); | 635 | return (0); |
632 | 636 | ||
633 | dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; | 637 | dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; |
638 | dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0; | ||
634 | dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; | 639 | dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; |
635 | 640 | ||
636 | xfs_qm_mplist_lock(mp); | 641 | xfs_qm_mplist_lock(mp); |
@@ -740,11 +745,11 @@ xfs_qm_dqattach_one( | |||
740 | 745 | ||
741 | /* | 746 | /* |
742 | * udqhint is the i_udquot field in inode, and is non-NULL only | 747 | * udqhint is the i_udquot field in inode, and is non-NULL only |
743 | * when the type arg is XFS_DQ_GROUP. Its purpose is to save a | 748 | * when the type arg is group/project. Its purpose is to save a |
744 | * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside | 749 | * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside |
745 | * the user dquot. | 750 | * the user dquot. |
746 | */ | 751 | */ |
747 | ASSERT(!udqhint || type == XFS_DQ_GROUP); | 752 | ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ); |
748 | if (udqhint && !dolock) | 753 | if (udqhint && !dolock) |
749 | xfs_dqlock(udqhint); | 754 | xfs_dqlock(udqhint); |
750 | 755 | ||
@@ -903,8 +908,8 @@ xfs_qm_dqattach_grouphint( | |||
903 | 908 | ||
904 | 909 | ||
905 | /* | 910 | /* |
906 | * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON | 911 | * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON |
907 | * in to account. | 912 | * into account. |
908 | * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. | 913 | * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. |
909 | * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty | 914 | * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty |
910 | * much made this code a complete mess, but it has been pretty useful. | 915 | * much made this code a complete mess, but it has been pretty useful. |
@@ -943,8 +948,13 @@ xfs_qm_dqattach( | |||
943 | nquotas++; | 948 | nquotas++; |
944 | } | 949 | } |
945 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 950 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); |
946 | if (XFS_IS_GQUOTA_ON(mp)) { | 951 | if (XFS_IS_OQUOTA_ON(mp)) { |
947 | error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, | 952 | error = XFS_IS_GQUOTA_ON(mp) ? |
953 | xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, | ||
954 | flags & XFS_QMOPT_DQALLOC, | ||
955 | flags & XFS_QMOPT_DQLOCK, | ||
956 | ip->i_udquot, &ip->i_gdquot) : | ||
957 | xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ, | ||
948 | flags & XFS_QMOPT_DQALLOC, | 958 | flags & XFS_QMOPT_DQALLOC, |
949 | flags & XFS_QMOPT_DQLOCK, | 959 | flags & XFS_QMOPT_DQLOCK, |
950 | ip->i_udquot, &ip->i_gdquot); | 960 | ip->i_udquot, &ip->i_gdquot); |
@@ -995,7 +1005,7 @@ xfs_qm_dqattach( | |||
995 | } | 1005 | } |
996 | if (XFS_IS_UQUOTA_ON(mp)) | 1006 | if (XFS_IS_UQUOTA_ON(mp)) |
997 | ASSERT(ip->i_udquot); | 1007 | ASSERT(ip->i_udquot); |
998 | if (XFS_IS_GQUOTA_ON(mp)) | 1008 | if (XFS_IS_OQUOTA_ON(mp)) |
999 | ASSERT(ip->i_gdquot); | 1009 | ASSERT(ip->i_gdquot); |
1000 | } | 1010 | } |
1001 | #endif | 1011 | #endif |
@@ -1024,13 +1034,13 @@ xfs_qm_dqdetach( | |||
1024 | 1034 | ||
1025 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); | 1035 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); |
1026 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); | 1036 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); |
1027 | if (ip->i_udquot) | ||
1028 | xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); | ||
1029 | if (ip->i_udquot) { | 1037 | if (ip->i_udquot) { |
1038 | xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); | ||
1030 | xfs_qm_dqrele(ip->i_udquot); | 1039 | xfs_qm_dqrele(ip->i_udquot); |
1031 | ip->i_udquot = NULL; | 1040 | ip->i_udquot = NULL; |
1032 | } | 1041 | } |
1033 | if (ip->i_gdquot) { | 1042 | if (ip->i_gdquot) { |
1043 | xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip); | ||
1034 | xfs_qm_dqrele(ip->i_gdquot); | 1044 | xfs_qm_dqrele(ip->i_gdquot); |
1035 | ip->i_gdquot = NULL; | 1045 | ip->i_gdquot = NULL; |
1036 | } | 1046 | } |
@@ -1208,8 +1218,9 @@ xfs_qm_init_quotainfo( | |||
1208 | * and group quotas, at least not at this point. | 1218 | * and group quotas, at least not at this point. |
1209 | */ | 1219 | */ |
1210 | error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, | 1220 | error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, |
1211 | (XFS_IS_UQUOTA_RUNNING(mp)) ? | 1221 | XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER : |
1212 | XFS_DQ_USER : XFS_DQ_GROUP, | 1222 | (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP : |
1223 | XFS_DQ_PROJ), | ||
1213 | XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, | 1224 | XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, |
1214 | &dqp); | 1225 | &dqp); |
1215 | if (! error) { | 1226 | if (! error) { |
@@ -1372,13 +1383,20 @@ xfs_qm_dqget_noattach( | |||
1372 | ASSERT(udqp); | 1383 | ASSERT(udqp); |
1373 | } | 1384 | } |
1374 | 1385 | ||
1375 | if (XFS_IS_GQUOTA_ON(mp)) { | 1386 | if (XFS_IS_OQUOTA_ON(mp)) { |
1376 | ASSERT(ip->i_gdquot == NULL); | 1387 | ASSERT(ip->i_gdquot == NULL); |
1377 | if (udqp) | 1388 | if (udqp) |
1378 | xfs_dqunlock(udqp); | 1389 | xfs_dqunlock(udqp); |
1379 | if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP, | 1390 | error = XFS_IS_GQUOTA_ON(mp) ? |
1380 | XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, | 1391 | xfs_qm_dqget(mp, ip, |
1381 | &gdqp))) { | 1392 | ip->i_d.di_gid, XFS_DQ_GROUP, |
1393 | XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, | ||
1394 | &gdqp) : | ||
1395 | xfs_qm_dqget(mp, ip, | ||
1396 | ip->i_d.di_projid, XFS_DQ_PROJ, | ||
1397 | XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, | ||
1398 | &gdqp); | ||
1399 | if (error) { | ||
1382 | if (udqp) | 1400 | if (udqp) |
1383 | xfs_qm_dqrele(udqp); | 1401 | xfs_qm_dqrele(udqp); |
1384 | ASSERT(error != ESRCH); | 1402 | ASSERT(error != ESRCH); |
@@ -1547,11 +1565,14 @@ xfs_qm_dqiter_bufs( | |||
1547 | int error; | 1565 | int error; |
1548 | int notcommitted; | 1566 | int notcommitted; |
1549 | int incr; | 1567 | int incr; |
1568 | int type; | ||
1550 | 1569 | ||
1551 | ASSERT(blkcnt > 0); | 1570 | ASSERT(blkcnt > 0); |
1552 | notcommitted = 0; | 1571 | notcommitted = 0; |
1553 | incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? | 1572 | incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? |
1554 | XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; | 1573 | XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; |
1574 | type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER : | ||
1575 | (flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP); | ||
1555 | error = 0; | 1576 | error = 0; |
1556 | 1577 | ||
1557 | /* | 1578 | /* |
@@ -1570,9 +1591,7 @@ xfs_qm_dqiter_bufs( | |||
1570 | if (error) | 1591 | if (error) |
1571 | break; | 1592 | break; |
1572 | 1593 | ||
1573 | (void) xfs_qm_reset_dqcounts(mp, bp, firstid, | 1594 | (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type); |
1574 | flags & XFS_QMOPT_UQUOTA ? | ||
1575 | XFS_DQ_USER : XFS_DQ_GROUP); | ||
1576 | xfs_bdwrite(mp, bp); | 1595 | xfs_bdwrite(mp, bp); |
1577 | /* | 1596 | /* |
1578 | * goto the next block. | 1597 | * goto the next block. |
@@ -1584,7 +1603,7 @@ xfs_qm_dqiter_bufs( | |||
1584 | } | 1603 | } |
1585 | 1604 | ||
1586 | /* | 1605 | /* |
1587 | * Iterate over all allocated USR/GRP dquots in the system, calling a | 1606 | * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a |
1588 | * caller supplied function for every chunk of dquots that we find. | 1607 | * caller supplied function for every chunk of dquots that we find. |
1589 | */ | 1608 | */ |
1590 | STATIC int | 1609 | STATIC int |
@@ -1855,7 +1874,7 @@ xfs_qm_dqusage_adjust( | |||
1855 | xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); | 1874 | xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); |
1856 | xfs_qm_dqput(udqp); | 1875 | xfs_qm_dqput(udqp); |
1857 | } | 1876 | } |
1858 | if (XFS_IS_GQUOTA_ON(mp)) { | 1877 | if (XFS_IS_OQUOTA_ON(mp)) { |
1859 | ASSERT(gdqp); | 1878 | ASSERT(gdqp); |
1860 | xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); | 1879 | xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); |
1861 | xfs_qm_dqput(gdqp); | 1880 | xfs_qm_dqput(gdqp); |
@@ -1904,7 +1923,7 @@ xfs_qm_quotacheck( | |||
1904 | cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); | 1923 | cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); |
1905 | 1924 | ||
1906 | /* | 1925 | /* |
1907 | * First we go thru all the dquots on disk, USR and GRP, and reset | 1926 | * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset |
1908 | * their counters to zero. We need a clean slate. | 1927 | * their counters to zero. We need a clean slate. |
1909 | * We don't log our changes till later. | 1928 | * We don't log our changes till later. |
1910 | */ | 1929 | */ |
@@ -1915,9 +1934,10 @@ xfs_qm_quotacheck( | |||
1915 | } | 1934 | } |
1916 | 1935 | ||
1917 | if ((gip = XFS_QI_GQIP(mp))) { | 1936 | if ((gip = XFS_QI_GQIP(mp))) { |
1918 | if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA))) | 1937 | if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ? |
1938 | XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA))) | ||
1919 | goto error_return; | 1939 | goto error_return; |
1920 | flags |= XFS_GQUOTA_CHKD; | 1940 | flags |= XFS_OQUOTA_CHKD; |
1921 | } | 1941 | } |
1922 | 1942 | ||
1923 | do { | 1943 | do { |
@@ -1944,7 +1964,7 @@ xfs_qm_quotacheck( | |||
1944 | if (error) { | 1964 | if (error) { |
1945 | xfs_qm_dqpurge_all(mp, | 1965 | xfs_qm_dqpurge_all(mp, |
1946 | XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| | 1966 | XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| |
1947 | XFS_QMOPT_QUOTAOFF); | 1967 | XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF); |
1948 | goto error_return; | 1968 | goto error_return; |
1949 | } | 1969 | } |
1950 | /* | 1970 | /* |
@@ -1967,7 +1987,7 @@ xfs_qm_quotacheck( | |||
1967 | * quotachecked status, since we won't be doing accounting for | 1987 | * quotachecked status, since we won't be doing accounting for |
1968 | * that type anymore. | 1988 | * that type anymore. |
1969 | */ | 1989 | */ |
1970 | mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD); | 1990 | mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD); |
1971 | mp->m_qflags |= flags; | 1991 | mp->m_qflags |= flags; |
1972 | 1992 | ||
1973 | XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); | 1993 | XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); |
@@ -2019,7 +2039,7 @@ xfs_qm_init_quotainos( | |||
2019 | 0, 0, &uip, 0))) | 2039 | 0, 0, &uip, 0))) |
2020 | return XFS_ERROR(error); | 2040 | return XFS_ERROR(error); |
2021 | } | 2041 | } |
2022 | if (XFS_IS_GQUOTA_ON(mp) && | 2042 | if (XFS_IS_OQUOTA_ON(mp) && |
2023 | mp->m_sb.sb_gquotino != NULLFSINO) { | 2043 | mp->m_sb.sb_gquotino != NULLFSINO) { |
2024 | ASSERT(mp->m_sb.sb_gquotino > 0); | 2044 | ASSERT(mp->m_sb.sb_gquotino > 0); |
2025 | if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | 2045 | if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, |
@@ -2049,10 +2069,12 @@ xfs_qm_init_quotainos( | |||
2049 | 2069 | ||
2050 | flags &= ~XFS_QMOPT_SBVERSION; | 2070 | flags &= ~XFS_QMOPT_SBVERSION; |
2051 | } | 2071 | } |
2052 | if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { | 2072 | if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) { |
2053 | if ((error = xfs_qm_qino_alloc(mp, &gip, | 2073 | flags |= (XFS_IS_GQUOTA_ON(mp) ? |
2054 | sbflags | XFS_SB_GQUOTINO, | 2074 | XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA); |
2055 | flags | XFS_QMOPT_GQUOTA))) { | 2075 | error = xfs_qm_qino_alloc(mp, &gip, |
2076 | sbflags | XFS_SB_GQUOTINO, flags); | ||
2077 | if (error) { | ||
2056 | if (uip) | 2078 | if (uip) |
2057 | VN_RELE(XFS_ITOV(uip)); | 2079 | VN_RELE(XFS_ITOV(uip)); |
2058 | 2080 | ||
@@ -2458,6 +2480,7 @@ xfs_qm_vop_dqalloc( | |||
2458 | xfs_inode_t *ip, | 2480 | xfs_inode_t *ip, |
2459 | uid_t uid, | 2481 | uid_t uid, |
2460 | gid_t gid, | 2482 | gid_t gid, |
2483 | prid_t prid, | ||
2461 | uint flags, | 2484 | uint flags, |
2462 | xfs_dquot_t **O_udqpp, | 2485 | xfs_dquot_t **O_udqpp, |
2463 | xfs_dquot_t **O_gdqpp) | 2486 | xfs_dquot_t **O_gdqpp) |
@@ -2489,8 +2512,7 @@ xfs_qm_vop_dqalloc( | |||
2489 | } | 2512 | } |
2490 | 2513 | ||
2491 | uq = gq = NULL; | 2514 | uq = gq = NULL; |
2492 | if ((flags & XFS_QMOPT_UQUOTA) && | 2515 | if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) { |
2493 | XFS_IS_UQUOTA_ON(mp)) { | ||
2494 | if (ip->i_d.di_uid != uid) { | 2516 | if (ip->i_d.di_uid != uid) { |
2495 | /* | 2517 | /* |
2496 | * What we need is the dquot that has this uid, and | 2518 | * What we need is the dquot that has this uid, and |
@@ -2528,8 +2550,7 @@ xfs_qm_vop_dqalloc( | |||
2528 | xfs_dqunlock(uq); | 2550 | xfs_dqunlock(uq); |
2529 | } | 2551 | } |
2530 | } | 2552 | } |
2531 | if ((flags & XFS_QMOPT_GQUOTA) && | 2553 | if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) { |
2532 | XFS_IS_GQUOTA_ON(mp)) { | ||
2533 | if (ip->i_d.di_gid != gid) { | 2554 | if (ip->i_d.di_gid != gid) { |
2534 | xfs_iunlock(ip, lockflags); | 2555 | xfs_iunlock(ip, lockflags); |
2535 | if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, | 2556 | if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, |
@@ -2552,6 +2573,29 @@ xfs_qm_vop_dqalloc( | |||
2552 | XFS_DQHOLD(gq); | 2573 | XFS_DQHOLD(gq); |
2553 | xfs_dqunlock(gq); | 2574 | xfs_dqunlock(gq); |
2554 | } | 2575 | } |
2576 | } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) { | ||
2577 | if (ip->i_d.di_projid != prid) { | ||
2578 | xfs_iunlock(ip, lockflags); | ||
2579 | if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid, | ||
2580 | XFS_DQ_PROJ, | ||
2581 | XFS_QMOPT_DQALLOC | | ||
2582 | XFS_QMOPT_DOWARN, | ||
2583 | &gq))) { | ||
2584 | if (uq) | ||
2585 | xfs_qm_dqrele(uq); | ||
2586 | ASSERT(error != ENOENT); | ||
2587 | return (error); | ||
2588 | } | ||
2589 | xfs_dqunlock(gq); | ||
2590 | lockflags = XFS_ILOCK_SHARED; | ||
2591 | xfs_ilock(ip, lockflags); | ||
2592 | } else { | ||
2593 | ASSERT(ip->i_gdquot); | ||
2594 | gq = ip->i_gdquot; | ||
2595 | xfs_dqlock(gq); | ||
2596 | XFS_DQHOLD(gq); | ||
2597 | xfs_dqunlock(gq); | ||
2598 | } | ||
2555 | } | 2599 | } |
2556 | if (uq) | 2600 | if (uq) |
2557 | xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); | 2601 | xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); |
@@ -2617,7 +2661,7 @@ xfs_qm_vop_chown( | |||
2617 | } | 2661 | } |
2618 | 2662 | ||
2619 | /* | 2663 | /* |
2620 | * Quota reservations for setattr(AT_UID|AT_GID). | 2664 | * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID). |
2621 | */ | 2665 | */ |
2622 | int | 2666 | int |
2623 | xfs_qm_vop_chown_reserve( | 2667 | xfs_qm_vop_chown_reserve( |
@@ -2652,12 +2696,16 @@ xfs_qm_vop_chown_reserve( | |||
2652 | unresudq = ip->i_udquot; | 2696 | unresudq = ip->i_udquot; |
2653 | } | 2697 | } |
2654 | } | 2698 | } |
2655 | if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && | 2699 | if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { |
2656 | ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) { | 2700 | if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid != |
2657 | delblksgdq = gdqp; | 2701 | INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) || |
2658 | if (delblks) { | 2702 | (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid != |
2659 | ASSERT(ip->i_gdquot); | 2703 | INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) { |
2660 | unresgdq = ip->i_gdquot; | 2704 | delblksgdq = gdqp; |
2705 | if (delblks) { | ||
2706 | ASSERT(ip->i_gdquot); | ||
2707 | unresgdq = ip->i_gdquot; | ||
2708 | } | ||
2661 | } | 2709 | } |
2662 | } | 2710 | } |
2663 | 2711 | ||
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index ae626eca5aca..781968779540 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of version 2 of the GNU General Public License as | 5 | * 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 | 202 | ||
203 | /* vop stuff */ | 203 | /* vop stuff */ |
204 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, | 204 | extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, |
205 | uid_t, gid_t, uint, | 205 | uid_t, gid_t, prid_t, uint, |
206 | xfs_dquot_t **, xfs_dquot_t **); | 206 | xfs_dquot_t **, xfs_dquot_t **); |
207 | extern void xfs_qm_vop_dqattach_and_dqmod_newinode( | 207 | extern void xfs_qm_vop_dqattach_and_dqmod_newinode( |
208 | xfs_trans_t *, xfs_inode_t *, | 208 | xfs_trans_t *, xfs_inode_t *, |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 09b1171dfb83..dc3c37a1e158 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -71,10 +71,13 @@ | |||
71 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | 71 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ |
72 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | 72 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ |
73 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | 73 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ |
74 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
74 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | 75 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ |
75 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | 76 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ |
77 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
76 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | 78 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ |
77 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 79 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
80 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
78 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 81 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
79 | 82 | ||
80 | STATIC int | 83 | STATIC int |
@@ -109,6 +112,14 @@ xfs_qm_parseargs( | |||
109 | args->flags |= XFSMNT_UQUOTA; | 112 | args->flags |= XFSMNT_UQUOTA; |
110 | args->flags &= ~XFSMNT_UQUOTAENF; | 113 | args->flags &= ~XFSMNT_UQUOTAENF; |
111 | referenced = 1; | 114 | referenced = 1; |
115 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
116 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
117 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
118 | referenced = 1; | ||
119 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
120 | args->flags |= XFSMNT_PQUOTA; | ||
121 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
122 | referenced = 1; | ||
112 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 123 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || |
113 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 124 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { |
114 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | 125 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; |
@@ -127,6 +138,12 @@ xfs_qm_parseargs( | |||
127 | *this_char++ = ','; | 138 | *this_char++ = ','; |
128 | } | 139 | } |
129 | 140 | ||
141 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
142 | cmn_err(CE_WARN, | ||
143 | "XFS: cannot mount with both project and group quota"); | ||
144 | return XFS_ERROR(EINVAL); | ||
145 | } | ||
146 | |||
130 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); | 147 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); |
131 | if (!error && !referenced) | 148 | if (!error && !referenced) |
132 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); | 149 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); |
@@ -148,13 +165,19 @@ xfs_qm_showargs( | |||
148 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | 165 | seq_puts(m, "," MNTOPT_UQUOTANOENF); |
149 | } | 166 | } |
150 | 167 | ||
168 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | ||
169 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? | ||
170 | seq_puts(m, "," MNTOPT_PRJQUOTA) : | ||
171 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
172 | } | ||
173 | |||
151 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | 174 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { |
152 | (mp->m_qflags & XFS_GQUOTA_ENFD) ? | 175 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? |
153 | seq_puts(m, "," MNTOPT_GRPQUOTA) : | 176 | seq_puts(m, "," MNTOPT_GRPQUOTA) : |
154 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | 177 | seq_puts(m, "," MNTOPT_GQUOTANOENF); |
155 | } | 178 | } |
156 | 179 | ||
157 | if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) | 180 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
158 | seq_puts(m, "," MNTOPT_NOQUOTA); | 181 | seq_puts(m, "," MNTOPT_NOQUOTA); |
159 | 182 | ||
160 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); | 183 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); |
@@ -171,7 +194,7 @@ xfs_qm_mount( | |||
171 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 194 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
172 | int error; | 195 | int error; |
173 | 196 | ||
174 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)) | 197 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) |
175 | xfs_qm_mount_quotainit(mp, args->flags); | 198 | xfs_qm_mount_quotainit(mp, args->flags); |
176 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); | 199 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); |
177 | return error; | 200 | return error; |
@@ -255,16 +278,17 @@ xfs_qm_newmount( | |||
255 | uint *quotaflags) | 278 | uint *quotaflags) |
256 | { | 279 | { |
257 | uint quotaondisk; | 280 | uint quotaondisk; |
258 | uint uquotaondisk = 0, gquotaondisk = 0; | 281 | uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0; |
259 | 282 | ||
260 | *quotaflags = 0; | 283 | *quotaflags = 0; |
261 | *needquotamount = B_FALSE; | 284 | *needquotamount = B_FALSE; |
262 | 285 | ||
263 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | 286 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && |
264 | mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT); | 287 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); |
265 | 288 | ||
266 | if (quotaondisk) { | 289 | if (quotaondisk) { |
267 | uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; | 290 | uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; |
291 | pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT; | ||
268 | gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; | 292 | gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; |
269 | } | 293 | } |
270 | 294 | ||
@@ -277,13 +301,16 @@ xfs_qm_newmount( | |||
277 | 301 | ||
278 | if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || | 302 | if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || |
279 | (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || | 303 | (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || |
304 | (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) || | ||
305 | (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) || | ||
280 | (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || | 306 | (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || |
281 | (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) && | 307 | (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) && |
282 | xfs_dev_is_read_only(mp, "changing quota state")) { | 308 | xfs_dev_is_read_only(mp, "changing quota state")) { |
283 | cmn_err(CE_WARN, | 309 | cmn_err(CE_WARN, |
284 | "XFS: please mount with%s%s%s.", | 310 | "XFS: please mount with%s%s%s%s.", |
285 | (!quotaondisk ? "out quota" : ""), | 311 | (!quotaondisk ? "out quota" : ""), |
286 | (uquotaondisk ? " usrquota" : ""), | 312 | (uquotaondisk ? " usrquota" : ""), |
313 | (pquotaondisk ? " prjquota" : ""), | ||
287 | (gquotaondisk ? " grpquota" : "")); | 314 | (gquotaondisk ? " grpquota" : "")); |
288 | return XFS_ERROR(EPERM); | 315 | return XFS_ERROR(EPERM); |
289 | } | 316 | } |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 229f5b5a2d25..365a054f02d6 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -118,40 +118,41 @@ xfs_qm_quotactl( | |||
118 | * The following commands are valid even when quotaoff. | 118 | * The following commands are valid even when quotaoff. |
119 | */ | 119 | */ |
120 | switch (cmd) { | 120 | switch (cmd) { |
121 | case Q_XQUOTARM: | ||
121 | /* | 122 | /* |
122 | * truncate quota files. quota must be off. | 123 | * Truncate quota files. quota must be off. |
123 | */ | 124 | */ |
124 | case Q_XQUOTARM: | ||
125 | if (XFS_IS_QUOTA_ON(mp) || addr == NULL) | 125 | if (XFS_IS_QUOTA_ON(mp) || addr == NULL) |
126 | return XFS_ERROR(EINVAL); | 126 | return XFS_ERROR(EINVAL); |
127 | if (vfsp->vfs_flag & VFS_RDONLY) | 127 | if (vfsp->vfs_flag & VFS_RDONLY) |
128 | return XFS_ERROR(EROFS); | 128 | return XFS_ERROR(EROFS); |
129 | return (xfs_qm_scall_trunc_qfiles(mp, | 129 | return (xfs_qm_scall_trunc_qfiles(mp, |
130 | xfs_qm_import_qtype_flags(*(uint *)addr))); | 130 | xfs_qm_import_qtype_flags(*(uint *)addr))); |
131 | |||
132 | case Q_XGETQSTAT: | ||
131 | /* | 133 | /* |
132 | * Get quota status information. | 134 | * Get quota status information. |
133 | */ | 135 | */ |
134 | case Q_XGETQSTAT: | ||
135 | return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); | 136 | return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); |
136 | 137 | ||
138 | case Q_XQUOTAON: | ||
137 | /* | 139 | /* |
138 | * QUOTAON for root f/s and quota enforcement on others.. | 140 | * QUOTAON - enabling quota enforcement. |
139 | * Quota accounting for non-root f/s's must be turned on | 141 | * Quota accounting must be turned on at mount time. |
140 | * at mount time. | ||
141 | */ | 142 | */ |
142 | case Q_XQUOTAON: | ||
143 | if (addr == NULL) | 143 | if (addr == NULL) |
144 | return XFS_ERROR(EINVAL); | 144 | return XFS_ERROR(EINVAL); |
145 | if (vfsp->vfs_flag & VFS_RDONLY) | 145 | if (vfsp->vfs_flag & VFS_RDONLY) |
146 | return XFS_ERROR(EROFS); | 146 | return XFS_ERROR(EROFS); |
147 | return (xfs_qm_scall_quotaon(mp, | 147 | return (xfs_qm_scall_quotaon(mp, |
148 | xfs_qm_import_flags(*(uint *)addr))); | 148 | xfs_qm_import_flags(*(uint *)addr))); |
149 | case Q_XQUOTAOFF: | 149 | |
150 | case Q_XQUOTAOFF: | ||
150 | if (vfsp->vfs_flag & VFS_RDONLY) | 151 | if (vfsp->vfs_flag & VFS_RDONLY) |
151 | return XFS_ERROR(EROFS); | 152 | return XFS_ERROR(EROFS); |
152 | break; | 153 | break; |
153 | 154 | ||
154 | default: | 155 | default: |
155 | break; | 156 | break; |
156 | } | 157 | } |
157 | 158 | ||
@@ -159,7 +160,7 @@ xfs_qm_quotactl( | |||
159 | return XFS_ERROR(ESRCH); | 160 | return XFS_ERROR(ESRCH); |
160 | 161 | ||
161 | switch (cmd) { | 162 | switch (cmd) { |
162 | case Q_XQUOTAOFF: | 163 | case Q_XQUOTAOFF: |
163 | if (vfsp->vfs_flag & VFS_RDONLY) | 164 | if (vfsp->vfs_flag & VFS_RDONLY) |
164 | return XFS_ERROR(EROFS); | 165 | return XFS_ERROR(EROFS); |
165 | error = xfs_qm_scall_quotaoff(mp, | 166 | error = xfs_qm_scall_quotaoff(mp, |
@@ -167,42 +168,39 @@ xfs_qm_quotactl( | |||
167 | B_FALSE); | 168 | B_FALSE); |
168 | break; | 169 | break; |
169 | 170 | ||
170 | /* | 171 | case Q_XGETQUOTA: |
171 | * Defaults to XFS_GETUQUOTA. | ||
172 | */ | ||
173 | case Q_XGETQUOTA: | ||
174 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, | 172 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, |
175 | (fs_disk_quota_t *)addr); | 173 | (fs_disk_quota_t *)addr); |
176 | break; | 174 | break; |
177 | /* | 175 | case Q_XGETGQUOTA: |
178 | * Set limits, both hard and soft. Defaults to Q_SETUQLIM. | 176 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, |
179 | */ | 177 | (fs_disk_quota_t *)addr); |
180 | case Q_XSETQLIM: | 178 | break; |
179 | case Q_XGETPQUOTA: | ||
180 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, | ||
181 | (fs_disk_quota_t *)addr); | ||
182 | break; | ||
183 | |||
184 | case Q_XSETQLIM: | ||
181 | if (vfsp->vfs_flag & VFS_RDONLY) | 185 | if (vfsp->vfs_flag & VFS_RDONLY) |
182 | return XFS_ERROR(EROFS); | 186 | return XFS_ERROR(EROFS); |
183 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, | 187 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, |
184 | (fs_disk_quota_t *)addr); | 188 | (fs_disk_quota_t *)addr); |
185 | break; | 189 | break; |
186 | 190 | case Q_XSETGQLIM: | |
187 | case Q_XSETGQLIM: | ||
188 | if (vfsp->vfs_flag & VFS_RDONLY) | 191 | if (vfsp->vfs_flag & VFS_RDONLY) |
189 | return XFS_ERROR(EROFS); | 192 | return XFS_ERROR(EROFS); |
190 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | 193 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, |
191 | (fs_disk_quota_t *)addr); | 194 | (fs_disk_quota_t *)addr); |
192 | break; | 195 | break; |
193 | 196 | case Q_XSETPQLIM: | |
194 | 197 | if (vfsp->vfs_flag & VFS_RDONLY) | |
195 | case Q_XGETGQUOTA: | 198 | return XFS_ERROR(EROFS); |
196 | error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | 199 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, |
197 | (fs_disk_quota_t *)addr); | 200 | (fs_disk_quota_t *)addr); |
198 | break; | 201 | break; |
199 | 202 | ||
200 | /* | 203 | default: |
201 | * Quotas are entirely undefined after quotaoff in XFS quotas. | ||
202 | * For instance, there's no way to set limits when quotaoff. | ||
203 | */ | ||
204 | |||
205 | default: | ||
206 | error = XFS_ERROR(EINVAL); | 204 | error = XFS_ERROR(EINVAL); |
207 | break; | 205 | break; |
208 | } | 206 | } |
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff( | |||
286 | } | 284 | } |
287 | if (flags & XFS_GQUOTA_ACCT) { | 285 | if (flags & XFS_GQUOTA_ACCT) { |
288 | dqtype |= XFS_QMOPT_GQUOTA; | 286 | dqtype |= XFS_QMOPT_GQUOTA; |
289 | flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); | 287 | flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); |
290 | inactivate_flags |= XFS_GQUOTA_ACTIVE; | 288 | inactivate_flags |= XFS_GQUOTA_ACTIVE; |
289 | } else if (flags & XFS_PQUOTA_ACCT) { | ||
290 | dqtype |= XFS_QMOPT_PQUOTA; | ||
291 | flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD); | ||
292 | inactivate_flags |= XFS_PQUOTA_ACTIVE; | ||
291 | } | 293 | } |
292 | 294 | ||
293 | /* | 295 | /* |
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff( | |||
364 | /* | 366 | /* |
365 | * If quotas is completely disabled, close shop. | 367 | * If quotas is completely disabled, close shop. |
366 | */ | 368 | */ |
367 | if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) { | 369 | if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) || |
370 | ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) { | ||
368 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); | 371 | mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); |
369 | xfs_qm_destroy_quotainfo(mp); | 372 | xfs_qm_destroy_quotainfo(mp); |
370 | return (0); | 373 | return (0); |
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff( | |||
378 | XFS_PURGE_INODE(XFS_QI_UQIP(mp)); | 381 | XFS_PURGE_INODE(XFS_QI_UQIP(mp)); |
379 | XFS_QI_UQIP(mp) = NULL; | 382 | XFS_QI_UQIP(mp) = NULL; |
380 | } | 383 | } |
381 | if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) { | 384 | if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) { |
382 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); | 385 | XFS_PURGE_INODE(XFS_QI_GQIP(mp)); |
383 | XFS_QI_GQIP(mp) = NULL; | 386 | XFS_QI_GQIP(mp) = NULL; |
384 | } | 387 | } |
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles( | |||
411 | } | 414 | } |
412 | } | 415 | } |
413 | 416 | ||
414 | if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) { | 417 | if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) && |
418 | mp->m_sb.sb_gquotino != NULLFSINO) { | ||
415 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); | 419 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); |
416 | if (! error) { | 420 | if (! error) { |
417 | (void) xfs_truncate_file(mp, qip); | 421 | (void) xfs_truncate_file(mp, qip); |
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon( | |||
434 | uint flags) | 438 | uint flags) |
435 | { | 439 | { |
436 | int error; | 440 | int error; |
437 | unsigned long s; | 441 | unsigned long s; |
438 | uint qf; | 442 | uint qf; |
439 | uint accflags; | 443 | uint accflags; |
440 | __int64_t sbflags; | 444 | __int64_t sbflags; |
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon( | |||
468 | (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && | 472 | (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && |
469 | (flags & XFS_UQUOTA_ENFD)) | 473 | (flags & XFS_UQUOTA_ENFD)) |
470 | || | 474 | || |
475 | ((flags & XFS_PQUOTA_ACCT) == 0 && | ||
476 | (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && | ||
477 | (flags & XFS_OQUOTA_ENFD)) | ||
478 | || | ||
471 | ((flags & XFS_GQUOTA_ACCT) == 0 && | 479 | ((flags & XFS_GQUOTA_ACCT) == 0 && |
472 | (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && | 480 | (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && |
473 | (flags & XFS_GQUOTA_ENFD))) { | 481 | (flags & XFS_OQUOTA_ENFD))) { |
474 | qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", | 482 | qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", |
475 | flags, mp->m_sb.sb_qflags); | 483 | flags, mp->m_sb.sb_qflags); |
476 | return XFS_ERROR(EINVAL); | 484 | return XFS_ERROR(EINVAL); |
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon( | |||
504 | */ | 512 | */ |
505 | if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != | 513 | if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != |
506 | (mp->m_qflags & XFS_UQUOTA_ACCT)) || | 514 | (mp->m_qflags & XFS_UQUOTA_ACCT)) || |
515 | ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != | ||
516 | (mp->m_qflags & XFS_PQUOTA_ACCT)) || | ||
517 | ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != | ||
518 | (mp->m_qflags & XFS_GQUOTA_ACCT)) || | ||
507 | (flags & XFS_ALL_QUOTA_ENFD) == 0) | 519 | (flags & XFS_ALL_QUOTA_ENFD) == 0) |
508 | return (0); | 520 | return (0); |
509 | 521 | ||
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon( | |||
521 | } | 533 | } |
522 | 534 | ||
523 | 535 | ||
524 | |||
525 | /* | 536 | /* |
526 | * Return quota status information, such as uquota-off, enforcements, etc. | 537 | * Return quota status information, such as uquota-off, enforcements, etc. |
527 | */ | 538 | */ |
@@ -776,9 +787,9 @@ xfs_qm_log_quotaoff_end( | |||
776 | xfs_qoff_logitem_t *startqoff, | 787 | xfs_qoff_logitem_t *startqoff, |
777 | uint flags) | 788 | uint flags) |
778 | { | 789 | { |
779 | xfs_trans_t *tp; | 790 | xfs_trans_t *tp; |
780 | int error; | 791 | int error; |
781 | xfs_qoff_logitem_t *qoffi; | 792 | xfs_qoff_logitem_t *qoffi; |
782 | 793 | ||
783 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); | 794 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); |
784 | 795 | ||
@@ -928,18 +939,26 @@ xfs_qm_export_dquot( | |||
928 | 939 | ||
929 | STATIC uint | 940 | STATIC uint |
930 | xfs_qm_import_qtype_flags( | 941 | xfs_qm_import_qtype_flags( |
931 | uint uflags) | 942 | uint uflags) |
932 | { | 943 | { |
944 | uint oflags = 0; | ||
945 | |||
933 | /* | 946 | /* |
934 | * Can't be both at the same time. | 947 | * Can't be more than one, or none. |
935 | */ | 948 | */ |
936 | if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == | 949 | if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == |
937 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || | 950 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || |
938 | ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0)) | 951 | ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) == |
952 | (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) || | ||
953 | ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) == | ||
954 | (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) || | ||
955 | ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0)) | ||
939 | return (0); | 956 | return (0); |
940 | 957 | ||
941 | return (uflags & XFS_USER_QUOTA) ? | 958 | oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0; |
942 | XFS_DQ_USER : XFS_DQ_GROUP; | 959 | oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0; |
960 | oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0; | ||
961 | return oflags; | ||
943 | } | 962 | } |
944 | 963 | ||
945 | STATIC uint | 964 | STATIC uint |
@@ -947,14 +966,19 @@ xfs_qm_export_qtype_flags( | |||
947 | uint flags) | 966 | uint flags) |
948 | { | 967 | { |
949 | /* | 968 | /* |
950 | * Can't be both at the same time. | 969 | * Can't be more than one, or none. |
951 | */ | 970 | */ |
952 | ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != | 971 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) != |
953 | (XFS_GROUP_QUOTA | XFS_USER_QUOTA)); | 972 | (XFS_PROJ_QUOTA | XFS_USER_QUOTA)); |
954 | ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0); | 973 | ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) != |
974 | (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)); | ||
975 | ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) != | ||
976 | (XFS_USER_QUOTA | XFS_GROUP_QUOTA)); | ||
977 | ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0); | ||
955 | 978 | ||
956 | return (flags & XFS_DQ_USER) ? | 979 | return (flags & XFS_DQ_USER) ? |
957 | XFS_USER_QUOTA : XFS_GROUP_QUOTA; | 980 | XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? |
981 | XFS_PROJ_QUOTA : XFS_GROUP_QUOTA; | ||
958 | } | 982 | } |
959 | 983 | ||
960 | STATIC uint | 984 | STATIC uint |
@@ -965,12 +989,14 @@ xfs_qm_import_flags( | |||
965 | 989 | ||
966 | if (uflags & XFS_QUOTA_UDQ_ACCT) | 990 | if (uflags & XFS_QUOTA_UDQ_ACCT) |
967 | flags |= XFS_UQUOTA_ACCT; | 991 | flags |= XFS_UQUOTA_ACCT; |
992 | if (uflags & XFS_QUOTA_PDQ_ACCT) | ||
993 | flags |= XFS_PQUOTA_ACCT; | ||
968 | if (uflags & XFS_QUOTA_GDQ_ACCT) | 994 | if (uflags & XFS_QUOTA_GDQ_ACCT) |
969 | flags |= XFS_GQUOTA_ACCT; | 995 | flags |= XFS_GQUOTA_ACCT; |
970 | if (uflags & XFS_QUOTA_UDQ_ENFD) | 996 | if (uflags & XFS_QUOTA_UDQ_ENFD) |
971 | flags |= XFS_UQUOTA_ENFD; | 997 | flags |= XFS_UQUOTA_ENFD; |
972 | if (uflags & XFS_QUOTA_GDQ_ENFD) | 998 | if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD)) |
973 | flags |= XFS_GQUOTA_ENFD; | 999 | flags |= XFS_OQUOTA_ENFD; |
974 | return (flags); | 1000 | return (flags); |
975 | } | 1001 | } |
976 | 1002 | ||
@@ -984,12 +1010,16 @@ xfs_qm_export_flags( | |||
984 | uflags = 0; | 1010 | uflags = 0; |
985 | if (flags & XFS_UQUOTA_ACCT) | 1011 | if (flags & XFS_UQUOTA_ACCT) |
986 | uflags |= XFS_QUOTA_UDQ_ACCT; | 1012 | uflags |= XFS_QUOTA_UDQ_ACCT; |
1013 | if (flags & XFS_PQUOTA_ACCT) | ||
1014 | uflags |= XFS_QUOTA_PDQ_ACCT; | ||
987 | if (flags & XFS_GQUOTA_ACCT) | 1015 | if (flags & XFS_GQUOTA_ACCT) |
988 | uflags |= XFS_QUOTA_GDQ_ACCT; | 1016 | uflags |= XFS_QUOTA_GDQ_ACCT; |
989 | if (flags & XFS_UQUOTA_ENFD) | 1017 | if (flags & XFS_UQUOTA_ENFD) |
990 | uflags |= XFS_QUOTA_UDQ_ENFD; | 1018 | uflags |= XFS_QUOTA_UDQ_ENFD; |
991 | if (flags & XFS_GQUOTA_ENFD) | 1019 | if (flags & (XFS_OQUOTA_ENFD)) { |
992 | uflags |= XFS_QUOTA_GDQ_ENFD; | 1020 | uflags |= (flags & XFS_GQUOTA_ACCT) ? |
1021 | XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD; | ||
1022 | } | ||
993 | return (uflags); | 1023 | return (uflags); |
994 | } | 1024 | } |
995 | 1025 | ||
@@ -1070,7 +1100,7 @@ again: | |||
1070 | xfs_qm_dqrele(ip->i_udquot); | 1100 | xfs_qm_dqrele(ip->i_udquot); |
1071 | ip->i_udquot = NULL; | 1101 | ip->i_udquot = NULL; |
1072 | } | 1102 | } |
1073 | if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { | 1103 | if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) { |
1074 | xfs_qm_dqrele(ip->i_gdquot); | 1104 | xfs_qm_dqrele(ip->i_gdquot); |
1075 | ip->i_gdquot = NULL; | 1105 | ip->i_gdquot = NULL; |
1076 | } | 1106 | } |
@@ -1160,7 +1190,6 @@ xfs_qm_dqtest_print( | |||
1160 | { | 1190 | { |
1161 | cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); | 1191 | cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); |
1162 | cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); | 1192 | cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); |
1163 | cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP"); | ||
1164 | cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); | 1193 | cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); |
1165 | cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", | 1194 | cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", |
1166 | d->d_bcount, (int)d->d_bcount); | 1195 | d->d_bcount, (int)d->d_bcount); |
@@ -1231,7 +1260,7 @@ xfs_dqtest_cmp2( | |||
1231 | #ifdef QUOTADEBUG | 1260 | #ifdef QUOTADEBUG |
1232 | if (!err) { | 1261 | if (!err) { |
1233 | cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", | 1262 | cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", |
1234 | d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); | 1263 | d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount); |
1235 | } | 1264 | } |
1236 | #endif | 1265 | #endif |
1237 | return (err); | 1266 | return (err); |
@@ -1287,6 +1316,7 @@ STATIC void | |||
1287 | xfs_qm_internalqcheck_get_dquots( | 1316 | xfs_qm_internalqcheck_get_dquots( |
1288 | xfs_mount_t *mp, | 1317 | xfs_mount_t *mp, |
1289 | xfs_dqid_t uid, | 1318 | xfs_dqid_t uid, |
1319 | xfs_dqid_t projid, | ||
1290 | xfs_dqid_t gid, | 1320 | xfs_dqid_t gid, |
1291 | xfs_dqtest_t **ud, | 1321 | xfs_dqtest_t **ud, |
1292 | xfs_dqtest_t **gd) | 1322 | xfs_dqtest_t **gd) |
@@ -1295,6 +1325,8 @@ xfs_qm_internalqcheck_get_dquots( | |||
1295 | xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); | 1325 | xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); |
1296 | if (XFS_IS_GQUOTA_ON(mp)) | 1326 | if (XFS_IS_GQUOTA_ON(mp)) |
1297 | xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); | 1327 | xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); |
1328 | else if (XFS_IS_PQUOTA_ON(mp)) | ||
1329 | xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd); | ||
1298 | } | 1330 | } |
1299 | 1331 | ||
1300 | 1332 | ||
@@ -1362,13 +1394,14 @@ xfs_qm_internalqcheck_adjust( | |||
1362 | } | 1394 | } |
1363 | xfs_qm_internalqcheck_get_dquots(mp, | 1395 | xfs_qm_internalqcheck_get_dquots(mp, |
1364 | (xfs_dqid_t) ip->i_d.di_uid, | 1396 | (xfs_dqid_t) ip->i_d.di_uid, |
1397 | (xfs_dqid_t) ip->i_d.di_projid, | ||
1365 | (xfs_dqid_t) ip->i_d.di_gid, | 1398 | (xfs_dqid_t) ip->i_d.di_gid, |
1366 | &ud, &gd); | 1399 | &ud, &gd); |
1367 | if (XFS_IS_UQUOTA_ON(mp)) { | 1400 | if (XFS_IS_UQUOTA_ON(mp)) { |
1368 | ASSERT(ud); | 1401 | ASSERT(ud); |
1369 | xfs_qm_internalqcheck_dqadjust(ip, ud); | 1402 | xfs_qm_internalqcheck_dqadjust(ip, ud); |
1370 | } | 1403 | } |
1371 | if (XFS_IS_GQUOTA_ON(mp)) { | 1404 | if (XFS_IS_OQUOTA_ON(mp)) { |
1372 | ASSERT(gd); | 1405 | ASSERT(gd); |
1373 | xfs_qm_internalqcheck_dqadjust(ip, gd); | 1406 | xfs_qm_internalqcheck_dqadjust(ip, gd); |
1374 | } | 1407 | } |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index 675f03f443d2..472afd3570c6 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
@@ -102,7 +102,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) | |||
102 | (xfs_Gqm->qm_grp_dqhtable + \ | 102 | (xfs_Gqm->qm_grp_dqhtable + \ |
103 | XFS_DQ_HASHVAL(mp, id))) | 103 | XFS_DQ_HASHVAL(mp, id))) |
104 | #define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ | 104 | #define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ |
105 | XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp)) | 105 | XFS_IS_UQUOTA_ON(mp) : \ |
106 | XFS_IS_OQUOTA_ON(mp)) | ||
106 | #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ | 107 | #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ |
107 | !dqp->q_core.d_blk_hardlimit && \ | 108 | !dqp->q_core.d_blk_hardlimit && \ |
108 | !dqp->q_core.d_blk_softlimit && \ | 109 | !dqp->q_core.d_blk_softlimit && \ |
@@ -180,7 +181,8 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ | |||
180 | IRELE(ip); | 181 | IRELE(ip); |
181 | 182 | ||
182 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ | 183 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ |
183 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) | 184 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ |
185 | (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) | ||
184 | #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") | 186 | #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") |
185 | 187 | ||
186 | #endif /* __XFS_QUOTA_PRIV_H__ */ | 188 | #endif /* __XFS_QUOTA_PRIV_H__ */ |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 3644ca00cc82..565efb73c233 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino( | |||
207 | if (tp->t_dqinfo == NULL) | 207 | if (tp->t_dqinfo == NULL) |
208 | xfs_trans_alloc_dqinfo(tp); | 208 | xfs_trans_alloc_dqinfo(tp); |
209 | 209 | ||
210 | if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) { | 210 | if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) |
211 | (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); | 211 | (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); |
212 | } | 212 | if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot) |
213 | if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) { | ||
214 | (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); | 213 | (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); |
215 | } | ||
216 | } | 214 | } |
217 | 215 | ||
218 | STATIC xfs_dqtrx_t * | 216 | STATIC xfs_dqtrx_t * |
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 5f1b0c9308f6..01aed5f2d579 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h | |||
@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t { | |||
80 | * user or group dquots and may require special recovery handling. | 80 | * user or group dquots and may require special recovery handling. |
81 | */ | 81 | */ |
82 | #define XFS_BLI_UDQUOT_BUF 0x4 | 82 | #define XFS_BLI_UDQUOT_BUF 0x4 |
83 | /* #define XFS_BLI_PDQUOT_BUF 0x8 */ | 83 | #define XFS_BLI_PDQUOT_BUF 0x8 |
84 | #define XFS_BLI_GDQUOT_BUF 0x10 | 84 | #define XFS_BLI_GDQUOT_BUF 0x10 |
85 | 85 | ||
86 | #define XFS_BLI_CHUNK 128 | 86 | #define XFS_BLI_CHUNK 128 |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 593e597c86b2..91d764a5a9b2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer( | |||
1964 | * probably a good thing to do for other buf types also. | 1964 | * probably a good thing to do for other buf types also. |
1965 | */ | 1965 | */ |
1966 | error = 0; | 1966 | error = 0; |
1967 | if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { | 1967 | if (buf_f->blf_flags & |
1968 | (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { | ||
1968 | error = xfs_qm_dqcheck((xfs_disk_dquot_t *) | 1969 | error = xfs_qm_dqcheck((xfs_disk_dquot_t *) |
1969 | item->ri_buf[i].i_addr, | 1970 | item->ri_buf[i].i_addr, |
1970 | -1, 0, XFS_QMOPT_DOWARN, | 1971 | -1, 0, XFS_QMOPT_DOWARN, |
@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck( | |||
2030 | } | 2031 | } |
2031 | 2032 | ||
2032 | if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && | 2033 | if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && |
2034 | INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ && | ||
2033 | INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) { | 2035 | INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) { |
2034 | if (flags & XFS_QMOPT_DOWARN) | 2036 | if (flags & XFS_QMOPT_DOWARN) |
2035 | cmn_err(CE_ALERT, | 2037 | cmn_err(CE_ALERT, |
@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer( | |||
2135 | type = 0; | 2137 | type = 0; |
2136 | if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) | 2138 | if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) |
2137 | type |= XFS_DQ_USER; | 2139 | type |= XFS_DQ_USER; |
2140 | if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF) | ||
2141 | type |= XFS_DQ_PROJ; | ||
2138 | if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) | 2142 | if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) |
2139 | type |= XFS_DQ_GROUP; | 2143 | type |= XFS_DQ_GROUP; |
2140 | /* | 2144 | /* |
@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans( | |||
2247 | error = 0; | 2251 | error = 0; |
2248 | if (flags & XFS_BLI_INODE_BUF) { | 2252 | if (flags & XFS_BLI_INODE_BUF) { |
2249 | error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); | 2253 | error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); |
2250 | } else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) { | 2254 | } else if (flags & |
2255 | (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { | ||
2251 | xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); | 2256 | xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); |
2252 | } else { | 2257 | } else { |
2253 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); | 2258 | xlog_recover_do_reg_buffer(mp, item, bp, buf_f); |
@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans( | |||
2619 | * This type of quotas was turned off, so ignore this record. | 2624 | * This type of quotas was turned off, so ignore this record. |
2620 | */ | 2625 | */ |
2621 | type = INT_GET(recddq->d_flags, ARCH_CONVERT) & | 2626 | type = INT_GET(recddq->d_flags, ARCH_CONVERT) & |
2622 | (XFS_DQ_USER | XFS_DQ_GROUP); | 2627 | (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP); |
2623 | ASSERT(type); | 2628 | ASSERT(type); |
2624 | if (log->l_quotaoffs_flag & type) | 2629 | if (log->l_quotaoffs_flag & type) |
2625 | return (0); | 2630 | return (0); |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index cd5170ec73a3..5affba38a577 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint); | |||
141 | typedef void (*xfs_dqdetach_t)(struct xfs_inode *); | 141 | typedef void (*xfs_dqdetach_t)(struct xfs_inode *); |
142 | typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); | 142 | typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); |
143 | typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, | 143 | typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, |
144 | struct xfs_inode *, uid_t, gid_t, uint, | 144 | struct xfs_inode *, uid_t, gid_t, prid_t, uint, |
145 | struct xfs_dquot **, struct xfs_dquot **); | 145 | struct xfs_dquot **, struct xfs_dquot **); |
146 | typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, | 146 | typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, |
147 | struct xfs_dquot *, struct xfs_dquot *); | 147 | struct xfs_dquot *, struct xfs_dquot *); |
@@ -185,8 +185,8 @@ typedef struct xfs_qmops { | |||
185 | (*(mp)->m_qm_ops.xfs_dqdetach)(ip) | 185 | (*(mp)->m_qm_ops.xfs_dqdetach)(ip) |
186 | #define XFS_QM_DQPURGEALL(mp, fl) \ | 186 | #define XFS_QM_DQPURGEALL(mp, fl) \ |
187 | (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) | 187 | (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) |
188 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \ | 188 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ |
189 | (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2) | 189 | (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) |
190 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ | 190 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ |
191 | (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) | 191 | (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) |
192 | #define XFS_QM_DQVOPRENAME(mp, ip) \ | 192 | #define XFS_QM_DQVOPRENAME(mp, ip) \ |
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 703ec4efcb41..341cb4604c66 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -96,7 +96,7 @@ typedef struct xfs_dqblk { | |||
96 | * flags for q_flags field in the dquot. | 96 | * flags for q_flags field in the dquot. |
97 | */ | 97 | */ |
98 | #define XFS_DQ_USER 0x0001 /* a user quota */ | 98 | #define XFS_DQ_USER 0x0001 /* a user quota */ |
99 | /* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */ | 99 | #define XFS_DQ_PROJ 0x0002 /* project quota */ |
100 | #define XFS_DQ_GROUP 0x0004 /* a group quota */ | 100 | #define XFS_DQ_GROUP 0x0004 /* a group quota */ |
101 | #define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ | 101 | #define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ |
102 | #define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ | 102 | #define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ |
@@ -104,6 +104,8 @@ typedef struct xfs_dqblk { | |||
104 | #define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ | 104 | #define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ |
105 | #define XFS_DQ_MARKER 0x0080 /* sentinel */ | 105 | #define XFS_DQ_MARKER 0x0080 /* sentinel */ |
106 | 106 | ||
107 | #define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP) | ||
108 | |||
107 | /* | 109 | /* |
108 | * In the worst case, when both user and group quotas are on, | 110 | * In the worst case, when both user and group quotas are on, |
109 | * we can have a max of three dquots changing in a single transaction. | 111 | * we can have a max of three dquots changing in a single transaction. |
@@ -124,7 +126,7 @@ typedef struct xfs_dqblk { | |||
124 | typedef struct xfs_dq_logformat { | 126 | typedef struct xfs_dq_logformat { |
125 | __uint16_t qlf_type; /* dquot log item type */ | 127 | __uint16_t qlf_type; /* dquot log item type */ |
126 | __uint16_t qlf_size; /* size of this item */ | 128 | __uint16_t qlf_size; /* size of this item */ |
127 | xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */ | 129 | xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */ |
128 | __int64_t qlf_blkno; /* blkno of dquot buffer */ | 130 | __int64_t qlf_blkno; /* blkno of dquot buffer */ |
129 | __int32_t qlf_len; /* len of dquot buffer */ | 131 | __int32_t qlf_len; /* len of dquot buffer */ |
130 | __uint32_t qlf_boffset; /* off of dquot in buffer */ | 132 | __uint32_t qlf_boffset; /* off of dquot in buffer */ |
@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat { | |||
152 | #define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ | 154 | #define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ |
153 | #define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ | 155 | #define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ |
154 | #define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ | 156 | #define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ |
155 | #define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */ | 157 | #define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */ |
156 | #define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */ | 158 | #define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */ |
157 | #define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */ | 159 | #define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */ |
158 | #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ | 160 | #define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ |
159 | 161 | ||
160 | /* | 162 | /* |
@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat { | |||
162 | * are in the process of getting turned off. These flags are in m_qflags but | 164 | * are in the process of getting turned off. These flags are in m_qflags but |
163 | * never in sb_qflags. | 165 | * never in sb_qflags. |
164 | */ | 166 | */ |
165 | #define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */ | 167 | #define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */ |
166 | #define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas are being turned off */ | 168 | #define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */ |
169 | #define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */ | ||
167 | 170 | ||
168 | /* | 171 | /* |
169 | * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees | 172 | * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees |
170 | * quota will be not be switched off as long as that inode lock is held. | 173 | * quota will be not be switched off as long as that inode lock is held. |
171 | */ | 174 | */ |
172 | #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ | 175 | #define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ |
173 | XFS_GQUOTA_ACTIVE)) | 176 | XFS_GQUOTA_ACTIVE | \ |
177 | XFS_PQUOTA_ACTIVE)) | ||
178 | #define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \ | ||
179 | XFS_PQUOTA_ACTIVE)) | ||
174 | #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) | 180 | #define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) |
175 | #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) | 181 | #define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) |
182 | #define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) | ||
176 | 183 | ||
177 | /* | 184 | /* |
178 | * Flags to tell various functions what to do. Not all of these are meaningful | 185 | * Flags to tell various functions what to do. Not all of these are meaningful |
@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat { | |||
182 | #define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ | 189 | #define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ |
183 | #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ | 190 | #define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ |
184 | #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ | 191 | #define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ |
185 | #define XFS_QMOPT_GQUOTA 0x0000008 /* group dquot requested */ | 192 | #define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */ |
186 | #define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ | 193 | #define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ |
187 | #define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ | 194 | #define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ |
188 | #define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ | 195 | #define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ |
@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat { | |||
192 | #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ | 199 | #define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ |
193 | #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ | 200 | #define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ |
194 | #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ | 201 | #define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ |
202 | #define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ | ||
195 | 203 | ||
196 | /* | 204 | /* |
197 | * flags to xfs_trans_mod_dquot to indicate which field needs to be | 205 | * flags to xfs_trans_mod_dquot to indicate which field needs to be |
@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat { | |||
231 | #define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT | 239 | #define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT |
232 | 240 | ||
233 | 241 | ||
234 | #define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA) | 242 | #define XFS_QMOPT_QUOTALL \ |
243 | (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA) | ||
235 | #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) | 244 | #define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) |
236 | 245 | ||
237 | #ifdef __KERNEL__ | 246 | #ifdef __KERNEL__ |
@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat { | |||
246 | */ | 255 | */ |
247 | #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ | 256 | #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ |
248 | (ip)->i_udquot == NULL) || \ | 257 | (ip)->i_udquot == NULL) || \ |
249 | (XFS_IS_GQUOTA_ON(mp) && \ | 258 | (XFS_IS_OQUOTA_ON(mp) && \ |
250 | (ip)->i_gdquot == NULL)) | 259 | (ip)->i_gdquot == NULL)) |
251 | 260 | ||
252 | #define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \ | 261 | #define XFS_QM_NEED_QUOTACHECK(mp) \ |
253 | (mp->m_sb.sb_qflags & \ | 262 | ((XFS_IS_UQUOTA_ON(mp) && \ |
254 | XFS_UQUOTA_CHKD) == 0) || \ | 263 | (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \ |
255 | (XFS_IS_GQUOTA_ON(mp) && \ | 264 | (XFS_IS_GQUOTA_ON(mp) && \ |
256 | (mp->m_sb.sb_qflags & \ | 265 | ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ |
257 | XFS_GQUOTA_CHKD) == 0)) | 266 | (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \ |
267 | (XFS_IS_PQUOTA_ON(mp) && \ | ||
268 | ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \ | ||
269 | (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT)))) | ||
270 | |||
271 | #define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ | ||
272 | XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ | ||
273 | XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) | ||
274 | |||
275 | #define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ | ||
276 | XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ | ||
277 | XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD) | ||
258 | 278 | ||
259 | #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ | 279 | #define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ |
260 | XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ | 280 | XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ |
261 | XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD) | 281 | XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ |
282 | XFS_GQUOTA_ACCT) | ||
262 | #define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ | 283 | #define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ |
263 | XFS_GQUOTA_ACTIVE) | 284 | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) |
264 | 285 | ||
265 | 286 | ||
266 | /* | 287 | /* |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index a9682b9510c1..144da7a85466 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -976,6 +976,7 @@ xfs_trans_dquot_buf( | |||
976 | ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); | 976 | ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); |
977 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); | 977 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); |
978 | ASSERT(type == XFS_BLI_UDQUOT_BUF || | 978 | ASSERT(type == XFS_BLI_UDQUOT_BUF || |
979 | type == XFS_BLI_PDQUOT_BUF || | ||
979 | type == XFS_BLI_GDQUOT_BUF); | 980 | type == XFS_BLI_GDQUOT_BUF); |
980 | 981 | ||
981 | bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); | 982 | bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index d1f8146a06ea..11351f08d438 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -428,7 +428,7 @@ xfs_truncate_file( | |||
428 | if (ip->i_ino != mp->m_sb.sb_uquotino) | 428 | if (ip->i_ino != mp->m_sb.sb_uquotino) |
429 | ASSERT(ip->i_udquot); | 429 | ASSERT(ip->i_udquot); |
430 | } | 430 | } |
431 | if (XFS_IS_GQUOTA_ON(mp)) { | 431 | if (XFS_IS_OQUOTA_ON(mp)) { |
432 | if (ip->i_ino != mp->m_sb.sb_gquotino) | 432 | if (ip->i_ino != mp->m_sb.sb_gquotino) |
433 | ASSERT(ip->i_gdquot); | 433 | ASSERT(ip->i_gdquot); |
434 | } | 434 | } |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index fb1ae6cfb1f3..103500498342 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -368,16 +368,6 @@ xfs_finish_flags( | |||
368 | } | 368 | } |
369 | 369 | ||
370 | /* | 370 | /* |
371 | * disallow mount attempts with (IRIX) project quota enabled | ||
372 | */ | ||
373 | if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | ||
374 | (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) { | ||
375 | cmn_err(CE_WARN, | ||
376 | "XFS: cannot mount a filesystem with IRIX project quota enabled"); | ||
377 | return XFS_ERROR(ENOSYS); | ||
378 | } | ||
379 | |||
380 | /* | ||
381 | * check for shared mount. | 371 | * check for shared mount. |
382 | */ | 372 | */ |
383 | if (ap->flags & XFSMNT_SHARED) { | 373 | if (ap->flags & XFSMNT_SHARED) { |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 5703783991fa..695978b27497 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -351,21 +351,28 @@ xfs_setattr( | |||
351 | * If the IDs do change before we take the ilock, we're covered | 351 | * If the IDs do change before we take the ilock, we're covered |
352 | * because the i_*dquot fields will get updated anyway. | 352 | * because the i_*dquot fields will get updated anyway. |
353 | */ | 353 | */ |
354 | if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { | 354 | if (XFS_IS_QUOTA_ON(mp) && |
355 | (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) { | ||
355 | uint qflags = 0; | 356 | uint qflags = 0; |
356 | 357 | ||
357 | if (mask & XFS_AT_UID) { | 358 | if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) { |
358 | uid = vap->va_uid; | 359 | uid = vap->va_uid; |
359 | qflags |= XFS_QMOPT_UQUOTA; | 360 | qflags |= XFS_QMOPT_UQUOTA; |
360 | } else { | 361 | } else { |
361 | uid = ip->i_d.di_uid; | 362 | uid = ip->i_d.di_uid; |
362 | } | 363 | } |
363 | if (mask & XFS_AT_GID) { | 364 | if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) { |
364 | gid = vap->va_gid; | 365 | gid = vap->va_gid; |
365 | qflags |= XFS_QMOPT_GQUOTA; | 366 | qflags |= XFS_QMOPT_GQUOTA; |
366 | } else { | 367 | } else { |
367 | gid = ip->i_d.di_gid; | 368 | gid = ip->i_d.di_gid; |
368 | } | 369 | } |
370 | if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) { | ||
371 | projid = vap->va_projid; | ||
372 | qflags |= XFS_QMOPT_PQUOTA; | ||
373 | } else { | ||
374 | projid = ip->i_d.di_projid; | ||
375 | } | ||
369 | /* | 376 | /* |
370 | * We take a reference when we initialize udqp and gdqp, | 377 | * We take a reference when we initialize udqp and gdqp, |
371 | * so it is important that we never blindly double trip on | 378 | * so it is important that we never blindly double trip on |
@@ -373,7 +380,8 @@ xfs_setattr( | |||
373 | */ | 380 | */ |
374 | ASSERT(udqp == NULL); | 381 | ASSERT(udqp == NULL); |
375 | ASSERT(gdqp == NULL); | 382 | ASSERT(gdqp == NULL); |
376 | code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); | 383 | code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags, |
384 | &udqp, &gdqp); | ||
377 | if (code) | 385 | if (code) |
378 | return (code); | 386 | return (code); |
379 | } | 387 | } |
@@ -510,10 +518,11 @@ xfs_setattr( | |||
510 | goto error_return; | 518 | goto error_return; |
511 | } | 519 | } |
512 | /* | 520 | /* |
513 | * Do a quota reservation only if uid or gid is actually | 521 | * Do a quota reservation only if uid/projid/gid is actually |
514 | * going to change. | 522 | * going to change. |
515 | */ | 523 | */ |
516 | if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || | 524 | if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || |
525 | (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) || | ||
517 | (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { | 526 | (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { |
518 | ASSERT(tp); | 527 | ASSERT(tp); |
519 | code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, | 528 | code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, |
@@ -774,6 +783,7 @@ xfs_setattr( | |||
774 | } | 783 | } |
775 | if (igid != gid) { | 784 | if (igid != gid) { |
776 | if (XFS_IS_GQUOTA_ON(mp)) { | 785 | if (XFS_IS_GQUOTA_ON(mp)) { |
786 | ASSERT(!XFS_IS_PQUOTA_ON(mp)); | ||
777 | ASSERT(mask & XFS_AT_GID); | 787 | ASSERT(mask & XFS_AT_GID); |
778 | ASSERT(gdqp); | 788 | ASSERT(gdqp); |
779 | olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, | 789 | olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, |
@@ -782,6 +792,13 @@ xfs_setattr( | |||
782 | ip->i_d.di_gid = gid; | 792 | ip->i_d.di_gid = gid; |
783 | } | 793 | } |
784 | if (iprojid != projid) { | 794 | if (iprojid != projid) { |
795 | if (XFS_IS_PQUOTA_ON(mp)) { | ||
796 | ASSERT(!XFS_IS_GQUOTA_ON(mp)); | ||
797 | ASSERT(mask & XFS_AT_PROJID); | ||
798 | ASSERT(gdqp); | ||
799 | olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, | ||
800 | &ip->i_gdquot, gdqp); | ||
801 | } | ||
785 | ip->i_d.di_projid = projid; | 802 | ip->i_d.di_projid = projid; |
786 | /* | 803 | /* |
787 | * We may have to rev the inode as well as | 804 | * We may have to rev the inode as well as |
@@ -1907,7 +1924,7 @@ xfs_create( | |||
1907 | * Make sure that we have allocated dquot(s) on disk. | 1924 | * Make sure that we have allocated dquot(s) on disk. |
1908 | */ | 1925 | */ |
1909 | error = XFS_QM_DQVOPALLOC(mp, dp, | 1926 | error = XFS_QM_DQVOPALLOC(mp, dp, |
1910 | current_fsuid(credp), current_fsgid(credp), | 1927 | current_fsuid(credp), current_fsgid(credp), prid, |
1911 | XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); | 1928 | XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); |
1912 | if (error) | 1929 | if (error) |
1913 | goto std_return; | 1930 | goto std_return; |
@@ -2812,7 +2829,7 @@ xfs_mkdir( | |||
2812 | * Make sure that we have allocated dquot(s) on disk. | 2829 | * Make sure that we have allocated dquot(s) on disk. |
2813 | */ | 2830 | */ |
2814 | error = XFS_QM_DQVOPALLOC(mp, dp, | 2831 | error = XFS_QM_DQVOPALLOC(mp, dp, |
2815 | current_fsuid(credp), current_fsgid(credp), | 2832 | current_fsuid(credp), current_fsgid(credp), prid, |
2816 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | 2833 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); |
2817 | if (error) | 2834 | if (error) |
2818 | goto std_return; | 2835 | goto std_return; |
@@ -3366,7 +3383,7 @@ xfs_symlink( | |||
3366 | * Make sure that we have allocated dquot(s) on disk. | 3383 | * Make sure that we have allocated dquot(s) on disk. |
3367 | */ | 3384 | */ |
3368 | error = XFS_QM_DQVOPALLOC(mp, dp, | 3385 | error = XFS_QM_DQVOPALLOC(mp, dp, |
3369 | current_fsuid(credp), current_fsgid(credp), | 3386 | current_fsuid(credp), current_fsgid(credp), prid, |
3370 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | 3387 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); |
3371 | if (error) | 3388 | if (error) |
3372 | goto std_return; | 3389 | goto std_return; |