Skip to content

Commit

Permalink
[XFS] replace dquot flush semaphore with a completion
Browse files Browse the repository at this point in the history
Use the new completion flush code to implement the dquot flush lock.
Removes one of the final users of semaphores in the XFS code base.

SGI-PV: 981498

SGI-Modid: xfs-linux-melb:xfs-kern:31822a

Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
  • Loading branch information
David Chinner authored and Lachlan McIlroy committed Aug 13, 2008
1 parent c63942d commit e1f49cf
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 41 deletions.
34 changes: 12 additions & 22 deletions fs/xfs/quota/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,16 @@ xfs_qm_dqinit(
if (brandnewdquot) {
dqp->dq_flnext = dqp->dq_flprev = dqp;
mutex_init(&dqp->q_qlock);
initnsema(&dqp->q_flock, 1, "fdq");
sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");

/*
* Because we want to use a counting completion, complete
* the flush completion once to allow a single access to
* the flush completion without blocking.
*/
init_completion(&dqp->q_flush);
complete(&dqp->q_flush);

#ifdef XFS_DQUOT_TRACE
dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_SLEEP);
xfs_dqtrace_entry(dqp, "DQINIT");
Expand Down Expand Up @@ -150,7 +157,6 @@ xfs_qm_dqdestroy(
ASSERT(! XFS_DQ_IS_ON_FREELIST(dqp));

mutex_destroy(&dqp->q_qlock);
freesema(&dqp->q_flock);
sv_destroy(&dqp->q_pinwait);

#ifdef XFS_DQUOT_TRACE
Expand Down Expand Up @@ -1211,7 +1217,7 @@ xfs_qm_dqflush(
int error;

ASSERT(XFS_DQ_IS_LOCKED(dqp));
ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp));
ASSERT(!completion_done(&dqp->q_flush));
xfs_dqtrace_entry(dqp, "DQFLUSH");

/*
Expand Down Expand Up @@ -1348,34 +1354,18 @@ xfs_qm_dqflush_done(
xfs_dqfunlock(dqp);
}


int
xfs_qm_dqflock_nowait(
xfs_dquot_t *dqp)
{
int locked;

locked = cpsema(&((dqp)->q_flock));

/* XXX ifdef these out */
if (locked)
(dqp)->dq_flags |= XFS_DQ_FLOCKED;
return (locked);
}


int
xfs_qm_dqlock_nowait(
xfs_dquot_t *dqp)
{
return (mutex_trylock(&((dqp)->q_qlock)));
return mutex_trylock(&dqp->q_qlock);
}

void
xfs_dqlock(
xfs_dquot_t *dqp)
{
mutex_lock(&(dqp->q_qlock));
mutex_lock(&dqp->q_qlock);
}

void
Expand Down Expand Up @@ -1468,7 +1458,7 @@ xfs_qm_dqpurge(
* if we're turning off quotas. Basically, we need this flush
* lock, and are willing to block on it.
*/
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
/*
* Block on the flush lock after nudging dquot buffer,
* if it is incore.
Expand Down
29 changes: 18 additions & 11 deletions fs/xfs/quota/xfs_dquot.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ typedef struct xfs_dquot {
xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */
xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */
mutex_t q_qlock; /* quota lock */
sema_t q_flock; /* flush lock */
struct completion q_flush; /* flush completion queue */
uint q_pincount; /* pin count for this dquot */
sv_t q_pinwait; /* sync var for pinning */
#ifdef XFS_DQUOT_TRACE
Expand Down Expand Up @@ -113,17 +113,25 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)


/*
* The following three routines simply manage the q_flock
* semaphore embedded in the dquot. This semaphore synchronizes
* processes attempting to flush the in-core dquot back to disk.
* Manage the q_flush completion queue embedded in the dquot. This completion
* queue synchronizes processes attempting to flush the in-core dquot back to
* disk.
*/
#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
(dqp)->dq_flags |= XFS_DQ_FLOCKED; }
#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
vsema(&((dqp)->q_flock)); \
(dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
static inline void xfs_dqflock(xfs_dquot_t *dqp)
{
wait_for_completion(&dqp->q_flush);
}

static inline int xfs_dqflock_nowait(xfs_dquot_t *dqp)
{
return try_wait_for_completion(&dqp->q_flush);
}

static inline void xfs_dqfunlock(xfs_dquot_t *dqp)
{
complete(&dqp->q_flush);
}

#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
Expand Down Expand Up @@ -167,7 +175,6 @@ extern int xfs_qm_dqflush(xfs_dquot_t *, uint);
extern int xfs_qm_dqpurge(xfs_dquot_t *);
extern void xfs_qm_dqunpin_wait(xfs_dquot_t *);
extern int xfs_qm_dqlock_nowait(xfs_dquot_t *);
extern int xfs_qm_dqflock_nowait(xfs_dquot_t *);
extern void xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t *dqp);
extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
xfs_disk_dquot_t *);
Expand Down
8 changes: 4 additions & 4 deletions fs/xfs/quota/xfs_dquot_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ xfs_qm_dquot_logitem_push(
dqp = logitem->qli_dquot;

ASSERT(XFS_DQ_IS_LOCKED(dqp));
ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp));
ASSERT(!completion_done(&dqp->q_flush));

/*
* Since we were able to lock the dquot's flush lock and
Expand Down Expand Up @@ -245,7 +245,7 @@ xfs_qm_dquot_logitem_pushbuf(
* inode flush completed and the inode was taken off the AIL.
* So, just get out.
*/
if (!issemalocked(&(dqp->q_flock)) ||
if (completion_done(&dqp->q_flush) ||
((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
qip->qli_pushbuf_flag = 0;
xfs_dqunlock(dqp);
Expand All @@ -258,7 +258,7 @@ xfs_qm_dquot_logitem_pushbuf(
if (bp != NULL) {
if (XFS_BUF_ISDELAYWRITE(bp)) {
dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
issemalocked(&(dqp->q_flock)));
!completion_done(&dqp->q_flush));
qip->qli_pushbuf_flag = 0;
xfs_dqunlock(dqp);

Expand Down Expand Up @@ -317,7 +317,7 @@ xfs_qm_dquot_logitem_trylock(
return (XFS_ITEM_LOCKED);

retval = XFS_ITEM_SUCCESS;
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
/*
* The dquot is already being flushed. It may have been
* flushed delayed write, however, and we don't want to
Expand Down
8 changes: 4 additions & 4 deletions fs/xfs/quota/xfs_qm.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ xfs_qm_dqflush_all(
xfs_dqtrace_entry(dqp, "FLUSHALL: DQDIRTY");
/* XXX a sentinel would be better */
recl = XFS_QI_MPLRECLAIMS(mp);
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
/*
* If we can't grab the flush lock then check
* to see if the dquot has been flushed delayed
Expand Down Expand Up @@ -1062,7 +1062,7 @@ xfs_qm_sync(

/* XXX a sentinel would be better */
recl = XFS_QI_MPLRECLAIMS(mp);
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
if (nowait) {
xfs_dqunlock(dqp);
continue;
Expand Down Expand Up @@ -2079,7 +2079,7 @@ xfs_qm_shake_freelist(
* Try to grab the flush lock. If this dquot is in the process of
* getting flushed to disk, we don't want to reclaim it.
*/
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
xfs_dqunlock(dqp);
dqp = dqp->dq_flnext;
continue;
Expand Down Expand Up @@ -2257,7 +2257,7 @@ xfs_qm_dqreclaim_one(void)
* Try to grab the flush lock. If this dquot is in the process of
* getting flushed to disk, we don't want to reclaim it.
*/
if (! xfs_qm_dqflock_nowait(dqp)) {
if (!xfs_dqflock_nowait(dqp)) {
xfs_dqunlock(dqp);
continue;
}
Expand Down

0 comments on commit e1f49cf

Please sign in to comment.