Commit 3a8406f6 authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder

xfs: convert the dquot free list to use list heads

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent e6a81f13
...@@ -101,7 +101,7 @@ xfs_qm_dqinit( ...@@ -101,7 +101,7 @@ xfs_qm_dqinit(
* No need to re-initialize these if this is a reclaimed dquot. * No need to re-initialize these if this is a reclaimed dquot.
*/ */
if (brandnewdquot) { if (brandnewdquot) {
dqp->dq_flnext = dqp->dq_flprev = dqp; INIT_LIST_HEAD(&dqp->q_freelist);
mutex_init(&dqp->q_qlock); mutex_init(&dqp->q_qlock);
init_waitqueue_head(&dqp->q_pinwait); init_waitqueue_head(&dqp->q_pinwait);
...@@ -119,20 +119,20 @@ xfs_qm_dqinit( ...@@ -119,20 +119,20 @@ xfs_qm_dqinit(
* Only the q_core portion was zeroed in dqreclaim_one(). * Only the q_core portion was zeroed in dqreclaim_one().
* So, we need to reset others. * So, we need to reset others.
*/ */
dqp->q_nrefs = 0; dqp->q_nrefs = 0;
dqp->q_blkno = 0; dqp->q_blkno = 0;
INIT_LIST_HEAD(&dqp->q_mplist); INIT_LIST_HEAD(&dqp->q_mplist);
INIT_LIST_HEAD(&dqp->q_hashlist); INIT_LIST_HEAD(&dqp->q_hashlist);
dqp->q_bufoffset = 0; dqp->q_bufoffset = 0;
dqp->q_fileoffset = 0; dqp->q_fileoffset = 0;
dqp->q_transp = NULL; dqp->q_transp = NULL;
dqp->q_gdquot = NULL; dqp->q_gdquot = NULL;
dqp->q_res_bcount = 0; dqp->q_res_bcount = 0;
dqp->q_res_icount = 0; dqp->q_res_icount = 0;
dqp->q_res_rtbcount = 0; dqp->q_res_rtbcount = 0;
atomic_set(&dqp->q_pincount, 0); atomic_set(&dqp->q_pincount, 0);
dqp->q_hash = NULL; dqp->q_hash = NULL;
ASSERT(dqp->dq_flnext == dqp->dq_flprev); ASSERT(list_empty(&dqp->q_freelist));
trace_xfs_dqreuse(dqp); trace_xfs_dqreuse(dqp);
} }
...@@ -158,7 +158,7 @@ void ...@@ -158,7 +158,7 @@ void
xfs_qm_dqdestroy( xfs_qm_dqdestroy(
xfs_dquot_t *dqp) xfs_dquot_t *dqp)
{ {
ASSERT(! XFS_DQ_IS_ON_FREELIST(dqp)); ASSERT(list_empty(&dqp->q_freelist));
mutex_destroy(&dqp->q_qlock); mutex_destroy(&dqp->q_qlock);
sv_destroy(&dqp->q_pinwait); sv_destroy(&dqp->q_pinwait);
...@@ -775,8 +775,8 @@ xfs_qm_dqlookup( ...@@ -775,8 +775,8 @@ xfs_qm_dqlookup(
xfs_dqlock(dqp); xfs_dqlock(dqp);
if (dqp->q_nrefs == 0) { if (dqp->q_nrefs == 0) {
ASSERT (XFS_DQ_IS_ON_FREELIST(dqp)); ASSERT(!list_empty(&dqp->q_freelist));
if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { if (!mutex_trylock(&xfs_Gqm->qm_dqfrlist_lock)) {
trace_xfs_dqlookup_want(dqp); trace_xfs_dqlookup_want(dqp);
/* /*
...@@ -786,7 +786,7 @@ xfs_qm_dqlookup( ...@@ -786,7 +786,7 @@ xfs_qm_dqlookup(
*/ */
dqp->dq_flags |= XFS_DQ_WANT; dqp->dq_flags |= XFS_DQ_WANT;
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_qm_freelist_lock(xfs_Gqm); mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
xfs_dqlock(dqp); xfs_dqlock(dqp);
dqp->dq_flags &= ~(XFS_DQ_WANT); dqp->dq_flags &= ~(XFS_DQ_WANT);
} }
...@@ -801,27 +801,20 @@ xfs_qm_dqlookup( ...@@ -801,27 +801,20 @@ xfs_qm_dqlookup(
if (flist_locked) { if (flist_locked) {
if (dqp->q_nrefs != 0) { if (dqp->q_nrefs != 0) {
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
flist_locked = B_FALSE; flist_locked = B_FALSE;
} else { } else {
/* /* take it off the freelist */
* take it off the freelist
*/
trace_xfs_dqlookup_freelist(dqp); trace_xfs_dqlookup_freelist(dqp);
XQM_FREELIST_REMOVE(dqp); list_del_init(&dqp->q_freelist);
/* xfs_qm_freelist_print(&(xfs_Gqm-> xfs_Gqm->qm_dqfrlist_cnt--;
qm_dqfreelist),
"after removal"); */
} }
} }
/*
* grab a reference
*/
XFS_DQHOLD(dqp); XFS_DQHOLD(dqp);
if (flist_locked) 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 * move the dquot to the front of the hashchain
*/ */
...@@ -1075,10 +1068,10 @@ xfs_qm_dqput( ...@@ -1075,10 +1068,10 @@ xfs_qm_dqput(
* drop the dqlock and acquire the freelist and dqlock * drop the dqlock and acquire the freelist and dqlock
* in the right order; but try to get it out-of-order first * 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); trace_xfs_dqput_wait(dqp);
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_qm_freelist_lock(xfs_Gqm); mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
xfs_dqlock(dqp); xfs_dqlock(dqp);
} }
...@@ -1089,10 +1082,8 @@ xfs_qm_dqput( ...@@ -1089,10 +1082,8 @@ xfs_qm_dqput(
if (--dqp->q_nrefs == 0) { if (--dqp->q_nrefs == 0) {
trace_xfs_dqput_free(dqp); trace_xfs_dqput_free(dqp);
/* list_add_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist);
* insert at end of the freelist. xfs_Gqm->qm_dqfrlist_cnt++;
*/
XQM_FREELIST_INSERT(&(xfs_Gqm->qm_dqfreelist), dqp);
/* /*
* If we just added a udquot to the freelist, then * If we just added a udquot to the freelist, then
...@@ -1107,10 +1098,6 @@ xfs_qm_dqput( ...@@ -1107,10 +1098,6 @@ xfs_qm_dqput(
xfs_dqlock(gdqp); xfs_dqlock(gdqp);
dqp->q_gdquot = NULL; dqp->q_gdquot = NULL;
} }
/* xfs_qm_freelist_print(&(xfs_Gqm->qm_dqfreelist),
"@@@@@++ Free list (after append) @@@@@+");
*/
} }
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
...@@ -1122,7 +1109,7 @@ xfs_qm_dqput( ...@@ -1122,7 +1109,7 @@ xfs_qm_dqput(
break; break;
dqp = gdqp; dqp = gdqp;
} }
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
} }
/* /*
...@@ -1396,7 +1383,7 @@ xfs_qm_dqpurge( ...@@ -1396,7 +1383,7 @@ xfs_qm_dqpurge(
return (1); 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 * If we're turning off quotas, we have to make sure that, for
...@@ -1450,7 +1437,7 @@ xfs_qm_dqpurge( ...@@ -1450,7 +1437,7 @@ xfs_qm_dqpurge(
* XXX Move this to the front of the freelist, if we can get the * XXX Move this to the front of the freelist, if we can get the
* freelist lock. * freelist lock.
*/ */
ASSERT(XFS_DQ_IS_ON_FREELIST(dqp)); ASSERT(!list_empty(&dqp->q_freelist));
dqp->q_mount = NULL; dqp->q_mount = NULL;
dqp->q_hash = NULL; dqp->q_hash = NULL;
......
...@@ -50,8 +50,6 @@ struct xfs_trans; ...@@ -50,8 +50,6 @@ struct xfs_trans;
* iterations because of locking considerations. * iterations because of locking considerations.
*/ */
typedef struct xfs_dqmarker { 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_*) */ uint dqm_flags; /* various flags (XFS_DQ_*) */
} xfs_dqmarker_t; } xfs_dqmarker_t;
...@@ -60,8 +58,9 @@ typedef struct xfs_dqmarker { ...@@ -60,8 +58,9 @@ typedef struct xfs_dqmarker {
*/ */
typedef struct xfs_dquot { typedef struct xfs_dquot {
xfs_dqmarker_t q_lists; /* list ptrs, q_flags (marker) */ 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_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 */ xfs_dqhash_t *q_hash; /* the hashchain header */
struct xfs_mount*q_mount; /* filesystem this relates to */ struct xfs_mount*q_mount; /* filesystem this relates to */
struct xfs_trans*q_transp; /* trans this belongs to currently */ struct xfs_trans*q_transp; /* trans this belongs to currently */
......
...@@ -67,9 +67,6 @@ static cred_t xfs_zerocr; ...@@ -67,9 +67,6 @@ static cred_t xfs_zerocr;
STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int);
STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
STATIC void xfs_qm_freelist_init(xfs_frlist_t *);
STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *);
STATIC int xfs_qm_init_quotainos(xfs_mount_t *); STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
STATIC int xfs_qm_shake(int, gfp_t); STATIC int xfs_qm_shake(int, gfp_t);
...@@ -148,7 +145,9 @@ xfs_Gqm_init(void) ...@@ -148,7 +145,9 @@ xfs_Gqm_init(void)
/* /*
* Freelist of all dquots of all file systems * Freelist of all dquots of all file systems
*/ */
xfs_qm_freelist_init(&(xqm->qm_dqfreelist)); INIT_LIST_HEAD(&xqm->qm_dqfrlist);
xqm->qm_dqfrlist_cnt = 0;
mutex_init(&xqm->qm_dqfrlist_lock);
/* /*
* dquot zone. we register our own low-memory callback. * dquot zone. we register our own low-memory callback.
...@@ -193,6 +192,7 @@ STATIC void ...@@ -193,6 +192,7 @@ STATIC void
xfs_qm_destroy( xfs_qm_destroy(
struct xfs_qm *xqm) struct xfs_qm *xqm)
{ {
struct xfs_dquot *dqp, *n;
int hsize, i; int hsize, i;
ASSERT(xqm != NULL); ASSERT(xqm != NULL);
...@@ -208,7 +208,21 @@ xfs_qm_destroy( ...@@ -208,7 +208,21 @@ xfs_qm_destroy(
xqm->qm_usr_dqhtable = NULL; xqm->qm_usr_dqhtable = NULL;
xqm->qm_grp_dqhtable = NULL; xqm->qm_grp_dqhtable = NULL;
xqm->qm_dqhashmask = 0; xqm->qm_dqhashmask = 0;
xfs_qm_freelist_destroy(&(xqm->qm_dqfreelist));
/* frlist cleanup */
mutex_lock(&xqm->qm_dqfrlist_lock);
list_for_each_entry_safe(dqp, n, &xqm->qm_dqfrlist, q_freelist) {
xfs_dqlock(dqp);
#ifdef QUOTADEBUG
cmn_err(CE_DEBUG, "FREELIST destroy 0x%p", dqp);
#endif
list_del_init(&dqp->q_freelist);
xfs_Gqm->qm_dqfrlist_cnt--;
xfs_dqunlock(dqp);
xfs_qm_dqdestroy(dqp);
}
mutex_unlock(&xqm->qm_dqfrlist_lock);
mutex_destroy(&xqm->qm_dqfrlist_lock);
#ifdef DEBUG #ifdef DEBUG
mutex_destroy(&qcheck_lock); mutex_destroy(&qcheck_lock);
#endif #endif
...@@ -260,7 +274,7 @@ STATIC void ...@@ -260,7 +274,7 @@ STATIC void
xfs_qm_rele_quotafs_ref( xfs_qm_rele_quotafs_ref(
struct xfs_mount *mp) struct xfs_mount *mp)
{ {
xfs_dquot_t *dqp, *nextdqp; xfs_dquot_t *dqp, *n;
ASSERT(xfs_Gqm); ASSERT(xfs_Gqm);
ASSERT(xfs_Gqm->qm_nrefs > 0); ASSERT(xfs_Gqm->qm_nrefs > 0);
...@@ -268,26 +282,24 @@ xfs_qm_rele_quotafs_ref( ...@@ -268,26 +282,24 @@ xfs_qm_rele_quotafs_ref(
/* /*
* Go thru the freelist and destroy all inactive dquots. * Go thru the freelist and destroy all inactive dquots.
*/ */
xfs_qm_freelist_lock(xfs_Gqm); mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
for (dqp = xfs_Gqm->qm_dqfreelist.qh_next; list_for_each_entry_safe(dqp, n, &xfs_Gqm->qm_dqfrlist, q_freelist) {
dqp != (xfs_dquot_t *)&(xfs_Gqm->qm_dqfreelist); ) {
xfs_dqlock(dqp); xfs_dqlock(dqp);
nextdqp = dqp->dq_flnext;
if (dqp->dq_flags & XFS_DQ_INACTIVE) { if (dqp->dq_flags & XFS_DQ_INACTIVE) {
ASSERT(dqp->q_mount == NULL); ASSERT(dqp->q_mount == NULL);
ASSERT(! XFS_DQ_IS_DIRTY(dqp)); ASSERT(! XFS_DQ_IS_DIRTY(dqp));
ASSERT(list_empty(&dqp->q_hashlist)); ASSERT(list_empty(&dqp->q_hashlist));
ASSERT(list_empty(&dqp->q_mplist)); ASSERT(list_empty(&dqp->q_mplist));
XQM_FREELIST_REMOVE(dqp); list_del_init(&dqp->q_freelist);
xfs_Gqm->qm_dqfrlist_cnt--;
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_qm_dqdestroy(dqp); xfs_qm_dqdestroy(dqp);
} else { } else {
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
} }
dqp = nextdqp;
} }
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
/* /*
* Destroy the entire XQM. If somebody mounts with quotaon, this'll * Destroy the entire XQM. If somebody mounts with quotaon, this'll
...@@ -1943,9 +1955,9 @@ xfs_qm_dqreclaim_one(void) ...@@ -1943,9 +1955,9 @@ xfs_qm_dqreclaim_one(void)
/* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */ /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */
startagain: startagain:
xfs_qm_freelist_lock(xfs_Gqm); mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
FOREACH_DQUOT_IN_FREELIST(dqp, &(xfs_Gqm->qm_dqfreelist)) { list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) {
struct xfs_mount *mp = dqp->q_mount; struct xfs_mount *mp = dqp->q_mount;
xfs_dqlock(dqp); xfs_dqlock(dqp);
...@@ -1961,7 +1973,7 @@ xfs_qm_dqreclaim_one(void) ...@@ -1961,7 +1973,7 @@ xfs_qm_dqreclaim_one(void)
trace_xfs_dqreclaim_want(dqp); trace_xfs_dqreclaim_want(dqp);
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return NULL; return NULL;
XQM_STATS_INC(xqmstats.xs_qm_dqwants); XQM_STATS_INC(xqmstats.xs_qm_dqwants);
...@@ -1978,7 +1990,8 @@ xfs_qm_dqreclaim_one(void) ...@@ -1978,7 +1990,8 @@ xfs_qm_dqreclaim_one(void)
ASSERT(! XFS_DQ_IS_DIRTY(dqp)); ASSERT(! XFS_DQ_IS_DIRTY(dqp));
ASSERT(list_empty(&dqp->q_hashlist)); ASSERT(list_empty(&dqp->q_hashlist));
ASSERT(list_empty(&dqp->q_mplist)); ASSERT(list_empty(&dqp->q_mplist));
XQM_FREELIST_REMOVE(dqp); list_del_init(&dqp->q_freelist);
xfs_Gqm->qm_dqfrlist_cnt--;
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
dqpout = dqp; dqpout = dqp;
XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
...@@ -2043,7 +2056,7 @@ xfs_qm_dqreclaim_one(void) ...@@ -2043,7 +2056,7 @@ xfs_qm_dqreclaim_one(void)
mutex_unlock(&dqp->q_hash->qh_lock); mutex_unlock(&dqp->q_hash->qh_lock);
xfs_dqfunlock(dqp); xfs_dqfunlock(dqp);
xfs_dqunlock(dqp); xfs_dqunlock(dqp);
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
if (restarts++ >= XFS_QM_RECLAIM_MAX_RESTARTS) if (restarts++ >= XFS_QM_RECLAIM_MAX_RESTARTS)
return NULL; return NULL;
goto startagain; goto startagain;
...@@ -2055,7 +2068,8 @@ xfs_qm_dqreclaim_one(void) ...@@ -2055,7 +2068,8 @@ xfs_qm_dqreclaim_one(void)
mp->m_quotainfo->qi_dqreclaims++; mp->m_quotainfo->qi_dqreclaims++;
list_del_init(&dqp->q_hashlist); list_del_init(&dqp->q_hashlist);
dqp->q_hash->qh_version++; dqp->q_hash->qh_version++;
XQM_FREELIST_REMOVE(dqp); list_del_init(&dqp->q_freelist);
xfs_Gqm->qm_dqfrlist_cnt--;
dqpout = dqp; dqpout = dqp;
mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock);
mutex_unlock(&dqp->q_hash->qh_lock); mutex_unlock(&dqp->q_hash->qh_lock);
...@@ -2067,7 +2081,7 @@ xfs_qm_dqreclaim_one(void) ...@@ -2067,7 +2081,7 @@ xfs_qm_dqreclaim_one(void)
if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return NULL; return NULL;
} }
xfs_qm_freelist_unlock(xfs_Gqm); mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
return dqpout; return dqpout;
} }
...@@ -2110,7 +2124,7 @@ xfs_qm_shake(int nr_to_scan, gfp_t gfp_mask) ...@@ -2110,7 +2124,7 @@ xfs_qm_shake(int nr_to_scan, gfp_t gfp_mask)
if (!xfs_Gqm) if (!xfs_Gqm)
return 0; return 0;
nfree = xfs_Gqm->qm_dqfreelist.qh_nelems; /* free dquots */ nfree = xfs_Gqm->qm_dqfrlist_cnt; /* free dquots */
/* incore dquots in all f/s's */ /* incore dquots in all f/s's */
ndqused = atomic_read(&xfs_Gqm->qm_totaldquots) - nfree; ndqused = atomic_read(&xfs_Gqm->qm_totaldquots) - nfree;
...@@ -2550,66 +2564,3 @@ xfs_qm_vop_create_dqattach( ...@@ -2550,66 +2564,3 @@ xfs_qm_vop_create_dqattach(
} }
} }
/* ------------- list stuff -----------------*/
STATIC void
xfs_qm_freelist_init(xfs_frlist_t *ql)
{
ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
mutex_init(&ql->qh_lock);
ql->qh_version = 0;
ql->qh_nelems = 0;
}
STATIC void
xfs_qm_freelist_destroy(xfs_frlist_t *ql)
{
xfs_dquot_t *dqp, *nextdqp;
mutex_lock(&ql->qh_lock);
for (dqp = ql->qh_next;
dqp != (xfs_dquot_t *)ql; ) {
xfs_dqlock(dqp);
nextdqp = dqp->dq_flnext;
#ifdef QUOTADEBUG
cmn_err(CE_DEBUG, "FREELIST destroy 0x%p", dqp);
#endif
XQM_FREELIST_REMOVE(dqp);
xfs_dqunlock(dqp);
xfs_qm_dqdestroy(dqp);
dqp = nextdqp;
}
mutex_unlock(&ql->qh_lock);
mutex_destroy(&ql->qh_lock);
ASSERT(ql->qh_nelems == 0);
}
STATIC void
xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
{
dq->dq_flnext = ql->qh_next;
dq->dq_flprev = (xfs_dquot_t *)ql;
ql->qh_next = dq;
dq->dq_flnext->dq_flprev = dq;
xfs_Gqm->qm_dqfreelist.qh_nelems++;
xfs_Gqm->qm_dqfreelist.qh_version++;
}
void
xfs_qm_freelist_unlink(xfs_dquot_t *dq)
{
xfs_dquot_t *next = dq->dq_flnext;
xfs_dquot_t *prev = dq->dq_flprev;
next->dq_flprev = prev;
prev->dq_flnext = next;
dq->dq_flnext = dq->dq_flprev = dq;
xfs_Gqm->qm_dqfreelist.qh_nelems--;
xfs_Gqm->qm_dqfreelist.qh_version++;
}
void
xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
{
xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
}
...@@ -72,17 +72,6 @@ extern kmem_zone_t *qm_dqtrxzone; ...@@ -72,17 +72,6 @@ extern kmem_zone_t *qm_dqtrxzone;
#define XFS_QM_MAX_DQCLUSTER_LOGSZ 3 #define XFS_QM_MAX_DQCLUSTER_LOGSZ 3
typedef xfs_dqhash_t xfs_dqlist_t; typedef xfs_dqhash_t xfs_dqlist_t;
/*
* The freelist head. The first two fields match the first two in the
* xfs_dquot_t structure (in xfs_dqmarker_t)
*/
typedef struct xfs_frlist {
struct xfs_dquot *qh_next;
struct xfs_dquot *qh_prev;
struct mutex qh_lock;
uint qh_version;
uint qh_nelems;
} xfs_frlist_t;
/* /*
* Quota Manager (global) structure. Lives only in core. * Quota Manager (global) structure. Lives only in core.
...@@ -91,7 +80,9 @@ typedef struct xfs_qm { ...@@ -91,7 +80,9 @@ typedef struct xfs_qm {
xfs_dqlist_t *qm_usr_dqhtable;/* udquot hash table */ xfs_dqlist_t *qm_usr_dqhtable;/* udquot hash table */
xfs_dqlist_t *qm_grp_dqhtable;/* gdquot hash table */ xfs_dqlist_t *qm_grp_dqhtable;/* gdquot hash table */
uint qm_dqhashmask; /* # buckets in dq hashtab - 1 */ uint qm_dqhashmask; /* # buckets in dq hashtab - 1 */
xfs_frlist_t qm_dqfreelist; /* freelist of dquots */ struct list_head qm_dqfrlist; /* freelist of dquots */
struct mutex qm_dqfrlist_lock;
int qm_dqfrlist_cnt;
atomic_t qm_totaldquots; /* total incore dquots */ atomic_t qm_totaldquots; /* total incore dquots */
uint qm_nrefs; /* file systems with quota on */ uint qm_nrefs; /* file systems with quota on */
int qm_dqfree_ratio;/* ratio of free to inuse dquots */ int qm_dqfree_ratio;/* ratio of free to inuse dquots */
...@@ -177,10 +168,6 @@ extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *); ...@@ -177,10 +168,6 @@ extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint); extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint); extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
/* list stuff */
extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
#ifdef DEBUG #ifdef DEBUG
extern int xfs_qm_internalqcheck(xfs_mount_t *); extern int xfs_qm_internalqcheck(xfs_mount_t *);
#else #else
......
...@@ -55,7 +55,7 @@ static int xqm_proc_show(struct seq_file *m, void *v) ...@@ -55,7 +55,7 @@ static int xqm_proc_show(struct seq_file *m, void *v)
ndquot, ndquot,
xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0, xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0, xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0); xfs_Gqm? xfs_Gqm->qm_dqfrlist_cnt : 0);
return 0; return 0;
} }
......
...@@ -40,13 +40,6 @@ ...@@ -40,13 +40,6 @@
#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) #define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit)
#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) #define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)
#define xfs_qm_freelist_lock(qm) \
mutex_lock(&((qm)->qm_dqfreelist.qh_lock))
#define xfs_qm_freelist_lock_nowait(qm) \
mutex_trylock(&((qm)->qm_dqfreelist.qh_lock))
#define xfs_qm_freelist_unlock(qm) \
mutex_unlock(&((qm)->qm_dqfreelist.qh_lock))
/* /*
* Hash into a bucket in the dquot hash table, based on <mp, id>. * Hash into a bucket in the dquot hash table, based on <mp, id>.
*/ */
...@@ -72,16 +65,6 @@ ...@@ -72,16 +65,6 @@
!dqp->q_core.d_rtbcount && \ !dqp->q_core.d_rtbcount && \
!dqp->q_core.d_icount) !dqp->q_core.d_icount)
#define FOREACH_DQUOT_IN_FREELIST(dqp, qlist) \
for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
(dqp) = (dqp)->dq_flnext)
#define XQM_FREELIST_INSERT(h, dqp) \
xfs_qm_freelist_append(h, dqp)
#define XQM_FREELIST_REMOVE(dqp) \
xfs_qm_freelist_unlink(dqp)
#define XFS_DQ_IS_LOGITEM_INITD(dqp) ((dqp)->q_logitem.qli_dquot == (dqp)) #define XFS_DQ_IS_LOGITEM_INITD(dqp) ((dqp)->q_logitem.qli_dquot == (dqp))
#define XFS_QM_DQP_TO_DQACCT(tp, dqp) (XFS_QM_ISUDQ(dqp) ? \ #define XFS_QM_DQP_TO_DQACCT(tp, dqp) (XFS_QM_ISUDQ(dqp) ? \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment