aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_qm.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r--fs/xfs/quota/xfs_qm.c168
1 files changed, 78 insertions, 90 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 5b6695049e00..45b1bfef7388 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -42,7 +42,6 @@
42#include "xfs_error.h" 42#include "xfs_error.h"
43#include "xfs_bmap.h" 43#include "xfs_bmap.h"
44#include "xfs_rw.h" 44#include "xfs_rw.h"
45#include "xfs_acl.h"
46#include "xfs_attr.h" 45#include "xfs_attr.h"
47#include "xfs_buf_item.h" 46#include "xfs_buf_item.h"
48#include "xfs_trans_space.h" 47#include "xfs_trans_space.h"
@@ -287,11 +286,13 @@ xfs_qm_rele_quotafs_ref(
287 * Just destroy the quotainfo structure. 286 * Just destroy the quotainfo structure.
288 */ 287 */
289void 288void
290xfs_qm_unmount_quotadestroy( 289xfs_qm_unmount(
291 xfs_mount_t *mp) 290 struct xfs_mount *mp)
292{ 291{
293 if (mp->m_quotainfo) 292 if (mp->m_quotainfo) {
293 xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING);
294 xfs_qm_destroy_quotainfo(mp); 294 xfs_qm_destroy_quotainfo(mp);
295 }
295} 296}
296 297
297 298
@@ -385,8 +386,13 @@ xfs_qm_mount_quotas(
385 if (error) { 386 if (error) {
386 xfs_fs_cmn_err(CE_WARN, mp, 387 xfs_fs_cmn_err(CE_WARN, mp,
387 "Failed to initialize disk quotas."); 388 "Failed to initialize disk quotas.");
389 return;
388 } 390 }
389 return; 391
392#ifdef QUOTADEBUG
393 if (XFS_IS_QUOTA_ON(mp))
394 xfs_qm_internalqcheck(mp);
395#endif
390} 396}
391 397
392/* 398/*
@@ -774,12 +780,11 @@ xfs_qm_dqattach_grouphint(
774 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON 780 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
775 * into account. 781 * into account.
776 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. 782 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
777 * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
778 * Inode may get unlocked and relocked in here, and the caller must deal with 783 * Inode may get unlocked and relocked in here, and the caller must deal with
779 * the consequences. 784 * the consequences.
780 */ 785 */
781int 786int
782xfs_qm_dqattach( 787xfs_qm_dqattach_locked(
783 xfs_inode_t *ip, 788 xfs_inode_t *ip,
784 uint flags) 789 uint flags)
785{ 790{
@@ -787,17 +792,14 @@ xfs_qm_dqattach(
787 uint nquotas = 0; 792 uint nquotas = 0;
788 int error = 0; 793 int error = 0;
789 794
790 if ((! XFS_IS_QUOTA_ON(mp)) || 795 if (!XFS_IS_QUOTA_RUNNING(mp) ||
791 (! XFS_NOT_DQATTACHED(mp, ip)) || 796 !XFS_IS_QUOTA_ON(mp) ||
792 (ip->i_ino == mp->m_sb.sb_uquotino) || 797 !XFS_NOT_DQATTACHED(mp, ip) ||
793 (ip->i_ino == mp->m_sb.sb_gquotino)) 798 ip->i_ino == mp->m_sb.sb_uquotino ||
799 ip->i_ino == mp->m_sb.sb_gquotino)
794 return 0; 800 return 0;
795 801
796 ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 || 802 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
797 xfs_isilocked(ip, XFS_ILOCK_EXCL));
798
799 if (! (flags & XFS_QMOPT_ILOCKED))
800 xfs_ilock(ip, XFS_ILOCK_EXCL);
801 803
802 if (XFS_IS_UQUOTA_ON(mp)) { 804 if (XFS_IS_UQUOTA_ON(mp)) {
803 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, 805 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
@@ -849,8 +851,7 @@ xfs_qm_dqattach(
849 xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot); 851 xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
850 } 852 }
851 853
852 done: 854 done:
853
854#ifdef QUOTADEBUG 855#ifdef QUOTADEBUG
855 if (! error) { 856 if (! error) {
856 if (XFS_IS_UQUOTA_ON(mp)) 857 if (XFS_IS_UQUOTA_ON(mp))
@@ -858,15 +859,22 @@ xfs_qm_dqattach(
858 if (XFS_IS_OQUOTA_ON(mp)) 859 if (XFS_IS_OQUOTA_ON(mp))
859 ASSERT(ip->i_gdquot); 860 ASSERT(ip->i_gdquot);
860 } 861 }
862 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
861#endif 863#endif
864 return error;
865}
862 866
863 if (! (flags & XFS_QMOPT_ILOCKED)) 867int
864 xfs_iunlock(ip, XFS_ILOCK_EXCL); 868xfs_qm_dqattach(
869 struct xfs_inode *ip,
870 uint flags)
871{
872 int error;
873
874 xfs_ilock(ip, XFS_ILOCK_EXCL);
875 error = xfs_qm_dqattach_locked(ip, flags);
876 xfs_iunlock(ip, XFS_ILOCK_EXCL);
865 877
866#ifdef QUOTADEBUG
867 else
868 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
869#endif
870 return error; 878 return error;
871} 879}
872 880
@@ -896,11 +904,6 @@ xfs_qm_dqdetach(
896 } 904 }
897} 905}
898 906
899/*
900 * This is called to sync quotas. We can be told to use non-blocking
901 * semantics by either the SYNC_BDFLUSH flag or the absence of the
902 * SYNC_WAIT flag.
903 */
904int 907int
905xfs_qm_sync( 908xfs_qm_sync(
906 xfs_mount_t *mp, 909 xfs_mount_t *mp,
@@ -909,17 +912,13 @@ xfs_qm_sync(
909 int recl, restarts; 912 int recl, restarts;
910 xfs_dquot_t *dqp; 913 xfs_dquot_t *dqp;
911 uint flush_flags; 914 uint flush_flags;
912 boolean_t nowait;
913 int error; 915 int error;
914 916
915 if (! XFS_IS_QUOTA_ON(mp)) 917 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
916 return 0; 918 return 0;
917 919
920 flush_flags = (flags & SYNC_WAIT) ? XFS_QMOPT_SYNC : XFS_QMOPT_DELWRI;
918 restarts = 0; 921 restarts = 0;
919 /*
920 * We won't block unless we are asked to.
921 */
922 nowait = (boolean_t)(flags & SYNC_BDFLUSH || (flags & SYNC_WAIT) == 0);
923 922
924 again: 923 again:
925 xfs_qm_mplist_lock(mp); 924 xfs_qm_mplist_lock(mp);
@@ -939,18 +938,10 @@ xfs_qm_sync(
939 * don't 'seem' to be dirty. ie. don't acquire dqlock. 938 * don't 'seem' to be dirty. ie. don't acquire dqlock.
940 * This is very similar to what xfs_sync does with inodes. 939 * This is very similar to what xfs_sync does with inodes.
941 */ 940 */
942 if (flags & SYNC_BDFLUSH) { 941 if (flags & SYNC_TRYLOCK) {
943 if (! XFS_DQ_IS_DIRTY(dqp)) 942 if (!XFS_DQ_IS_DIRTY(dqp))
944 continue; 943 continue;
945 } 944 if (!xfs_qm_dqlock_nowait(dqp))
946
947 if (nowait) {
948 /*
949 * Try to acquire the dquot lock. We are NOT out of
950 * lock order, but we just don't want to wait for this
951 * lock, unless somebody wanted us to.
952 */
953 if (! xfs_qm_dqlock_nowait(dqp))
954 continue; 945 continue;
955 } else { 946 } else {
956 xfs_dqlock(dqp); 947 xfs_dqlock(dqp);
@@ -967,7 +958,7 @@ xfs_qm_sync(
967 /* XXX a sentinel would be better */ 958 /* XXX a sentinel would be better */
968 recl = XFS_QI_MPLRECLAIMS(mp); 959 recl = XFS_QI_MPLRECLAIMS(mp);
969 if (!xfs_dqflock_nowait(dqp)) { 960 if (!xfs_dqflock_nowait(dqp)) {
970 if (nowait) { 961 if (flags & SYNC_TRYLOCK) {
971 xfs_dqunlock(dqp); 962 xfs_dqunlock(dqp);
972 continue; 963 continue;
973 } 964 }
@@ -985,7 +976,6 @@ xfs_qm_sync(
985 * Let go of the mplist lock. We don't want to hold it 976 * Let go of the mplist lock. We don't want to hold it
986 * across a disk write 977 * across a disk write
987 */ 978 */
988 flush_flags = (nowait) ? XFS_QMOPT_DELWRI : XFS_QMOPT_SYNC;
989 xfs_qm_mplist_unlock(mp); 979 xfs_qm_mplist_unlock(mp);
990 xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH"); 980 xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH");
991 error = xfs_qm_dqflush(dqp, flush_flags); 981 error = xfs_qm_dqflush(dqp, flush_flags);
@@ -2319,20 +2309,20 @@ xfs_qm_write_sb_changes(
2319 */ 2309 */
2320int 2310int
2321xfs_qm_vop_dqalloc( 2311xfs_qm_vop_dqalloc(
2322 xfs_mount_t *mp, 2312 struct xfs_inode *ip,
2323 xfs_inode_t *ip, 2313 uid_t uid,
2324 uid_t uid, 2314 gid_t gid,
2325 gid_t gid, 2315 prid_t prid,
2326 prid_t prid, 2316 uint flags,
2327 uint flags, 2317 struct xfs_dquot **O_udqpp,
2328 xfs_dquot_t **O_udqpp, 2318 struct xfs_dquot **O_gdqpp)
2329 xfs_dquot_t **O_gdqpp)
2330{ 2319{
2331 int error; 2320 struct xfs_mount *mp = ip->i_mount;
2332 xfs_dquot_t *uq, *gq; 2321 struct xfs_dquot *uq, *gq;
2333 uint lockflags; 2322 int error;
2323 uint lockflags;
2334 2324
2335 if (!XFS_IS_QUOTA_ON(mp)) 2325 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
2336 return 0; 2326 return 0;
2337 2327
2338 lockflags = XFS_ILOCK_EXCL; 2328 lockflags = XFS_ILOCK_EXCL;
@@ -2346,8 +2336,8 @@ xfs_qm_vop_dqalloc(
2346 * if necessary. The dquot(s) will not be locked. 2336 * if necessary. The dquot(s) will not be locked.
2347 */ 2337 */
2348 if (XFS_NOT_DQATTACHED(mp, ip)) { 2338 if (XFS_NOT_DQATTACHED(mp, ip)) {
2349 if ((error = xfs_qm_dqattach(ip, XFS_QMOPT_DQALLOC | 2339 error = xfs_qm_dqattach_locked(ip, XFS_QMOPT_DQALLOC);
2350 XFS_QMOPT_ILOCKED))) { 2340 if (error) {
2351 xfs_iunlock(ip, lockflags); 2341 xfs_iunlock(ip, lockflags);
2352 return error; 2342 return error;
2353 } 2343 }
@@ -2469,6 +2459,7 @@ xfs_qm_vop_chown(
2469 uint bfield = XFS_IS_REALTIME_INODE(ip) ? 2459 uint bfield = XFS_IS_REALTIME_INODE(ip) ?
2470 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; 2460 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
2471 2461
2462
2472 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 2463 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2473 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 2464 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
2474 2465
@@ -2508,13 +2499,13 @@ xfs_qm_vop_chown_reserve(
2508 xfs_dquot_t *gdqp, 2499 xfs_dquot_t *gdqp,
2509 uint flags) 2500 uint flags)
2510{ 2501{
2511 int error; 2502 xfs_mount_t *mp = ip->i_mount;
2512 xfs_mount_t *mp;
2513 uint delblks, blkflags, prjflags = 0; 2503 uint delblks, blkflags, prjflags = 0;
2514 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2504 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2505 int error;
2506
2515 2507
2516 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2508 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2517 mp = ip->i_mount;
2518 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 2509 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
2519 2510
2520 delblks = ip->i_delayed_blks; 2511 delblks = ip->i_delayed_blks;
@@ -2582,28 +2573,23 @@ xfs_qm_vop_chown_reserve(
2582 2573
2583int 2574int
2584xfs_qm_vop_rename_dqattach( 2575xfs_qm_vop_rename_dqattach(
2585 xfs_inode_t **i_tab) 2576 struct xfs_inode **i_tab)
2586{ 2577{
2587 xfs_inode_t *ip; 2578 struct xfs_mount *mp = i_tab[0]->i_mount;
2588 int i; 2579 int i;
2589 int error;
2590 2580
2591 ip = i_tab[0]; 2581 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
2592
2593 if (! XFS_IS_QUOTA_ON(ip->i_mount))
2594 return 0; 2582 return 0;
2595 2583
2596 if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) { 2584 for (i = 0; (i < 4 && i_tab[i]); i++) {
2597 error = xfs_qm_dqattach(ip, 0); 2585 struct xfs_inode *ip = i_tab[i];
2598 if (error) 2586 int error;
2599 return error; 2587
2600 }
2601 for (i = 1; (i < 4 && i_tab[i]); i++) {
2602 /* 2588 /*
2603 * Watch out for duplicate entries in the table. 2589 * Watch out for duplicate entries in the table.
2604 */ 2590 */
2605 if ((ip = i_tab[i]) != i_tab[i-1]) { 2591 if (i == 0 || ip != i_tab[i-1]) {
2606 if (XFS_NOT_DQATTACHED(ip->i_mount, ip)) { 2592 if (XFS_NOT_DQATTACHED(mp, ip)) {
2607 error = xfs_qm_dqattach(ip, 0); 2593 error = xfs_qm_dqattach(ip, 0);
2608 if (error) 2594 if (error)
2609 return error; 2595 return error;
@@ -2614,17 +2600,19 @@ xfs_qm_vop_rename_dqattach(
2614} 2600}
2615 2601
2616void 2602void
2617xfs_qm_vop_dqattach_and_dqmod_newinode( 2603xfs_qm_vop_create_dqattach(
2618 xfs_trans_t *tp, 2604 struct xfs_trans *tp,
2619 xfs_inode_t *ip, 2605 struct xfs_inode *ip,
2620 xfs_dquot_t *udqp, 2606 struct xfs_dquot *udqp,
2621 xfs_dquot_t *gdqp) 2607 struct xfs_dquot *gdqp)
2622{ 2608{
2623 if (!XFS_IS_QUOTA_ON(tp->t_mountp)) 2609 struct xfs_mount *mp = tp->t_mountp;
2610
2611 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
2624 return; 2612 return;
2625 2613
2626 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 2614 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2627 ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp)); 2615 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
2628 2616
2629 if (udqp) { 2617 if (udqp) {
2630 xfs_dqlock(udqp); 2618 xfs_dqlock(udqp);
@@ -2632,7 +2620,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
2632 xfs_dqunlock(udqp); 2620 xfs_dqunlock(udqp);
2633 ASSERT(ip->i_udquot == NULL); 2621 ASSERT(ip->i_udquot == NULL);
2634 ip->i_udquot = udqp; 2622 ip->i_udquot = udqp;
2635 ASSERT(XFS_IS_UQUOTA_ON(tp->t_mountp)); 2623 ASSERT(XFS_IS_UQUOTA_ON(mp));
2636 ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id)); 2624 ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
2637 xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1); 2625 xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
2638 } 2626 }
@@ -2642,8 +2630,8 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
2642 xfs_dqunlock(gdqp); 2630 xfs_dqunlock(gdqp);
2643 ASSERT(ip->i_gdquot == NULL); 2631 ASSERT(ip->i_gdquot == NULL);
2644 ip->i_gdquot = gdqp; 2632 ip->i_gdquot = gdqp;
2645 ASSERT(XFS_IS_OQUOTA_ON(tp->t_mountp)); 2633 ASSERT(XFS_IS_OQUOTA_ON(mp));
2646 ASSERT((XFS_IS_GQUOTA_ON(tp->t_mountp) ? 2634 ASSERT((XFS_IS_GQUOTA_ON(mp) ?
2647 ip->i_d.di_gid : ip->i_d.di_projid) == 2635 ip->i_d.di_gid : ip->i_d.di_projid) ==
2648 be32_to_cpu(gdqp->q_core.d_id)); 2636 be32_to_cpu(gdqp->q_core.d_id));
2649 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1); 2637 xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);