xfs
[Top] [All Lists]

Re: [PATCH 03/10] xfs: Don't issue buffer IO direct from AIL push V2

To: Dave Chinner <david@xxxxxxxxxxxxx>
Subject: Re: [PATCH 03/10] xfs: Don't issue buffer IO direct from AIL push V2
From: Alex Elder <aelder@xxxxxxx>
Date: Fri, 05 Feb 2010 16:51:29 -0600
Cc: xfs@xxxxxxxxxxx
In-reply-to: <1265153104-29680-4-git-send-email-david@xxxxxxxxxxxxx>
References: <1265153104-29680-1-git-send-email-david@xxxxxxxxxxxxx> <1265153104-29680-4-git-send-email-david@xxxxxxxxxxxxx>
Reply-to: aelder@xxxxxxx
On Wed, 2010-02-03 at 10:24 +1100, Dave Chinner wrote:
> All buffers logged into the AIL are marked as delayed write.
> When the AIL needs to push the buffer out, it issues an async write of the
> buffer. This means that IO patterns are dependent on the order of
> buffers in the AIL.
> 
> Instead of flushing the buffer, promote the buffer in the delayed
> write list so that the next time the xfsbufd is run the buffer will
> be flushed by the xfsbufd. Return the state to the xfsaild that the
> buffer was promoted so that the xfsaild knows that it needs to cause
> the xfsbufd to run to flush the buffers that were promoted.
> 
> Using the xfsbufd for issuing the IO allows us to dispatch all
> buffer IO from the one queue. This means that we can make much more
> enlightened decisions on what order to flush buffers to disk as
> we don't have multiple places issuing IO. Optimisations to xfsbufd
> will be in a future patch.
> 
> Version 2
> - kill XFS_ITEM_FLUSHING as it is now unused.

Looks good.

> Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
> Reviewed-by: Christoph Hellwig <hch@xxxxxx>

Reviewed-by: Alex Elder <aelder@xxxxxxx>

> ---
>  fs/xfs/linux-2.6/xfs_buf.c    |   29 ++++++++++++
>  fs/xfs/linux-2.6/xfs_buf.h    |    2 +
>  fs/xfs/linux-2.6/xfs_trace.h  |    1 +
>  fs/xfs/quota/xfs_dquot_item.c |   85 +++++------------------------------
>  fs/xfs/quota/xfs_dquot_item.h |    4 --
>  fs/xfs/xfs_buf_item.c         |   64 +++++++++++++++------------
>  fs/xfs/xfs_inode_item.c       |   98 ++++++----------------------------------
>  fs/xfs/xfs_inode_item.h       |    6 ---
>  fs/xfs/xfs_trans.h            |    3 +-
>  fs/xfs/xfs_trans_ail.c        |   13 +++---
>  10 files changed, 102 insertions(+), 203 deletions(-)
> 
> diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
> index 44e20e5..b306265 100644
> --- a/fs/xfs/linux-2.6/xfs_buf.c
> +++ b/fs/xfs/linux-2.6/xfs_buf.c
> @@ -1778,6 +1778,35 @@ xfs_buf_delwri_dequeue(
>       trace_xfs_buf_delwri_dequeue(bp, _RET_IP_);
>  }
>  
> +/*
> + * If a delwri buffer needs to be pushed before it has aged out, then promote
> + * it to the head of the delwri queue so that it will be flushed on the next
> + * xfsbufd run. We do this by resetting the queuetime of the buffer to be 
> older
> + * than the age currently needed to flush the buffer. Hence the next time the
> + * xfsbufd sees it is guaranteed to be considered old enough to flush.
> + */
> +void
> +xfs_buf_delwri_promote(
> +     struct xfs_buf  *bp)
> +{
> +     struct xfs_buftarg *btp = bp->b_target;
> +     long            age = xfs_buf_age_centisecs * msecs_to_jiffies(10) + 1;
> +
> +     ASSERT(bp->b_flags & XBF_DELWRI);
> +     ASSERT(bp->b_flags & _XBF_DELWRI_Q);
> +
> +     /*
> +      * Check the buffer age before locking the delayed write queue as we
> +      * don't need to promote buffers that are already past the flush age.
> +      */
> +     if (bp->b_queuetime < jiffies - age)
> +             return;
> +     bp->b_queuetime = jiffies - age;
> +     spin_lock(&btp->bt_delwrite_lock);
> +     list_move(&bp->b_list, &btp->bt_delwrite_queue);
> +     spin_unlock(&btp->bt_delwrite_lock);
> +}
> +
>  STATIC void
>  xfs_buf_runall_queues(
>       struct workqueue_struct *queue)
> diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
> index ea8c198..be45e8c 100644
> --- a/fs/xfs/linux-2.6/xfs_buf.h
> +++ b/fs/xfs/linux-2.6/xfs_buf.h
> @@ -266,6 +266,7 @@ extern int xfs_buf_ispin(xfs_buf_t *);
>  
>  /* Delayed Write Buffer Routines */
>  extern void xfs_buf_delwri_dequeue(xfs_buf_t *);
> +extern void xfs_buf_delwri_promote(xfs_buf_t *);
>  
>  /* Buffer Daemon Setup Routines */
>  extern int xfs_buf_init(void);
> @@ -395,6 +396,7 @@ extern void xfs_free_buftarg(struct xfs_mount *, struct 
> xfs_buftarg *);
>  extern void xfs_wait_buftarg(xfs_buftarg_t *);
>  extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
>  extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
> +
>  #ifdef CONFIG_KDB_MODULES
>  extern struct list_head *xfs_get_buftarg_list(void);
>  #endif
> diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
> index 1bb09e7..a4574dc 100644
> --- a/fs/xfs/linux-2.6/xfs_trace.h
> +++ b/fs/xfs/linux-2.6/xfs_trace.h
> @@ -483,6 +483,7 @@ DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unlock);
>  DEFINE_BUF_ITEM_EVENT(xfs_buf_item_unlock_stale);
>  DEFINE_BUF_ITEM_EVENT(xfs_buf_item_committed);
>  DEFINE_BUF_ITEM_EVENT(xfs_buf_item_push);
> +DEFINE_BUF_ITEM_EVENT(xfs_buf_item_pushbuf);
>  DEFINE_BUF_ITEM_EVENT(xfs_trans_get_buf);
>  DEFINE_BUF_ITEM_EVENT(xfs_trans_get_buf_recur);
>  DEFINE_BUF_ITEM_EVENT(xfs_trans_getsb);
> diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
> index 1b56437..dda0fb0 100644
> --- a/fs/xfs/quota/xfs_dquot_item.c
> +++ b/fs/xfs/quota/xfs_dquot_item.c
> @@ -212,66 +212,31 @@ xfs_qm_dquot_logitem_pushbuf(
>       xfs_dquot_t     *dqp;
>       xfs_mount_t     *mp;
>       xfs_buf_t       *bp;
> -     uint            dopush;
>  
>       dqp = qip->qli_dquot;
>       ASSERT(XFS_DQ_IS_LOCKED(dqp));
>  
>       /*
> -      * The qli_pushbuf_flag keeps others from
> -      * trying to duplicate our effort.
> -      */
> -     ASSERT(qip->qli_pushbuf_flag != 0);
> -     ASSERT(qip->qli_push_owner == current_pid());
> -
> -     /*
>        * If flushlock isn't locked anymore, chances are that the
>        * inode flush completed and the inode was taken off the AIL.
>        * So, just get out.
>        */
>       if (completion_done(&dqp->q_flush)  ||
>           ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
> -             qip->qli_pushbuf_flag = 0;
>               xfs_dqunlock(dqp);
>               return;
>       }
>       mp = dqp->q_mount;
>       bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno,
>                   XFS_QI_DQCHUNKLEN(mp), XBF_TRYLOCK);
> -     if (bp != NULL) {
> -             if (XFS_BUF_ISDELAYWRITE(bp)) {
> -                     dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
> -                               !completion_done(&dqp->q_flush));
> -                     qip->qli_pushbuf_flag = 0;
> -                     xfs_dqunlock(dqp);
> -
> -                     if (XFS_BUF_ISPINNED(bp))
> -                             xfs_log_force(mp, 0);
> -
> -                     if (dopush) {
> -                             int     error;
> -#ifdef XFSRACEDEBUG
> -                             delay_for_intr();
> -                             delay(300);
> -#endif
> -                             error = xfs_bawrite(mp, bp);
> -                             if (error)
> -                                     xfs_fs_cmn_err(CE_WARN, mp,
> -     "xfs_qm_dquot_logitem_pushbuf: pushbuf error %d on qip %p, bp %p",
> -                                                     error, qip, bp);
> -                     } else {
> -                             xfs_buf_relse(bp);
> -                     }
> -             } else {
> -                     qip->qli_pushbuf_flag = 0;
> -                     xfs_dqunlock(dqp);
> -                     xfs_buf_relse(bp);
> -             }
> +     xfs_dqunlock(dqp);
> +     if (!bp)
>               return;
> -     }
> +     if (XFS_BUF_ISDELAYWRITE(bp))
> +             xfs_buf_delwri_promote(bp);
> +     xfs_buf_relse(bp);
> +     return;
>  
> -     qip->qli_pushbuf_flag = 0;
> -     xfs_dqunlock(dqp);
>  }
>  
>  /*
> @@ -289,50 +254,24 @@ xfs_qm_dquot_logitem_trylock(
>       xfs_dq_logitem_t        *qip)
>  {
>       xfs_dquot_t             *dqp;
> -     uint                    retval;
>  
>       dqp = qip->qli_dquot;
>       if (atomic_read(&dqp->q_pincount) > 0)
> -             return (XFS_ITEM_PINNED);
> +             return XFS_ITEM_PINNED;
>  
>       if (! xfs_qm_dqlock_nowait(dqp))
> -             return (XFS_ITEM_LOCKED);
> +             return XFS_ITEM_LOCKED;
>  
> -     retval = XFS_ITEM_SUCCESS;
>       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
> -              * get stuck waiting for that to complete.  So, we want to check
> -              * to see if we can lock the dquot's buffer without sleeping.
> -              * If we can and it is marked for delayed write, then we
> -              * hold it and send it out from the push routine.  We don't
> -              * want to do that now since we might sleep in the device
> -              * strategy routine.  We also don't want to grab the buffer lock
> -              * here because we'd like not to call into the buffer cache
> -              * while holding the AIL lock.
> -              * Make sure to only return PUSHBUF if we set pushbuf_flag
> -              * ourselves.  If someone else is doing it then we don't
> -              * want to go to the push routine and duplicate their efforts.
> +              * dquot has already been flushed to the backing buffer,
> +              * leave it locked, pushbuf routine will unlock it.
>                */
> -             if (qip->qli_pushbuf_flag == 0) {
> -                     qip->qli_pushbuf_flag = 1;
> -                     ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno);
> -#ifdef DEBUG
> -                     qip->qli_push_owner = current_pid();
> -#endif
> -                     /*
> -                      * The dquot is left locked.
> -                      */
> -                     retval = XFS_ITEM_PUSHBUF;
> -             } else {
> -                     retval = XFS_ITEM_FLUSHING;
> -                     xfs_dqunlock_nonotify(dqp);
> -             }
> +             return XFS_ITEM_PUSHBUF;
>       }
>  
>       ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
> -     return (retval);
> +     return XFS_ITEM_SUCCESS;
>  }
>  
> 
> diff --git a/fs/xfs/quota/xfs_dquot_item.h b/fs/xfs/quota/xfs_dquot_item.h
> index 5a63253..5acae2a 100644
> --- a/fs/xfs/quota/xfs_dquot_item.h
> +++ b/fs/xfs/quota/xfs_dquot_item.h
> @@ -27,10 +27,6 @@ typedef struct xfs_dq_logitem {
>       xfs_log_item_t           qli_item;         /* common portion */
>       struct xfs_dquot        *qli_dquot;        /* dquot ptr */
>       xfs_lsn_t                qli_flush_lsn;    /* lsn at last flush */
> -     unsigned short           qli_pushbuf_flag; /* 1 bit used in push_ail */
> -#ifdef DEBUG
> -     uint64_t                 qli_push_owner;
> -#endif
>       xfs_dq_logformat_t       qli_format;       /* logged structure */
>  } xfs_dq_logitem_t;
>  
> diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
> index e0a1158..f3c49e6 100644
> --- a/fs/xfs/xfs_buf_item.c
> +++ b/fs/xfs/xfs_buf_item.c
> @@ -467,8 +467,10 @@ xfs_buf_item_unpin_remove(
>  /*
>   * This is called to attempt to lock the buffer associated with this
>   * buf log item.  Don't sleep on the buffer lock.  If we can't get
> - * the lock right away, return 0.  If we can get the lock, pull the
> - * buffer from the free list, mark it busy, and return 1.
> + * the lock right away, return 0.  If we can get the lock, take a
> + * reference to the buffer. If this is a delayed write buffer that
> + * needs AIL help to be written back, invoke the pushbuf routine
> + * rather than the normal success path.
>   */
>  STATIC uint
>  xfs_buf_item_trylock(
> @@ -477,24 +479,18 @@ xfs_buf_item_trylock(
>       xfs_buf_t       *bp;
>  
>       bp = bip->bli_buf;
> -
> -     if (XFS_BUF_ISPINNED(bp)) {
> +     if (XFS_BUF_ISPINNED(bp))
>               return XFS_ITEM_PINNED;
> -     }
> -
> -     if (!XFS_BUF_CPSEMA(bp)) {
> +     if (!XFS_BUF_CPSEMA(bp))
>               return XFS_ITEM_LOCKED;
> -     }
>  
> -     /*
> -      * Remove the buffer from the free list.  Only do this
> -      * if it's on the free list.  Private buffers like the
> -      * superblock buffer are not.
> -      */
> +     /* take a reference to the buffer.  */
>       XFS_BUF_HOLD(bp);
>  
>       ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
>       trace_xfs_buf_item_trylock(bip);
> +     if (XFS_BUF_ISDELAYWRITE(bp))
> +             return XFS_ITEM_PUSHBUF;
>       return XFS_ITEM_SUCCESS;
>  }
>  
> @@ -626,11 +622,9 @@ xfs_buf_item_committed(
>  }
>  
>  /*
> - * This is called to asynchronously write the buffer associated with this
> - * buf log item out to disk. The buffer will already have been locked by
> - * a successful call to xfs_buf_item_trylock().  If the buffer still has
> - * B_DELWRI set, then get it going out to disk with a call to bawrite().
> - * If not, then just release the buffer.
> + * The buffer is locked, but is not a delayed write buffer. This happens
> + * if we race with IO completion and hence we don't want to try to write it
> + * again. Just release the buffer.
>   */
>  STATIC void
>  xfs_buf_item_push(
> @@ -642,17 +636,29 @@ xfs_buf_item_push(
>       trace_xfs_buf_item_push(bip);
>  
>       bp = bip->bli_buf;
> +     ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
> +     xfs_buf_relse(bp);
> +}
>  
> -     if (XFS_BUF_ISDELAYWRITE(bp)) {
> -             int     error;
> -             error = xfs_bawrite(bip->bli_item.li_mountp, bp);
> -             if (error)
> -                     xfs_fs_cmn_err(CE_WARN, bip->bli_item.li_mountp,
> -                     "xfs_buf_item_push: pushbuf error %d on bip %p, bp %p",
> -                                     error, bip, bp);
> -     } else {
> -             xfs_buf_relse(bp);
> -     }
> +/*
> + * The buffer is locked and is a delayed write buffer. Promote the buffer
> + * in the delayed write queue as the caller knows that they must invoke
> + * the xfsbufd to get this buffer written. We have to unlock the buffer
> + * to allow the xfsbufd to write it, too.
> + */
> +STATIC void
> +xfs_buf_item_pushbuf(
> +     xfs_buf_log_item_t      *bip)
> +{
> +     xfs_buf_t       *bp;
> +
> +     ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
> +     trace_xfs_buf_item_pushbuf(bip);
> +
> +     bp = bip->bli_buf;
> +     ASSERT(XFS_BUF_ISDELAYWRITE(bp));
> +     xfs_buf_delwri_promote(bp);
> +     xfs_buf_relse(bp);
>  }
>  
>  /* ARGSUSED */
> @@ -677,7 +683,7 @@ static struct xfs_item_ops xfs_buf_item_ops = {
>       .iop_committed  = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
>                                       xfs_buf_item_committed,
>       .iop_push       = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
> -     .iop_pushbuf    = NULL,
> +     .iop_pushbuf    = (void(*)(xfs_log_item_t*))xfs_buf_item_pushbuf,
>       .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
>                                       xfs_buf_item_committing
>  };
> diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> index 207553e..d4dc063 100644
> --- a/fs/xfs/xfs_inode_item.c
> +++ b/fs/xfs/xfs_inode_item.c
> @@ -602,33 +602,20 @@ xfs_inode_item_trylock(
>  
>       if (!xfs_iflock_nowait(ip)) {
>               /*
> -              * If someone else isn't already trying to push the inode
> -              * buffer, we get to do it.
> +              * inode has already been flushed to the backing buffer,
> +              * leave it locked in shared mode, pushbuf routine will
> +              * unlock it.
>                */
> -             if (iip->ili_pushbuf_flag == 0) {
> -                     iip->ili_pushbuf_flag = 1;
> -#ifdef DEBUG
> -                     iip->ili_push_owner = current_pid();
> -#endif
> -                     /*
> -                      * Inode is left locked in shared mode.
> -                      * Pushbuf routine gets to unlock it.
> -                      */
> -                     return XFS_ITEM_PUSHBUF;
> -             } else {
> -                     /*
> -                      * We hold the AIL lock, so we must specify the
> -                      * NONOTIFY flag so that we won't double trip.
> -                      */
> -                     xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);
> -                     return XFS_ITEM_FLUSHING;
> -             }
> -             /* NOTREACHED */
> +             return XFS_ITEM_PUSHBUF;
>       }
>  
>       /* Stale items should force out the iclog */
>       if (ip->i_flags & XFS_ISTALE) {
>               xfs_ifunlock(ip);
> +             /*
> +              * we hold the AIL lock - notify the unlock routine of this
> +              * so it doesn't try to get the lock again.
> +              */
>               xfs_iunlock(ip, XFS_ILOCK_SHARED|XFS_IUNLOCK_NONOTIFY);
>               return XFS_ITEM_PINNED;
>       }
> @@ -746,11 +733,8 @@ xfs_inode_item_committed(
>   * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK
>   * failed to get the inode flush lock but did get the inode locked SHARED.
>   * Here we're trying to see if the inode buffer is incore, and if so whether 
> it's
> - * marked delayed write. If that's the case, we'll initiate a bawrite on that
> - * buffer to expedite the process.
> - *
> - * We aren't holding the AIL lock (or the flush lock) when this gets called,
> - * so it is inherently race-y.
> + * marked delayed write. If that's the case, we'll promote it and that will
> + * allow the caller to write the buffer by triggering the xfsbufd to run.
>   */
>  STATIC void
>  xfs_inode_item_pushbuf(
> @@ -759,26 +743,16 @@ xfs_inode_item_pushbuf(
>       xfs_inode_t     *ip;
>       xfs_mount_t     *mp;
>       xfs_buf_t       *bp;
> -     uint            dopush;
>  
>       ip = iip->ili_inode;
> -
>       ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
>  
>       /*
> -      * The ili_pushbuf_flag keeps others from
> -      * trying to duplicate our effort.
> -      */
> -     ASSERT(iip->ili_pushbuf_flag != 0);
> -     ASSERT(iip->ili_push_owner == current_pid());
> -
> -     /*
>        * If a flush is not in progress anymore, chances are that the
>        * inode was taken off the AIL. So, just get out.
>        */
>       if (completion_done(&ip->i_flush) ||
>           ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
> -             iip->ili_pushbuf_flag = 0;
>               xfs_iunlock(ip, XFS_ILOCK_SHARED);
>               return;
>       }
> @@ -787,53 +761,12 @@ xfs_inode_item_pushbuf(
>       bp = xfs_incore(mp->m_ddev_targp, iip->ili_format.ilf_blkno,
>                   iip->ili_format.ilf_len, XBF_TRYLOCK);
>  
> -     if (bp != NULL) {
> -             if (XFS_BUF_ISDELAYWRITE(bp)) {
> -                     /*
> -                      * We were racing with iflush because we don't hold
> -                      * the AIL lock or the flush lock. However, at this 
> point,
> -                      * we have the buffer, and we know that it's dirty.
> -                      * So, it's possible that iflush raced with us, and
> -                      * this item is already taken off the AIL.
> -                      * If not, we can flush it async.
> -                      */
> -                     dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
> -                               !completion_done(&ip->i_flush));
> -                     iip->ili_pushbuf_flag = 0;
> -                     xfs_iunlock(ip, XFS_ILOCK_SHARED);
> -
> -                     trace_xfs_inode_item_push(bp, _RET_IP_);
> -
> -                     if (XFS_BUF_ISPINNED(bp))
> -                             xfs_log_force(mp, 0);
> -
> -                     if (dopush) {
> -                             int     error;
> -                             error = xfs_bawrite(mp, bp);
> -                             if (error)
> -                                     xfs_fs_cmn_err(CE_WARN, mp,
> -             "xfs_inode_item_pushbuf: pushbuf error %d on iip %p, bp %p",
> -                                                     error, iip, bp);
> -                     } else {
> -                             xfs_buf_relse(bp);
> -                     }
> -             } else {
> -                     iip->ili_pushbuf_flag = 0;
> -                     xfs_iunlock(ip, XFS_ILOCK_SHARED);
> -                     xfs_buf_relse(bp);
> -             }
> -             return;
> -     }
> -     /*
> -      * We have to be careful about resetting pushbuf flag too early (above).
> -      * Even though in theory we can do it as soon as we have the buflock,
> -      * we don't want others to be doing work needlessly. They'll come to
> -      * this function thinking that pushing the buffer is their
> -      * responsibility only to find that the buffer is still locked by
> -      * another doing the same thing
> -      */
> -     iip->ili_pushbuf_flag = 0;
>       xfs_iunlock(ip, XFS_ILOCK_SHARED);
> +     if (!bp)
> +             return;
> +     if (XFS_BUF_ISDELAYWRITE(bp))
> +             xfs_buf_delwri_promote(bp);
> +     xfs_buf_relse(bp);
>       return;
>  }
>  
> @@ -937,7 +870,6 @@ xfs_inode_item_init(
>       /*
>          We have zeroed memory. No need ...
>          iip->ili_extents_buf = NULL;
> -        iip->ili_pushbuf_flag = 0;
>        */
>  
>       iip->ili_format.ilf_type = XFS_LI_INODE;
> diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
> index cc8df1a..9a46795 100644
> --- a/fs/xfs/xfs_inode_item.h
> +++ b/fs/xfs/xfs_inode_item.h
> @@ -144,12 +144,6 @@ typedef struct xfs_inode_log_item {
>                                                     data exts */
>       struct xfs_bmbt_rec     *ili_aextents_buf; /* array of logged
>                                                     attr exts */
> -     unsigned int            ili_pushbuf_flag;  /* one bit used in push_ail 
> */
> -
> -#ifdef DEBUG
> -     uint64_t                ili_push_owner;    /* one who sets pushbuf_flag
> -                                                   above gets to push the 
> buf */
> -#endif
>  #ifdef XFS_TRANS_DEBUG
>       int                     ili_root_size;
>       char                    *ili_orig_root;
> diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> index ca64f33..c93e3a1 100644
> --- a/fs/xfs/xfs_trans.h
> +++ b/fs/xfs/xfs_trans.h
> @@ -861,8 +861,7 @@ typedef struct xfs_item_ops {
>  #define      XFS_ITEM_SUCCESS        0
>  #define      XFS_ITEM_PINNED         1
>  #define      XFS_ITEM_LOCKED         2
> -#define      XFS_ITEM_FLUSHING       3
> -#define XFS_ITEM_PUSHBUF     4
> +#define XFS_ITEM_PUSHBUF     3
>  
>  /*
>   * This structure is used to maintain a list of block ranges that have been
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index d7b1af8..e799824 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -253,6 +253,7 @@ xfsaild_push(
>       int             flush_log, count, stuck;
>       xfs_mount_t     *mp = ailp->xa_mount;
>       struct xfs_ail_cursor   *cur = &ailp->xa_cursors;
> +     int             push_xfsbufd = 0;
>  
>       spin_lock(&ailp->xa_lock);
>       xfs_trans_ail_cursor_init(ailp, cur);
> @@ -308,6 +309,7 @@ xfsaild_push(
>                       XFS_STATS_INC(xs_push_ail_pushbuf);
>                       IOP_PUSHBUF(lip);
>                       last_pushed_lsn = lsn;
> +                     push_xfsbufd = 1;
>                       break;
>  
>               case XFS_ITEM_PINNED:
> @@ -322,12 +324,6 @@ xfsaild_push(
>                       stuck++;
>                       break;
>  
> -             case XFS_ITEM_FLUSHING:
> -                     XFS_STATS_INC(xs_push_ail_flushing);
> -                     last_pushed_lsn = lsn;
> -                     stuck++;
> -                     break;
> -
>               default:
>                       ASSERT(0);
>                       break;
> @@ -374,6 +370,11 @@ xfsaild_push(
>               xfs_log_force(mp, 0);
>       }
>  
> +     if (push_xfsbufd) {
> +             /* we've got delayed write buffers to flush */
> +             wake_up_process(mp->m_ddev_targp->bt_task);
> +     }
> +
>       if (!count) {
>               /* We're past our target or empty, so idle */
>               last_pushed_lsn = 0;



<Prev in Thread] Current Thread [Next in Thread>