diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-12-06 16:58:17 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2011-12-13 17:46:28 -0500 |
commit | be7ffc38a80a78e6b68d0f51fae8e8d57b55324c (patch) | |
tree | bb5ca49fd1dc92051e9898a653d7bdd26c93af59 /fs/xfs/xfs_qm.c | |
parent | 80a376bfb7f8ff8f1942cb1bdd0052e908918252 (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.c | 22 |
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; |