Skip to content

Commit

Permalink
xfs: convert the dquot free list to use list heads
Browse files Browse the repository at this point in the history
Convert the dquot free list on the filesystem 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>
  • Loading branch information
Dave Chinner authored and Alex Elder committed May 19, 2010
1 parent e6a81f1 commit 3a8406f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 165 deletions.
75 changes: 31 additions & 44 deletions fs/xfs/quota/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ xfs_qm_dqinit(
* No need to re-initialize these if this is a reclaimed dquot.
*/
if (brandnewdquot) {
dqp->dq_flnext = dqp->dq_flprev = dqp;
INIT_LIST_HEAD(&dqp->q_freelist);
mutex_init(&dqp->q_qlock);
init_waitqueue_head(&dqp->q_pinwait);

Expand All @@ -119,20 +119,20 @@ xfs_qm_dqinit(
* Only the q_core portion was zeroed in dqreclaim_one().
* So, we need to reset others.
*/
dqp->q_nrefs = 0;
dqp->q_blkno = 0;
INIT_LIST_HEAD(&dqp->q_mplist);
INIT_LIST_HEAD(&dqp->q_hashlist);
dqp->q_bufoffset = 0;
dqp->q_fileoffset = 0;
dqp->q_transp = NULL;
dqp->q_gdquot = NULL;
dqp->q_res_bcount = 0;
dqp->q_res_icount = 0;
dqp->q_res_rtbcount = 0;
atomic_set(&dqp->q_pincount, 0);
dqp->q_hash = NULL;
ASSERT(dqp->dq_flnext == dqp->dq_flprev);
dqp->q_nrefs = 0;
dqp->q_blkno = 0;
INIT_LIST_HEAD(&dqp->q_mplist);
INIT_LIST_HEAD(&dqp->q_hashlist);
dqp->q_bufoffset = 0;
dqp->q_fileoffset = 0;
dqp->q_transp = NULL;
dqp->q_gdquot = NULL;
dqp->q_res_bcount = 0;
dqp->q_res_icount = 0;
dqp->q_res_rtbcount = 0;
atomic_set(&dqp->q_pincount, 0);
dqp->q_hash = NULL;
ASSERT(list_empty(&dqp->q_freelist));

trace_xfs_dqreuse(dqp);
}
Expand All @@ -158,7 +158,7 @@ void
xfs_qm_dqdestroy(
xfs_dquot_t *dqp)
{
ASSERT(! XFS_DQ_IS_ON_FREELIST(dqp));
ASSERT(list_empty(&dqp->q_freelist));

mutex_destroy(&dqp->q_qlock);
sv_destroy(&dqp->q_pinwait);
Expand Down Expand Up @@ -775,8 +775,8 @@ xfs_qm_dqlookup(

xfs_dqlock(dqp);
if (dqp->q_nrefs == 0) {
ASSERT (XFS_DQ_IS_ON_FREELIST(dqp));
if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) {
ASSERT(!list_empty(&dqp->q_freelist));
if (!mutex_trylock(&xfs_Gqm->qm_dqfrlist_lock)) {
trace_xfs_dqlookup_want(dqp);

/*
Expand All @@ -786,7 +786,7 @@ xfs_qm_dqlookup(
*/
dqp->dq_flags |= XFS_DQ_WANT;
xfs_dqunlock(dqp);
xfs_qm_freelist_lock(xfs_Gqm);
mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
xfs_dqlock(dqp);
dqp->dq_flags &= ~(XFS_DQ_WANT);
}
Expand All @@ -801,27 +801,20 @@ xfs_qm_dqlookup(

if (flist_locked) {
if (dqp->q_nrefs != 0) {
xfs_qm_freelist_unlock(xfs_Gqm);
mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
flist_locked = B_FALSE;
} else {
/*
* take it off the freelist
*/
/* take it off the freelist */
trace_xfs_dqlookup_freelist(dqp);
XQM_FREELIST_REMOVE(dqp);
/* xfs_qm_freelist_print(&(xfs_Gqm->
qm_dqfreelist),
"after removal"); */
list_del_init(&dqp->q_freelist);
xfs_Gqm->qm_dqfrlist_cnt--;
}
}

/*
* grab a reference
*/
XFS_DQHOLD(dqp);

if (flist_locked)
xfs_qm_freelist_unlock(xfs_Gqm);
mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
/*
* move the dquot to the front of the hashchain
*/
Expand Down Expand Up @@ -1075,10 +1068,10 @@ xfs_qm_dqput(
* drop the dqlock and acquire the freelist and dqlock
* in the right order; but try to get it out-of-order first
*/
if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) {
if (!mutex_trylock(&xfs_Gqm->qm_dqfrlist_lock)) {
trace_xfs_dqput_wait(dqp);
xfs_dqunlock(dqp);
xfs_qm_freelist_lock(xfs_Gqm);
mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
xfs_dqlock(dqp);
}

Expand All @@ -1089,10 +1082,8 @@ xfs_qm_dqput(
if (--dqp->q_nrefs == 0) {
trace_xfs_dqput_free(dqp);

/*
* insert at end of the freelist.
*/
XQM_FREELIST_INSERT(&(xfs_Gqm->qm_dqfreelist), dqp);
list_add_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
xfs_Gqm->qm_dqfrlist_cnt++;

/*
* If we just added a udquot to the freelist, then
Expand All @@ -1107,10 +1098,6 @@ xfs_qm_dqput(
xfs_dqlock(gdqp);
dqp->q_gdquot = NULL;
}

/* xfs_qm_freelist_print(&(xfs_Gqm->qm_dqfreelist),
"@@@@@++ Free list (after append) @@@@@+");
*/
}
xfs_dqunlock(dqp);

Expand All @@ -1122,7 +1109,7 @@ xfs_qm_dqput(
break;
dqp = gdqp;
}
xfs_qm_freelist_unlock(xfs_Gqm);
mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
}

/*
Expand Down Expand Up @@ -1396,7 +1383,7 @@ xfs_qm_dqpurge(
return (1);
}

ASSERT(XFS_DQ_IS_ON_FREELIST(dqp));
ASSERT(!list_empty(&dqp->q_freelist));

/*
* If we're turning off quotas, we have to make sure that, for
Expand Down Expand Up @@ -1450,7 +1437,7 @@ xfs_qm_dqpurge(
* XXX Move this to the front of the freelist, if we can get the
* freelist lock.
*/
ASSERT(XFS_DQ_IS_ON_FREELIST(dqp));
ASSERT(!list_empty(&dqp->q_freelist));

dqp->q_mount = NULL;
dqp->q_hash = NULL;
Expand Down
5 changes: 2 additions & 3 deletions fs/xfs/quota/xfs_dquot.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ struct xfs_trans;
* iterations because of locking considerations.
*/
typedef struct xfs_dqmarker {
struct xfs_dquot*dqm_flnext; /* link to freelist: must be first */
struct xfs_dquot*dqm_flprev;
uint dqm_flags; /* various flags (XFS_DQ_*) */
} xfs_dqmarker_t;

Expand All @@ -60,8 +58,9 @@ typedef struct xfs_dqmarker {
*/
typedef struct xfs_dquot {
xfs_dqmarker_t q_lists; /* list ptrs, q_flags (marker) */
struct list_head q_freelist; /* global free list of dquots */
struct list_head q_mplist; /* mount's list of dquots */
struct list_head q_hashlist; /* mount's list of dquots */
struct list_head q_hashlist; /* gloabl hash list of dquots */
xfs_dqhash_t *q_hash; /* the hashchain header */
struct xfs_mount*q_mount; /* filesystem this relates to */
struct xfs_trans*q_transp; /* trans this belongs to currently */
Expand Down
Loading

0 comments on commit 3a8406f

Please sign in to comment.