diff options
author | Dave Chinner <dchinner@redhat.com> | 2010-04-13 01:06:48 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-05-19 10:58:10 -0400 |
commit | 3a25404b3fccd41d36b2fda18d86011201608c38 (patch) | |
tree | 28979d8581760327c16a3389a2eb8752ed3f0665 /fs/xfs/quota/xfs_qm.c | |
parent | 9abbc539bf7f299819ad0a235064a1b643ab6407 (diff) |
xfs: convert the per-mount dquot list to use list heads
Convert the dquot list on the filesytesm to use listhead
infrastructure rather than the roll-your-own in the quota code.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 155 |
1 files changed, 80 insertions, 75 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 417e61e3d9dd..855827320ff6 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -84,21 +84,25 @@ extern struct mutex qcheck_lock; | |||
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | #ifdef QUOTADEBUG | 86 | #ifdef QUOTADEBUG |
87 | #define XQM_LIST_PRINT(l, NXT, title) \ | 87 | static void |
88 | { \ | 88 | xfs_qm_dquot_list_print( |
89 | xfs_dquot_t *dqp; int i = 0; \ | 89 | struct xfs_mount *mp) |
90 | cmn_err(CE_DEBUG, "%s (#%d)", title, (int) (l)->qh_nelems); \ | 90 | { |
91 | for (dqp = (l)->qh_next; dqp != NULL; dqp = dqp->NXT) { \ | 91 | xfs_dquot_t *dqp; |
92 | cmn_err(CE_DEBUG, " %d. \"%d (%s)\" " \ | 92 | int i = 0; |
93 | "bcnt = %d, icnt = %d, refs = %d", \ | 93 | |
94 | ++i, (int) be32_to_cpu(dqp->q_core.d_id), \ | 94 | list_for_each_entry(dqp, &mp->m_quotainfo->qi_dqlist_lock, qi_mplist) { |
95 | DQFLAGTO_TYPESTR(dqp), \ | 95 | cmn_err(CE_DEBUG, " %d. \"%d (%s)\" " |
96 | (int) be64_to_cpu(dqp->q_core.d_bcount), \ | 96 | "bcnt = %lld, icnt = %lld, refs = %d", |
97 | (int) be64_to_cpu(dqp->q_core.d_icount), \ | 97 | i++, be32_to_cpu(dqp->q_core.d_id), |
98 | (int) dqp->q_nrefs); } \ | 98 | DQFLAGTO_TYPESTR(dqp), |
99 | (long long)be64_to_cpu(dqp->q_core.d_bcount), | ||
100 | (long long)be64_to_cpu(dqp->q_core.d_icount), | ||
101 | dqp->q_nrefs); | ||
102 | } | ||
99 | } | 103 | } |
100 | #else | 104 | #else |
101 | #define XQM_LIST_PRINT(l, NXT, title) do { } while (0) | 105 | static void xfs_qm_dquot_list_print(struct xfs_mount *mp) { } |
102 | #endif | 106 | #endif |
103 | 107 | ||
104 | /* | 108 | /* |
@@ -274,7 +278,7 @@ xfs_qm_rele_quotafs_ref( | |||
274 | ASSERT(dqp->q_mount == NULL); | 278 | ASSERT(dqp->q_mount == NULL); |
275 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); | 279 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); |
276 | ASSERT(dqp->HL_PREVP == NULL); | 280 | ASSERT(dqp->HL_PREVP == NULL); |
277 | ASSERT(dqp->MPL_PREVP == NULL); | 281 | ASSERT(list_empty(&dqp->q_mplist)); |
278 | XQM_FREELIST_REMOVE(dqp); | 282 | XQM_FREELIST_REMOVE(dqp); |
279 | xfs_dqunlock(dqp); | 283 | xfs_dqunlock(dqp); |
280 | xfs_qm_dqdestroy(dqp); | 284 | xfs_qm_dqdestroy(dqp); |
@@ -461,8 +465,8 @@ xfs_qm_dqflush_all( | |||
461 | return 0; | 465 | return 0; |
462 | niters = 0; | 466 | niters = 0; |
463 | again: | 467 | again: |
464 | xfs_qm_mplist_lock(mp); | 468 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
465 | FOREACH_DQUOT_IN_MP(dqp, mp) { | 469 | list_for_each_entry(dqp, &mp->m_quotainfo->qi_dqlist, q_mplist) { |
466 | xfs_dqlock(dqp); | 470 | xfs_dqlock(dqp); |
467 | if (! XFS_DQ_IS_DIRTY(dqp)) { | 471 | if (! XFS_DQ_IS_DIRTY(dqp)) { |
468 | xfs_dqunlock(dqp); | 472 | xfs_dqunlock(dqp); |
@@ -470,7 +474,7 @@ again: | |||
470 | } | 474 | } |
471 | 475 | ||
472 | /* XXX a sentinel would be better */ | 476 | /* XXX a sentinel would be better */ |
473 | recl = XFS_QI_MPLRECLAIMS(mp); | 477 | recl = mp->m_quotainfo->qi_dqreclaims; |
474 | if (!xfs_dqflock_nowait(dqp)) { | 478 | if (!xfs_dqflock_nowait(dqp)) { |
475 | /* | 479 | /* |
476 | * If we can't grab the flush lock then check | 480 | * If we can't grab the flush lock then check |
@@ -485,21 +489,21 @@ again: | |||
485 | * Let go of the mplist lock. We don't want to hold it | 489 | * Let go of the mplist lock. We don't want to hold it |
486 | * across a disk write. | 490 | * across a disk write. |
487 | */ | 491 | */ |
488 | xfs_qm_mplist_unlock(mp); | 492 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
489 | error = xfs_qm_dqflush(dqp, sync_mode); | 493 | error = xfs_qm_dqflush(dqp, sync_mode); |
490 | xfs_dqunlock(dqp); | 494 | xfs_dqunlock(dqp); |
491 | if (error) | 495 | if (error) |
492 | return error; | 496 | return error; |
493 | 497 | ||
494 | xfs_qm_mplist_lock(mp); | 498 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
495 | if (recl != XFS_QI_MPLRECLAIMS(mp)) { | 499 | if (recl != mp->m_quotainfo->qi_dqreclaims) { |
496 | xfs_qm_mplist_unlock(mp); | 500 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
497 | /* XXX restart limit */ | 501 | /* XXX restart limit */ |
498 | goto again; | 502 | goto again; |
499 | } | 503 | } |
500 | } | 504 | } |
501 | 505 | ||
502 | xfs_qm_mplist_unlock(mp); | 506 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
503 | /* return ! busy */ | 507 | /* return ! busy */ |
504 | return 0; | 508 | return 0; |
505 | } | 509 | } |
@@ -515,9 +519,8 @@ xfs_qm_detach_gdquots( | |||
515 | int nrecl; | 519 | int nrecl; |
516 | 520 | ||
517 | again: | 521 | again: |
518 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); | 522 | ASSERT(mutex_is_locked(&mp->m_quotainfo->qi_dqlist_lock)); |
519 | dqp = XFS_QI_MPLNEXT(mp); | 523 | list_for_each_entry(dqp, &mp->m_quotainfo->qi_dqlist, q_mplist) { |
520 | while (dqp) { | ||
521 | xfs_dqlock(dqp); | 524 | xfs_dqlock(dqp); |
522 | if ((gdqp = dqp->q_gdquot)) { | 525 | if ((gdqp = dqp->q_gdquot)) { |
523 | xfs_dqlock(gdqp); | 526 | xfs_dqlock(gdqp); |
@@ -530,15 +533,14 @@ xfs_qm_detach_gdquots( | |||
530 | * Can't hold the mplist lock across a dqput. | 533 | * Can't hold the mplist lock across a dqput. |
531 | * XXXmust convert to marker based iterations here. | 534 | * XXXmust convert to marker based iterations here. |
532 | */ | 535 | */ |
533 | nrecl = XFS_QI_MPLRECLAIMS(mp); | 536 | nrecl = mp->m_quotainfo->qi_dqreclaims; |
534 | xfs_qm_mplist_unlock(mp); | 537 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
535 | xfs_qm_dqput(gdqp); | 538 | xfs_qm_dqput(gdqp); |
536 | 539 | ||
537 | xfs_qm_mplist_lock(mp); | 540 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
538 | if (nrecl != XFS_QI_MPLRECLAIMS(mp)) | 541 | if (nrecl != mp->m_quotainfo->qi_dqreclaims) |
539 | goto again; | 542 | goto again; |
540 | } | 543 | } |
541 | dqp = dqp->MPL_NEXT; | ||
542 | } | 544 | } |
543 | } | 545 | } |
544 | 546 | ||
@@ -553,10 +555,9 @@ xfs_qm_dqpurge_int( | |||
553 | xfs_mount_t *mp, | 555 | xfs_mount_t *mp, |
554 | uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */ | 556 | uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */ |
555 | { | 557 | { |
556 | xfs_dquot_t *dqp; | 558 | xfs_dquot_t *dqp, *n; |
557 | uint dqtype; | 559 | uint dqtype; |
558 | int nrecl; | 560 | int nrecl; |
559 | xfs_dquot_t *nextdqp; | ||
560 | int nmisses; | 561 | int nmisses; |
561 | 562 | ||
562 | if (mp->m_quotainfo == NULL) | 563 | if (mp->m_quotainfo == NULL) |
@@ -566,7 +567,7 @@ xfs_qm_dqpurge_int( | |||
566 | dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0; | 567 | dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0; |
567 | dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; | 568 | dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; |
568 | 569 | ||
569 | xfs_qm_mplist_lock(mp); | 570 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
570 | 571 | ||
571 | /* | 572 | /* |
572 | * In the first pass through all incore dquots of this filesystem, | 573 | * In the first pass through all incore dquots of this filesystem, |
@@ -578,28 +579,25 @@ xfs_qm_dqpurge_int( | |||
578 | 579 | ||
579 | again: | 580 | again: |
580 | nmisses = 0; | 581 | nmisses = 0; |
581 | ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp)); | 582 | ASSERT(mutex_is_locked(&mp->m_quotainfo->qi_dqlist_lock)); |
582 | /* | 583 | /* |
583 | * Try to get rid of all of the unwanted dquots. The idea is to | 584 | * Try to get rid of all of the unwanted dquots. The idea is to |
584 | * get them off mplist and hashlist, but leave them on freelist. | 585 | * get them off mplist and hashlist, but leave them on freelist. |
585 | */ | 586 | */ |
586 | dqp = XFS_QI_MPLNEXT(mp); | 587 | list_for_each_entry_safe(dqp, n, &mp->m_quotainfo->qi_dqlist, q_mplist) { |
587 | while (dqp) { | ||
588 | /* | 588 | /* |
589 | * It's OK to look at the type without taking dqlock here. | 589 | * It's OK to look at the type without taking dqlock here. |
590 | * We're holding the mplist lock here, and that's needed for | 590 | * We're holding the mplist lock here, and that's needed for |
591 | * a dqreclaim. | 591 | * a dqreclaim. |
592 | */ | 592 | */ |
593 | if ((dqp->dq_flags & dqtype) == 0) { | 593 | if ((dqp->dq_flags & dqtype) == 0) |
594 | dqp = dqp->MPL_NEXT; | ||
595 | continue; | 594 | continue; |
596 | } | ||
597 | 595 | ||
598 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) { | 596 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) { |
599 | nrecl = XFS_QI_MPLRECLAIMS(mp); | 597 | nrecl = mp->m_quotainfo->qi_dqreclaims; |
600 | xfs_qm_mplist_unlock(mp); | 598 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
601 | mutex_lock(&dqp->q_hash->qh_lock); | 599 | mutex_lock(&dqp->q_hash->qh_lock); |
602 | xfs_qm_mplist_lock(mp); | 600 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
603 | 601 | ||
604 | /* | 602 | /* |
605 | * XXXTheoretically, we can get into a very long | 603 | * XXXTheoretically, we can get into a very long |
@@ -607,7 +605,7 @@ xfs_qm_dqpurge_int( | |||
607 | * No one can be adding dquots to the mplist at | 605 | * No one can be adding dquots to the mplist at |
608 | * this point, but somebody might be taking things off. | 606 | * this point, but somebody might be taking things off. |
609 | */ | 607 | */ |
610 | if (nrecl != XFS_QI_MPLRECLAIMS(mp)) { | 608 | if (nrecl != mp->m_quotainfo->qi_dqreclaims) { |
611 | mutex_unlock(&dqp->q_hash->qh_lock); | 609 | mutex_unlock(&dqp->q_hash->qh_lock); |
612 | goto again; | 610 | goto again; |
613 | } | 611 | } |
@@ -617,11 +615,9 @@ xfs_qm_dqpurge_int( | |||
617 | * Take the dquot off the mplist and hashlist. It may remain on | 615 | * Take the dquot off the mplist and hashlist. It may remain on |
618 | * freelist in INACTIVE state. | 616 | * freelist in INACTIVE state. |
619 | */ | 617 | */ |
620 | nextdqp = dqp->MPL_NEXT; | ||
621 | nmisses += xfs_qm_dqpurge(dqp); | 618 | nmisses += xfs_qm_dqpurge(dqp); |
622 | dqp = nextdqp; | ||
623 | } | 619 | } |
624 | xfs_qm_mplist_unlock(mp); | 620 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
625 | return nmisses; | 621 | return nmisses; |
626 | } | 622 | } |
627 | 623 | ||
@@ -934,18 +930,19 @@ xfs_qm_sync( | |||
934 | restarts = 0; | 930 | restarts = 0; |
935 | 931 | ||
936 | again: | 932 | again: |
937 | xfs_qm_mplist_lock(mp); | 933 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
938 | /* | 934 | /* |
939 | * dqpurge_all() also takes the mplist lock and iterate thru all dquots | 935 | * dqpurge_all() also takes the mplist lock and iterate thru all dquots |
940 | * in quotaoff. However, if the QUOTA_ACTIVE bits are not cleared | 936 | * in quotaoff. However, if the QUOTA_ACTIVE bits are not cleared |
941 | * when we have the mplist lock, we know that dquots will be consistent | 937 | * when we have the mplist lock, we know that dquots will be consistent |
942 | * as long as we have it locked. | 938 | * as long as we have it locked. |
943 | */ | 939 | */ |
944 | if (! XFS_IS_QUOTA_ON(mp)) { | 940 | if (!XFS_IS_QUOTA_ON(mp)) { |
945 | xfs_qm_mplist_unlock(mp); | 941 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
946 | return 0; | 942 | return 0; |
947 | } | 943 | } |
948 | FOREACH_DQUOT_IN_MP(dqp, mp) { | 944 | ASSERT(mutex_is_locked(&mp->m_quotainfo->qi_dqlist_lock)); |
945 | list_for_each_entry(dqp, &mp->m_quotainfo->qi_dqlist, q_mplist) { | ||
949 | /* | 946 | /* |
950 | * If this is vfs_sync calling, then skip the dquots that | 947 | * If this is vfs_sync calling, then skip the dquots that |
951 | * don't 'seem' to be dirty. ie. don't acquire dqlock. | 948 | * don't 'seem' to be dirty. ie. don't acquire dqlock. |
@@ -969,7 +966,7 @@ xfs_qm_sync( | |||
969 | } | 966 | } |
970 | 967 | ||
971 | /* XXX a sentinel would be better */ | 968 | /* XXX a sentinel would be better */ |
972 | recl = XFS_QI_MPLRECLAIMS(mp); | 969 | recl = mp->m_quotainfo->qi_dqreclaims; |
973 | if (!xfs_dqflock_nowait(dqp)) { | 970 | if (!xfs_dqflock_nowait(dqp)) { |
974 | if (flags & SYNC_TRYLOCK) { | 971 | if (flags & SYNC_TRYLOCK) { |
975 | xfs_dqunlock(dqp); | 972 | xfs_dqunlock(dqp); |
@@ -989,7 +986,7 @@ xfs_qm_sync( | |||
989 | * Let go of the mplist lock. We don't want to hold it | 986 | * Let go of the mplist lock. We don't want to hold it |
990 | * across a disk write | 987 | * across a disk write |
991 | */ | 988 | */ |
992 | xfs_qm_mplist_unlock(mp); | 989 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
993 | error = xfs_qm_dqflush(dqp, flags); | 990 | error = xfs_qm_dqflush(dqp, flags); |
994 | xfs_dqunlock(dqp); | 991 | xfs_dqunlock(dqp); |
995 | if (error && XFS_FORCED_SHUTDOWN(mp)) | 992 | if (error && XFS_FORCED_SHUTDOWN(mp)) |
@@ -997,17 +994,17 @@ xfs_qm_sync( | |||
997 | else if (error) | 994 | else if (error) |
998 | return error; | 995 | return error; |
999 | 996 | ||
1000 | xfs_qm_mplist_lock(mp); | 997 | mutex_lock(&mp->m_quotainfo->qi_dqlist_lock); |
1001 | if (recl != XFS_QI_MPLRECLAIMS(mp)) { | 998 | if (recl != mp->m_quotainfo->qi_dqreclaims) { |
1002 | if (++restarts >= XFS_QM_SYNC_MAX_RESTARTS) | 999 | if (++restarts >= XFS_QM_SYNC_MAX_RESTARTS) |
1003 | break; | 1000 | break; |
1004 | 1001 | ||
1005 | xfs_qm_mplist_unlock(mp); | 1002 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
1006 | goto again; | 1003 | goto again; |
1007 | } | 1004 | } |
1008 | } | 1005 | } |
1009 | 1006 | ||
1010 | xfs_qm_mplist_unlock(mp); | 1007 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
1011 | return 0; | 1008 | return 0; |
1012 | } | 1009 | } |
1013 | 1010 | ||
@@ -1052,8 +1049,9 @@ xfs_qm_init_quotainfo( | |||
1052 | return error; | 1049 | return error; |
1053 | } | 1050 | } |
1054 | 1051 | ||
1055 | xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0); | 1052 | INIT_LIST_HEAD(&qinf->qi_dqlist); |
1056 | lockdep_set_class(&qinf->qi_dqlist.qh_lock, &xfs_quota_mplist_class); | 1053 | mutex_init(&qinf->qi_dqlist_lock); |
1054 | lockdep_set_class(&qinf->qi_dqlist_lock, &xfs_quota_mplist_class); | ||
1057 | 1055 | ||
1058 | qinf->qi_dqreclaims = 0; | 1056 | qinf->qi_dqreclaims = 0; |
1059 | 1057 | ||
@@ -1150,7 +1148,8 @@ xfs_qm_destroy_quotainfo( | |||
1150 | */ | 1148 | */ |
1151 | xfs_qm_rele_quotafs_ref(mp); | 1149 | xfs_qm_rele_quotafs_ref(mp); |
1152 | 1150 | ||
1153 | xfs_qm_list_destroy(&qi->qi_dqlist); | 1151 | ASSERT(list_empty(&qi->qi_dqlist)); |
1152 | mutex_destroy(&qi->qi_dqlist_lock); | ||
1154 | 1153 | ||
1155 | if (qi->qi_uquotaip) { | 1154 | if (qi->qi_uquotaip) { |
1156 | IRELE(qi->qi_uquotaip); | 1155 | IRELE(qi->qi_uquotaip); |
@@ -1754,7 +1753,7 @@ xfs_qm_quotacheck( | |||
1754 | * There should be no cached dquots. The (simplistic) quotacheck | 1753 | * There should be no cached dquots. The (simplistic) quotacheck |
1755 | * algorithm doesn't like that. | 1754 | * algorithm doesn't like that. |
1756 | */ | 1755 | */ |
1757 | ASSERT(XFS_QI_MPLNDQUOTS(mp) == 0); | 1756 | ASSERT(list_empty(&mp->m_quotainfo->qi_dqlist)); |
1758 | 1757 | ||
1759 | cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); | 1758 | cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); |
1760 | 1759 | ||
@@ -1825,7 +1824,7 @@ xfs_qm_quotacheck( | |||
1825 | mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD); | 1824 | mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD); |
1826 | mp->m_qflags |= flags; | 1825 | mp->m_qflags |= flags; |
1827 | 1826 | ||
1828 | XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); | 1827 | xfs_qm_dquot_list_print(mp); |
1829 | 1828 | ||
1830 | error_return: | 1829 | error_return: |
1831 | if (error) { | 1830 | if (error) { |
@@ -1960,6 +1959,7 @@ xfs_qm_shake_freelist( | |||
1960 | for (dqp = xfs_Gqm->qm_dqfreelist.qh_next; | 1959 | for (dqp = xfs_Gqm->qm_dqfreelist.qh_next; |
1961 | ((dqp != (xfs_dquot_t *) &xfs_Gqm->qm_dqfreelist) && | 1960 | ((dqp != (xfs_dquot_t *) &xfs_Gqm->qm_dqfreelist) && |
1962 | nreclaimed < howmany); ) { | 1961 | nreclaimed < howmany); ) { |
1962 | struct xfs_mount *mp = dqp->q_mount; | ||
1963 | xfs_dqlock(dqp); | 1963 | xfs_dqlock(dqp); |
1964 | 1964 | ||
1965 | /* | 1965 | /* |
@@ -1981,16 +1981,16 @@ xfs_qm_shake_freelist( | |||
1981 | * life easier. | 1981 | * life easier. |
1982 | */ | 1982 | */ |
1983 | if (dqp->dq_flags & XFS_DQ_INACTIVE) { | 1983 | if (dqp->dq_flags & XFS_DQ_INACTIVE) { |
1984 | ASSERT(dqp->q_mount == NULL); | 1984 | ASSERT(mp == NULL); |
1985 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); | 1985 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); |
1986 | ASSERT(dqp->HL_PREVP == NULL); | 1986 | ASSERT(dqp->HL_PREVP == NULL); |
1987 | ASSERT(dqp->MPL_PREVP == NULL); | 1987 | ASSERT(list_empty(&dqp->q_mplist)); |
1988 | XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); | 1988 | XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); |
1989 | nextdqp = dqp->dq_flnext; | 1989 | nextdqp = dqp->dq_flnext; |
1990 | goto off_freelist; | 1990 | goto off_freelist; |
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | ASSERT(dqp->MPL_PREVP); | 1993 | ASSERT(!list_empty(&dqp->q_mplist)); |
1994 | /* | 1994 | /* |
1995 | * Try to grab the flush lock. If this dquot is in the process of | 1995 | * Try to grab the flush lock. If this dquot is in the process of |
1996 | * getting flushed to disk, we don't want to reclaim it. | 1996 | * getting flushed to disk, we don't want to reclaim it. |
@@ -2018,7 +2018,7 @@ xfs_qm_shake_freelist( | |||
2018 | */ | 2018 | */ |
2019 | error = xfs_qm_dqflush(dqp, 0); | 2019 | error = xfs_qm_dqflush(dqp, 0); |
2020 | if (error) { | 2020 | if (error) { |
2021 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | 2021 | xfs_fs_cmn_err(CE_WARN, mp, |
2022 | "xfs_qm_dqflush_all: dquot %p flush failed", dqp); | 2022 | "xfs_qm_dqflush_all: dquot %p flush failed", dqp); |
2023 | } | 2023 | } |
2024 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ | 2024 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ |
@@ -2045,7 +2045,7 @@ xfs_qm_shake_freelist( | |||
2045 | */ | 2045 | */ |
2046 | hash = dqp->q_hash; | 2046 | hash = dqp->q_hash; |
2047 | ASSERT(hash); | 2047 | ASSERT(hash); |
2048 | if (! xfs_qm_mplist_nowait(dqp->q_mount)) { | 2048 | if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) { |
2049 | /* XXX put a sentinel so that we can come back here */ | 2049 | /* XXX put a sentinel so that we can come back here */ |
2050 | xfs_dqfunlock(dqp); | 2050 | xfs_dqfunlock(dqp); |
2051 | xfs_dqunlock(dqp); | 2051 | xfs_dqunlock(dqp); |
@@ -2064,10 +2064,12 @@ xfs_qm_shake_freelist( | |||
2064 | #endif | 2064 | #endif |
2065 | ASSERT(dqp->q_nrefs == 0); | 2065 | ASSERT(dqp->q_nrefs == 0); |
2066 | nextdqp = dqp->dq_flnext; | 2066 | nextdqp = dqp->dq_flnext; |
2067 | XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp); | ||
2068 | XQM_HASHLIST_REMOVE(hash, dqp); | 2067 | XQM_HASHLIST_REMOVE(hash, dqp); |
2068 | list_del_init(&dqp->q_mplist); | ||
2069 | mp->m_quotainfo->qi_dquots--; | ||
2070 | mp->m_quotainfo->qi_dqreclaims++; | ||
2069 | xfs_dqfunlock(dqp); | 2071 | xfs_dqfunlock(dqp); |
2070 | xfs_qm_mplist_unlock(dqp->q_mount); | 2072 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
2071 | mutex_unlock(&hash->qh_lock); | 2073 | mutex_unlock(&hash->qh_lock); |
2072 | 2074 | ||
2073 | off_freelist: | 2075 | off_freelist: |
@@ -2134,6 +2136,7 @@ xfs_qm_dqreclaim_one(void) | |||
2134 | xfs_qm_freelist_lock(xfs_Gqm); | 2136 | xfs_qm_freelist_lock(xfs_Gqm); |
2135 | 2137 | ||
2136 | FOREACH_DQUOT_IN_FREELIST(dqp, &(xfs_Gqm->qm_dqfreelist)) { | 2138 | FOREACH_DQUOT_IN_FREELIST(dqp, &(xfs_Gqm->qm_dqfreelist)) { |
2139 | struct xfs_mount *mp = dqp->q_mount; | ||
2137 | xfs_dqlock(dqp); | 2140 | xfs_dqlock(dqp); |
2138 | 2141 | ||
2139 | /* | 2142 | /* |
@@ -2161,10 +2164,10 @@ xfs_qm_dqreclaim_one(void) | |||
2161 | * life easier. | 2164 | * life easier. |
2162 | */ | 2165 | */ |
2163 | if (dqp->dq_flags & XFS_DQ_INACTIVE) { | 2166 | if (dqp->dq_flags & XFS_DQ_INACTIVE) { |
2164 | ASSERT(dqp->q_mount == NULL); | 2167 | ASSERT(mp == NULL); |
2165 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); | 2168 | ASSERT(! XFS_DQ_IS_DIRTY(dqp)); |
2166 | ASSERT(dqp->HL_PREVP == NULL); | 2169 | ASSERT(dqp->HL_PREVP == NULL); |
2167 | ASSERT(dqp->MPL_PREVP == NULL); | 2170 | ASSERT(list_empty(&dqp->q_mplist)); |
2168 | XQM_FREELIST_REMOVE(dqp); | 2171 | XQM_FREELIST_REMOVE(dqp); |
2169 | xfs_dqunlock(dqp); | 2172 | xfs_dqunlock(dqp); |
2170 | dqpout = dqp; | 2173 | dqpout = dqp; |
@@ -2173,7 +2176,7 @@ xfs_qm_dqreclaim_one(void) | |||
2173 | } | 2176 | } |
2174 | 2177 | ||
2175 | ASSERT(dqp->q_hash); | 2178 | ASSERT(dqp->q_hash); |
2176 | ASSERT(dqp->MPL_PREVP); | 2179 | ASSERT(!list_empty(&dqp->q_mplist)); |
2177 | 2180 | ||
2178 | /* | 2181 | /* |
2179 | * Try to grab the flush lock. If this dquot is in the process of | 2182 | * Try to grab the flush lock. If this dquot is in the process of |
@@ -2201,14 +2204,14 @@ xfs_qm_dqreclaim_one(void) | |||
2201 | */ | 2204 | */ |
2202 | error = xfs_qm_dqflush(dqp, 0); | 2205 | error = xfs_qm_dqflush(dqp, 0); |
2203 | if (error) { | 2206 | if (error) { |
2204 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | 2207 | xfs_fs_cmn_err(CE_WARN, mp, |
2205 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); | 2208 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); |
2206 | } | 2209 | } |
2207 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ | 2210 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ |
2208 | continue; | 2211 | continue; |
2209 | } | 2212 | } |
2210 | 2213 | ||
2211 | if (! xfs_qm_mplist_nowait(dqp->q_mount)) { | 2214 | if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) { |
2212 | xfs_dqfunlock(dqp); | 2215 | xfs_dqfunlock(dqp); |
2213 | xfs_dqunlock(dqp); | 2216 | xfs_dqunlock(dqp); |
2214 | continue; | 2217 | continue; |
@@ -2220,13 +2223,15 @@ xfs_qm_dqreclaim_one(void) | |||
2220 | trace_xfs_dqreclaim_unlink(dqp); | 2223 | trace_xfs_dqreclaim_unlink(dqp); |
2221 | 2224 | ||
2222 | ASSERT(dqp->q_nrefs == 0); | 2225 | ASSERT(dqp->q_nrefs == 0); |
2223 | XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp); | 2226 | list_del_init(&dqp->q_mplist); |
2227 | mp->m_quotainfo->qi_dquots--; | ||
2228 | mp->m_quotainfo->qi_dqreclaims++; | ||
2224 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); | 2229 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); |
2225 | XQM_FREELIST_REMOVE(dqp); | 2230 | XQM_FREELIST_REMOVE(dqp); |
2226 | dqpout = dqp; | 2231 | dqpout = dqp; |
2227 | mutex_unlock(&dqp->q_hash->qh_lock); | 2232 | mutex_unlock(&dqp->q_hash->qh_lock); |
2228 | mplistunlock: | 2233 | mplistunlock: |
2229 | xfs_qm_mplist_unlock(dqp->q_mount); | 2234 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
2230 | xfs_dqfunlock(dqp); | 2235 | xfs_dqfunlock(dqp); |
2231 | xfs_dqunlock(dqp); | 2236 | xfs_dqunlock(dqp); |
2232 | if (dqpout) | 2237 | if (dqpout) |