diff options
| -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; |
