aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_qm.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-12-06 16:58:17 -0500
committerBen Myers <bpm@sgi.com>2011-12-13 17:46:28 -0500
commitbe7ffc38a80a78e6b68d0f51fae8e8d57b55324c (patch)
treebb5ca49fd1dc92051e9898a653d7bdd26c93af59 /fs/xfs/xfs_qm.c
parent80a376bfb7f8ff8f1942cb1bdd0052e908918252 (diff)
xfs: implement lazy removal for the dquot freelist
Do not remove dquots from the freelist when we grab a reference to them in xfs_qm_dqlookup, but leave them on the freelist util scanning notices that they have a reference. This speeds up the lookup fastpath, and greatly simplifies the lock ordering constraints. Note that the same scheme is used by the VFS inode and dentry caches. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_qm.c')
-rw-r--r--fs/xfs/xfs_qm.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index be1df6839237..6a0c4f0d9306 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -517,13 +517,12 @@ xfs_qm_dqpurge_int(
517 * get them off mplist and hashlist, but leave them on freelist. 517 * get them off mplist and hashlist, but leave them on freelist.
518 */ 518 */
519 list_for_each_entry_safe(dqp, n, &q->qi_dqlist, q_mplist) { 519 list_for_each_entry_safe(dqp, n, &q->qi_dqlist, q_mplist) {
520 /* 520 xfs_dqlock(dqp);
521 * It's OK to look at the type without taking dqlock here. 521 if ((dqp->dq_flags & dqtype) == 0) {
522 * We're holding the mplist lock here, and that's needed for 522 xfs_dqunlock(dqp);
523 * a dqreclaim.
524 */
525 if ((dqp->dq_flags & dqtype) == 0)
526 continue; 523 continue;
524 }
525 xfs_dqunlock(dqp);
527 526
528 if (!mutex_trylock(&dqp->q_hash->qh_lock)) { 527 if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
529 nrecl = q->qi_dqreclaims; 528 nrecl = q->qi_dqreclaims;
@@ -1692,14 +1691,15 @@ again:
1692 xfs_dqlock(dqp); 1691 xfs_dqlock(dqp);
1693 1692
1694 /* 1693 /*
1695 * We are racing with dqlookup here. Naturally we don't 1694 * This dquot has already been grabbed by dqlookup.
1696 * want to reclaim a dquot that lookup wants. We release the 1695 * Remove it from the freelist and try again.
1697 * freelist lock and start over, so that lookup will grab
1698 * both the dquot and the freelistlock.
1699 */ 1696 */
1700 if (dqp->dq_flags & XFS_DQ_WANT) { 1697 if (dqp->q_nrefs) {
1701 trace_xfs_dqreclaim_want(dqp); 1698 trace_xfs_dqreclaim_want(dqp);
1702 XQM_STATS_INC(xqmstats.xs_qm_dqwants); 1699 XQM_STATS_INC(xqmstats.xs_qm_dqwants);
1700
1701 list_del_init(&dqp->q_freelist);
1702 xfs_Gqm->qm_dqfrlist_cnt--;
1703 restarts++; 1703 restarts++;
1704 startagain = 1; 1704 startagain = 1;
1705 goto dqunlock; 1705 goto dqunlock;