diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 142 |
1 files changed, 95 insertions, 47 deletions
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 | ||