Skip to content

Commit

Permalink
xfs: sanitize qh_lock wrappers
Browse files Browse the repository at this point in the history
Get rid of various obsfucating wrappers for accessing the quota hash lock,
we only keep the accessors for accessing the mplist and freelist locks as
they encode a multi-level datastructure walk.  But make sure all of them
are defined in the same way as simple macros.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
Christoph Hellwig authored and Christoph Hellwig committed Feb 9, 2009
1 parent 7201813 commit c9a192d
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 81 deletions.
28 changes: 14 additions & 14 deletions fs/xfs/quota/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ xfs_qm_dqlookup(
uint flist_locked;
xfs_dquot_t *d;

ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
ASSERT(mutex_is_locked(&qh->qh_lock));

flist_locked = B_FALSE;

Expand Down Expand Up @@ -877,7 +877,7 @@ xfs_qm_dqlookup(
/*
* move the dquot to the front of the hashchain
*/
ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
ASSERT(mutex_is_locked(&qh->qh_lock));
if (dqp->HL_PREVP != &qh->qh_next) {
xfs_dqtrace_entry(dqp,
"DQLOOKUP: HASH MOVETOFRONT");
Expand All @@ -892,13 +892,13 @@ xfs_qm_dqlookup(
}
xfs_dqtrace_entry(dqp, "LOOKUP END");
*O_dqpp = dqp;
ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
ASSERT(mutex_is_locked(&qh->qh_lock));
return (0);
}
}

*O_dqpp = NULL;
ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
ASSERT(mutex_is_locked(&qh->qh_lock));
return (1);
}

Expand Down Expand Up @@ -956,7 +956,7 @@ xfs_qm_dqget(
ASSERT(ip->i_gdquot == NULL);
}
#endif
XFS_DQ_HASH_LOCK(h);
mutex_lock(&h->qh_lock);

/*
* Look in the cache (hashtable).
Expand All @@ -971,7 +971,7 @@ xfs_qm_dqget(
*/
ASSERT(*O_dqpp);
ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp));
XFS_DQ_HASH_UNLOCK(h);
mutex_unlock(&h->qh_lock);
xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)");
return (0); /* success */
}
Expand All @@ -991,7 +991,7 @@ xfs_qm_dqget(
* we don't keep the lock across a disk read
*/
version = h->qh_version;
XFS_DQ_HASH_UNLOCK(h);
mutex_unlock(&h->qh_lock);

/*
* Allocate the dquot on the kernel heap, and read the ondisk
Expand Down Expand Up @@ -1056,7 +1056,7 @@ xfs_qm_dqget(
/*
* Hashlock comes after ilock in lock order
*/
XFS_DQ_HASH_LOCK(h);
mutex_lock(&h->qh_lock);
if (version != h->qh_version) {
xfs_dquot_t *tmpdqp;
/*
Expand All @@ -1072,7 +1072,7 @@ xfs_qm_dqget(
* and start over.
*/
xfs_qm_dqput(tmpdqp);
XFS_DQ_HASH_UNLOCK(h);
mutex_unlock(&h->qh_lock);
xfs_qm_dqdestroy(dqp);
XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
goto again;
Expand All @@ -1083,7 +1083,7 @@ xfs_qm_dqget(
* Put the dquot at the beginning of the hash-chain and mp's list
* LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock ..
*/
ASSERT(XFS_DQ_IS_HASH_LOCKED(h));
ASSERT(mutex_is_locked(&h->qh_lock));
dqp->q_hash = h;
XQM_HASHLIST_INSERT(h, dqp);

Expand All @@ -1102,7 +1102,7 @@ xfs_qm_dqget(
XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp);

xfs_qm_mplist_unlock(mp);
XFS_DQ_HASH_UNLOCK(h);
mutex_unlock(&h->qh_lock);
dqret:
ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL));
xfs_dqtrace_entry(dqp, "DQGET DONE");
Expand Down Expand Up @@ -1440,7 +1440,7 @@ xfs_qm_dqpurge(
xfs_mount_t *mp = dqp->q_mount;

ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash));
ASSERT(mutex_is_locked(&dqp->q_hash->qh_lock));

xfs_dqlock(dqp);
/*
Expand All @@ -1453,7 +1453,7 @@ xfs_qm_dqpurge(
*/
if (dqp->q_nrefs != 0) {
xfs_dqunlock(dqp);
XFS_DQ_HASH_UNLOCK(dqp->q_hash);
mutex_unlock(&dqp->q_hash->qh_lock);
return (1);
}

Expand Down Expand Up @@ -1517,7 +1517,7 @@ xfs_qm_dqpurge(
memset(&dqp->q_core, 0, sizeof(dqp->q_core));
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
XFS_DQ_HASH_UNLOCK(thishash);
mutex_unlock(&thishash->qh_lock);
return (0);
}

Expand Down
49 changes: 8 additions & 41 deletions fs/xfs/quota/xfs_qm.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ 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_mplist_nowait(xfs_mount_t *);
STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);

STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
Expand Down Expand Up @@ -576,10 +574,10 @@ xfs_qm_dqpurge_int(
continue;
}

if (! xfs_qm_dqhashlock_nowait(dqp)) {
if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
nrecl = XFS_QI_MPLRECLAIMS(mp);
xfs_qm_mplist_unlock(mp);
XFS_DQ_HASH_LOCK(dqp->q_hash);
mutex_lock(&dqp->q_hash->qh_lock);
xfs_qm_mplist_lock(mp);

/*
Expand All @@ -589,7 +587,7 @@ xfs_qm_dqpurge_int(
* this point, but somebody might be taking things off.
*/
if (nrecl != XFS_QI_MPLRECLAIMS(mp)) {
XFS_DQ_HASH_UNLOCK(dqp->q_hash);
mutex_unlock(&dqp->q_hash->qh_lock);
goto again;
}
}
Expand Down Expand Up @@ -2027,7 +2025,7 @@ xfs_qm_shake_freelist(
* a dqlookup process that holds the hashlock that is
* waiting for the freelist lock.
*/
if (! xfs_qm_dqhashlock_nowait(dqp)) {
if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
dqp = dqp->dq_flnext;
Expand All @@ -2044,7 +2042,7 @@ xfs_qm_shake_freelist(
/* XXX put a sentinel so that we can come back here */
xfs_dqfunlock(dqp);
xfs_dqunlock(dqp);
XFS_DQ_HASH_UNLOCK(hash);
mutex_unlock(&hash->qh_lock);
xfs_qm_freelist_unlock(xfs_Gqm);
if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
return nreclaimed;
Expand All @@ -2061,7 +2059,7 @@ xfs_qm_shake_freelist(
XQM_HASHLIST_REMOVE(hash, dqp);
xfs_dqfunlock(dqp);
xfs_qm_mplist_unlock(dqp->q_mount);
XFS_DQ_HASH_UNLOCK(hash);
mutex_unlock(&hash->qh_lock);

off_freelist:
XQM_FREELIST_REMOVE(dqp);
Expand Down Expand Up @@ -2203,7 +2201,7 @@ xfs_qm_dqreclaim_one(void)
continue;
}

if (! xfs_qm_dqhashlock_nowait(dqp))
if (!mutex_trylock(&dqp->q_hash->qh_lock))
goto mplistunlock;

ASSERT(dqp->q_nrefs == 0);
Expand All @@ -2212,7 +2210,7 @@ xfs_qm_dqreclaim_one(void)
XQM_HASHLIST_REMOVE(dqp->q_hash, dqp);
XQM_FREELIST_REMOVE(dqp);
dqpout = dqp;
XFS_DQ_HASH_UNLOCK(dqp->q_hash);
mutex_unlock(&dqp->q_hash->qh_lock);
mplistunlock:
xfs_qm_mplist_unlock(dqp->q_mount);
xfs_dqfunlock(dqp);
Expand Down Expand Up @@ -2715,34 +2713,3 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
{
xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
}

STATIC int
xfs_qm_dqhashlock_nowait(
xfs_dquot_t *dqp)
{
int locked;

locked = mutex_trylock(&((dqp)->q_hash->qh_lock));
return locked;
}

int
xfs_qm_freelist_lock_nowait(
xfs_qm_t *xqm)
{
int locked;

locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock));
return locked;
}

STATIC int
xfs_qm_mplist_nowait(
xfs_mount_t *mp)
{
int locked;

ASSERT(mp->m_quotainfo);
locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp)));
return locked;
}
1 change: 0 additions & 1 deletion fs/xfs/quota/xfs_qm.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
/* list stuff */
extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);

/* system call interface */
extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
Expand Down
40 changes: 15 additions & 25 deletions fs/xfs/quota/xfs_quota_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,34 +42,24 @@
#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)

#define XFS_QI_MPL_LIST(mp) ((mp)->m_quotainfo->qi_dqlist)
#define XFS_QI_MPLLOCK(mp) ((mp)->m_quotainfo->qi_dqlist.qh_lock)
#define XFS_QI_MPLNEXT(mp) ((mp)->m_quotainfo->qi_dqlist.qh_next)
#define XFS_QI_MPLNDQUOTS(mp) ((mp)->m_quotainfo->qi_dqlist.qh_nelems)

#define XQMLCK(h) (mutex_lock(&((h)->qh_lock)))
#define XQMUNLCK(h) (mutex_unlock(&((h)->qh_lock)))
#ifdef DEBUG
struct xfs_dqhash;
static inline int XQMISLCKD(struct xfs_dqhash *h)
{
if (mutex_trylock(&h->qh_lock)) {
mutex_unlock(&h->qh_lock);
return 0;
}
return 1;
}
#endif

#define XFS_DQ_HASH_LOCK(h) XQMLCK(h)
#define XFS_DQ_HASH_UNLOCK(h) XQMUNLCK(h)
#define XFS_DQ_IS_HASH_LOCKED(h) XQMISLCKD(h)

#define xfs_qm_mplist_lock(mp) XQMLCK(&(XFS_QI_MPL_LIST(mp)))
#define xfs_qm_mplist_unlock(mp) XQMUNLCK(&(XFS_QI_MPL_LIST(mp)))
#define XFS_QM_IS_MPLIST_LOCKED(mp) XQMISLCKD(&(XFS_QI_MPL_LIST(mp)))

#define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist))
#define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist))
#define xfs_qm_mplist_lock(mp) \
mutex_lock(&(XFS_QI_MPL_LIST(mp).qh_lock))
#define xfs_qm_mplist_nowait(mp) \
mutex_trylock(&(XFS_QI_MPL_LIST(mp).qh_lock))
#define xfs_qm_mplist_unlock(mp) \
mutex_unlock(&(XFS_QI_MPL_LIST(mp).qh_lock))
#define XFS_QM_IS_MPLIST_LOCKED(mp) \
mutex_is_locked(&(XFS_QI_MPL_LIST(mp).qh_lock))

#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>.
Expand Down

0 comments on commit c9a192d

Please sign in to comment.