diff mbox

[1/3] xfs: use atomic operations to handle xfs_log_item flags

Message ID 20170522153220.25072-2-cmaiolino@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Carlos Maiolino May 22, 2017, 3:32 p.m. UTC
In order to fix a bug during buffer retries, a new flag type will be
added to xfs_log_item, and such operations need to be atomic.

Change all operations in xfs_log_item flags to atomic operations

To use atomic operations, xfs_log_item->li_flags also needed to be
converted to unsigned long type.

There is a small whitespace cleanup in the patch too

Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
---
 fs/xfs/xfs_bmap_item.c     |  4 ++--
 fs/xfs/xfs_buf_item.c      |  4 ++--
 fs/xfs/xfs_dquot.c         |  2 +-
 fs/xfs/xfs_extfree_item.c  |  4 ++--
 fs/xfs/xfs_icache.c        |  2 +-
 fs/xfs/xfs_icreate_item.c  |  2 +-
 fs/xfs/xfs_inode.c         |  4 ++--
 fs/xfs/xfs_inode_item.c    |  2 +-
 fs/xfs/xfs_qm.c            |  2 +-
 fs/xfs/xfs_refcount_item.c |  4 ++--
 fs/xfs/xfs_rmap_item.c     |  4 ++--
 fs/xfs/xfs_trace.h         |  4 ++--
 fs/xfs/xfs_trans.c         |  4 ++--
 fs/xfs/xfs_trans.h         |  2 +-
 fs/xfs/xfs_trans_ail.c     | 12 ++++++------
 fs/xfs/xfs_trans_buf.c     |  2 +-
 fs/xfs/xfs_trans_priv.h    |  2 +-
 17 files changed, 30 insertions(+), 30 deletions(-)

Comments

Christoph Hellwig May 22, 2017, 7:11 p.m. UTC | #1
> --- a/fs/xfs/xfs_buf_item.c
> +++ b/fs/xfs/xfs_buf_item.c
> @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
>  	 * (cancelled) buffers at unpin time, but we'll never go through the
>  	 * pin/unpin cycle if we abort inside commit.
>  	 */
> -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;

	aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags);

does the same job in a slightly simpler way.

> +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));

no need for the inner braces.

> +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));

Same here.  Also please don't break lines after 80 characters.

> +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));

Also no need for the braces around test_bit here.

> +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {

.. again

> +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));

.. again

Also last but not least the arguments to the *_bit functions are
bit indices, so they should be renumber to 0 and 1 (and the tracing
helpers will need some updates as well).
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Carlos Maiolino May 23, 2017, 10:35 a.m. UTC | #2
Hi,

On Mon, May 22, 2017 at 12:11:11PM -0700, Christoph Hellwig wrote:
> > --- a/fs/xfs/xfs_buf_item.c
> > +++ b/fs/xfs/xfs_buf_item.c
> > @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
> >  	 * (cancelled) buffers at unpin time, but we'll never go through the
> >  	 * pin/unpin cycle if we abort inside commit.
> >  	 */
> > -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> > +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
> 
> 	aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags);
> 
> does the same job in a slightly simpler way.
> 
> > +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> 
> no need for the inner braces.
> 
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
> 
> Same here.  Also please don't break lines after 80 characters.
> 
> > +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
> 
> Also no need for the braces around test_bit here.
> 
> > +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
> 
> .. again
> 
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> 
> .. again
> 
> Also last but not least the arguments to the *_bit functions are
> bit indices, so they should be renumber to 0 and 1 (and the tracing
> helpers will need some updates as well).

Thanks for the review of this series, I'll queue these changes for V3.
Carlos Maiolino May 23, 2017, 10:42 a.m. UTC | #3
On Mon, May 22, 2017 at 12:11:11PM -0700, Christoph Hellwig wrote:
> > --- a/fs/xfs/xfs_buf_item.c
> > +++ b/fs/xfs/xfs_buf_item.c
> > @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
> >  	 * (cancelled) buffers at unpin time, but we'll never go through the
> >  	 * pin/unpin cycle if we abort inside commit.
> >  	 */
> > -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> > +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
> 
> 	aborted = test_bit(XFS_LI_ABORTED, &lip->li_flags);
> 
> does the same job in a slightly simpler way.
> 
> > +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> 
> no need for the inner braces.
> 
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
> 
> Same here.  Also please don't break lines after 80 characters.

Btw, I believe you meant I didn't break the line here? Removing the inner braces
will leave it with 82 chars, I wonder if it's worth to break the line here in
this case? Just looks harder to read with the line broken for just 2 chars.


> 
> > +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
> 
> Also no need for the braces around test_bit here.
> 
> > +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
> 
> .. again
> 
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> 
> .. again
> 
> Also last but not least the arguments to the *_bit functions are
> bit indices, so they should be renumber to 0 and 1 (and the tracing
> helpers will need some updates as well).
Brian Foster May 24, 2017, 5:06 p.m. UTC | #4
On Mon, May 22, 2017 at 05:32:18PM +0200, Carlos Maiolino wrote:
> In order to fix a bug during buffer retries, a new flag type will be
> added to xfs_log_item, and such operations need to be atomic.
> 
> Change all operations in xfs_log_item flags to atomic operations
> 
> To use atomic operations, xfs_log_item->li_flags also needed to be
> converted to unsigned long type.
> 
> There is a small whitespace cleanup in the patch too
> 
> Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> ---

As noted in the v1 discussion, I don't think this needs to be a
dependency of the bug fix patch. Provided we can alleviate Dave's
concerns over performance and not add any ->xa_lock acquisitions that
aren't triggered by I/O errors, can we fix the bug using ->xa_lock and
then port this on top? That way we have more of a backportable fix for
older kernels affected by this problem.

(Please see my comments on patches 2 and 3 wrt proposed changes to avoid
the custom callback and need for atomic flags..)

Brian

>  fs/xfs/xfs_bmap_item.c     |  4 ++--
>  fs/xfs/xfs_buf_item.c      |  4 ++--
>  fs/xfs/xfs_dquot.c         |  2 +-
>  fs/xfs/xfs_extfree_item.c  |  4 ++--
>  fs/xfs/xfs_icache.c        |  2 +-
>  fs/xfs/xfs_icreate_item.c  |  2 +-
>  fs/xfs/xfs_inode.c         |  4 ++--
>  fs/xfs/xfs_inode_item.c    |  2 +-
>  fs/xfs/xfs_qm.c            |  2 +-
>  fs/xfs/xfs_refcount_item.c |  4 ++--
>  fs/xfs/xfs_rmap_item.c     |  4 ++--
>  fs/xfs/xfs_trace.h         |  4 ++--
>  fs/xfs/xfs_trans.c         |  4 ++--
>  fs/xfs/xfs_trans.h         |  2 +-
>  fs/xfs/xfs_trans_ail.c     | 12 ++++++------
>  fs/xfs/xfs_trans_buf.c     |  2 +-
>  fs/xfs/xfs_trans_priv.h    |  2 +-
>  17 files changed, 30 insertions(+), 30 deletions(-)
> 
> diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
> index d419d23..9ebdca9 100644
> --- a/fs/xfs/xfs_bmap_item.c
> +++ b/fs/xfs/xfs_bmap_item.c
> @@ -141,7 +141,7 @@ STATIC void
>  xfs_bui_item_unlock(
>  	struct xfs_log_item	*lip)
>  {
> -	if (lip->li_flags & XFS_LI_ABORTED)
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
>  		xfs_bui_item_free(BUI_ITEM(lip));
>  }
>  
> @@ -304,7 +304,7 @@ xfs_bud_item_unlock(
>  {
>  	struct xfs_bud_log_item	*budp = BUD_ITEM(lip);
>  
> -	if (lip->li_flags & XFS_LI_ABORTED) {
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
>  		xfs_bui_release(budp->bud_buip);
>  		kmem_zone_free(xfs_bud_zone, budp);
>  	}
> diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
> index 0306168..6ac3816 100644
> --- a/fs/xfs/xfs_buf_item.c
> +++ b/fs/xfs/xfs_buf_item.c
> @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
>  	 * (cancelled) buffers at unpin time, but we'll never go through the
>  	 * pin/unpin cycle if we abort inside commit.
>  	 */
> -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
>  	/*
>  	 * Before possibly freeing the buf item, copy the per-transaction state
>  	 * so we can reference it safely later after clearing it from the
> @@ -975,7 +975,7 @@ xfs_buf_item_relse(
>  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
>  
>  	trace_xfs_buf_item_relse(bp, _RET_IP_);
> -	ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
>  
>  	bp->b_fspriv = bip->bli_item.li_bio_list;
>  	if (bp->b_fspriv == NULL)
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 9d06cc3..e8f2cbc 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -1003,7 +1003,7 @@ xfs_qm_dqflush_done(
>  	 * since it's cheaper, and then we recheck while
>  	 * holding the lock before removing the dquot from the AIL.
>  	 */
> -	if ((lip->li_flags & XFS_LI_IN_AIL) &&
> +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) &&
>  	    lip->li_lsn == qip->qli_flush_lsn) {
>  
>  		/* xfs_trans_ail_delete() drops the AIL lock. */
> diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> index 44f8c54..32a519d 100644
> --- a/fs/xfs/xfs_extfree_item.c
> +++ b/fs/xfs/xfs_extfree_item.c
> @@ -150,7 +150,7 @@ STATIC void
>  xfs_efi_item_unlock(
>  	struct xfs_log_item	*lip)
>  {
> -	if (lip->li_flags & XFS_LI_ABORTED)
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
>  		xfs_efi_item_free(EFI_ITEM(lip));
>  }
>  
> @@ -402,7 +402,7 @@ xfs_efd_item_unlock(
>  {
>  	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
>  
> -	if (lip->li_flags & XFS_LI_ABORTED) {
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
>  		xfs_efi_release(efdp->efd_efip);
>  		xfs_efd_item_free(efdp);
>  	}
> diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> index f61c84f8..23d750f 100644
> --- a/fs/xfs/xfs_icache.c
> +++ b/fs/xfs/xfs_icache.c
> @@ -107,7 +107,7 @@ xfs_inode_free_callback(
>  		xfs_idestroy_fork(ip, XFS_COW_FORK);
>  
>  	if (ip->i_itemp) {
> -		ASSERT(!(ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL));
> +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
>  		xfs_inode_item_destroy(ip);
>  		ip->i_itemp = NULL;
>  	}
> diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
> index 865ad13..e24cf83 100644
> --- a/fs/xfs/xfs_icreate_item.c
> +++ b/fs/xfs/xfs_icreate_item.c
> @@ -91,7 +91,7 @@ xfs_icreate_item_unlock(
>  {
>  	struct xfs_icreate_item	*icp = ICR_ITEM(lip);
>  
> -	if (icp->ic_item.li_flags & XFS_LI_ABORTED)
> +	if (test_bit(XFS_LI_ABORTED, &icp->ic_item.li_flags))
>  		kmem_zone_free(xfs_icreate_zone, icp);
>  	return;
>  }
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index ec9826c..208c8c7 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -504,7 +504,7 @@ xfs_lock_inodes(
>  		if (!try_lock) {
>  			for (j = (i - 1); j >= 0 && !try_lock; j--) {
>  				lp = (xfs_log_item_t *)ips[j]->i_itemp;
> -				if (lp && (lp->li_flags & XFS_LI_IN_AIL))
> +				if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags))
>  					try_lock++;
>  			}
>  		}
> @@ -601,7 +601,7 @@ xfs_lock_two_inodes(
>  	 * and try again.
>  	 */
>  	lp = (xfs_log_item_t *)ip0->i_itemp;
> -	if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
> +	if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags)) {
>  		if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
>  			xfs_iunlock(ip0, lock_mode);
>  			if ((++attempts % 5) == 0)
> diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> index 08cb7d1..eeeadbb 100644
> --- a/fs/xfs/xfs_inode_item.c
> +++ b/fs/xfs/xfs_inode_item.c
> @@ -783,7 +783,7 @@ xfs_iflush_abort(
>  	xfs_inode_log_item_t	*iip = ip->i_itemp;
>  
>  	if (iip) {
> -		if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
> +		if (test_bit(XFS_LI_IN_AIL, &iip->ili_item.li_flags)) {
>  			xfs_trans_ail_remove(&iip->ili_item,
>  					     stale ? SHUTDOWN_LOG_IO_ERROR :
>  						     SHUTDOWN_CORRUPT_INCORE);
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 5fe6e70..da58263 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -169,7 +169,7 @@ xfs_qm_dqpurge(
>  
>  	ASSERT(atomic_read(&dqp->q_pincount) == 0);
>  	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
> -	       !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
> +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
>  
>  	xfs_dqfunlock(dqp);
>  	xfs_dqunlock(dqp);
> diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
> index 96fe209..5ecfd04 100644
> --- a/fs/xfs/xfs_refcount_item.c
> +++ b/fs/xfs/xfs_refcount_item.c
> @@ -139,7 +139,7 @@ STATIC void
>  xfs_cui_item_unlock(
>  	struct xfs_log_item	*lip)
>  {
> -	if (lip->li_flags & XFS_LI_ABORTED)
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
>  		xfs_cui_item_free(CUI_ITEM(lip));
>  }
>  
> @@ -308,7 +308,7 @@ xfs_cud_item_unlock(
>  {
>  	struct xfs_cud_log_item	*cudp = CUD_ITEM(lip);
>  
> -	if (lip->li_flags & XFS_LI_ABORTED) {
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
>  		xfs_cui_release(cudp->cud_cuip);
>  		kmem_zone_free(xfs_cud_zone, cudp);
>  	}
> diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
> index f3b139c..ada5ec7 100644
> --- a/fs/xfs/xfs_rmap_item.c
> +++ b/fs/xfs/xfs_rmap_item.c
> @@ -139,7 +139,7 @@ STATIC void
>  xfs_rui_item_unlock(
>  	struct xfs_log_item	*lip)
>  {
> -	if (lip->li_flags & XFS_LI_ABORTED)
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
>  		xfs_rui_item_free(RUI_ITEM(lip));
>  }
>  
> @@ -330,7 +330,7 @@ xfs_rud_item_unlock(
>  {
>  	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);
>  
> -	if (lip->li_flags & XFS_LI_ABORTED) {
> +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
>  		xfs_rui_release(rudp->rud_ruip);
>  		kmem_zone_free(xfs_rud_zone, rudp);
>  	}
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 7c5a165..d09e539 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -1031,7 +1031,7 @@ DECLARE_EVENT_CLASS(xfs_log_item_class,
>  		__field(dev_t, dev)
>  		__field(void *, lip)
>  		__field(uint, type)
> -		__field(uint, flags)
> +		__field(unsigned long, flags)
>  		__field(xfs_lsn_t, lsn)
>  	),
>  	TP_fast_assign(
> @@ -1083,7 +1083,7 @@ DECLARE_EVENT_CLASS(xfs_ail_class,
>  		__field(dev_t, dev)
>  		__field(void *, lip)
>  		__field(uint, type)
> -		__field(uint, flags)
> +		__field(unsigned long, flags)
>  		__field(xfs_lsn_t, old_lsn)
>  		__field(xfs_lsn_t, new_lsn)
>  	),
> diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
> index be86e4e..6c8f492 100644
> --- a/fs/xfs/xfs_trans.c
> +++ b/fs/xfs/xfs_trans.c
> @@ -764,7 +764,7 @@ xfs_trans_free_items(
>  		if (commit_lsn != NULLCOMMITLSN)
>  			lip->li_ops->iop_committing(lip, commit_lsn);
>  		if (abort)
> -			lip->li_flags |= XFS_LI_ABORTED;
> +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
>  		lip->li_ops->iop_unlock(lip);
>  
>  		xfs_trans_free_item_desc(lidp);
> @@ -835,7 +835,7 @@ xfs_trans_committed_bulk(
>  		xfs_lsn_t		item_lsn;
>  
>  		if (aborted)
> -			lip->li_flags |= XFS_LI_ABORTED;
> +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
>  		item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
>  
>  		/* item_lsn of -1 means the item needs no further processing */
> diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> index a07acbf..7ae04de 100644
> --- a/fs/xfs/xfs_trans.h
> +++ b/fs/xfs/xfs_trans.h
> @@ -48,7 +48,7 @@ typedef struct xfs_log_item {
>  	struct xfs_mount		*li_mountp;	/* ptr to fs mount */
>  	struct xfs_ail			*li_ailp;	/* ptr to AIL */
>  	uint				li_type;	/* item type */
> -	uint				li_flags;	/* misc flags */
> +	unsigned long			li_flags;	/* misc flags */
>  	struct xfs_log_item		*li_bio_list;	/* buffer item list */
>  	void				(*li_cb)(struct xfs_buf *,
>  						 struct xfs_log_item *);
> diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> index 9056c0f..76e0de7 100644
> --- a/fs/xfs/xfs_trans_ail.c
> +++ b/fs/xfs/xfs_trans_ail.c
> @@ -45,7 +45,7 @@ xfs_ail_check(
>  	/*
>  	 * Check the next and previous entries are valid.
>  	 */
> -	ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
> +	ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
>  	prev_lip = list_entry(lip->li_ail.prev, xfs_log_item_t, li_ail);
>  	if (&prev_lip->li_ail != &ailp->xa_ail)
>  		ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
> @@ -653,7 +653,7 @@ xfs_trans_ail_update_bulk(
>  
>  	for (i = 0; i < nr_items; i++) {
>  		struct xfs_log_item *lip = log_items[i];
> -		if (lip->li_flags & XFS_LI_IN_AIL) {
> +		if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
>  			/* check if we really need to move the item */
>  			if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0)
>  				continue;
> @@ -663,7 +663,7 @@ xfs_trans_ail_update_bulk(
>  			if (mlip == lip)
>  				mlip_changed = 1;
>  		} else {
> -			lip->li_flags |= XFS_LI_IN_AIL;
> +			set_bit(XFS_LI_IN_AIL, &lip->li_flags);
>  			trace_xfs_ail_insert(lip, 0, lsn);
>  		}
>  		lip->li_lsn = lsn;
> @@ -687,13 +687,13 @@ xfs_trans_ail_update_bulk(
>  bool
>  xfs_ail_delete_one(
>  	struct xfs_ail		*ailp,
> -	struct xfs_log_item 	*lip)
> +	struct xfs_log_item	*lip)
>  {
>  	struct xfs_log_item	*mlip = xfs_ail_min(ailp);
>  
>  	trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
>  	xfs_ail_delete(ailp, lip);
> -	lip->li_flags &= ~XFS_LI_IN_AIL;
> +	clear_bit(XFS_LI_IN_AIL, &lip->li_flags);
>  	lip->li_lsn = 0;
>  
>  	return mlip == lip;
> @@ -729,7 +729,7 @@ xfs_trans_ail_delete(
>  	struct xfs_mount	*mp = ailp->xa_mount;
>  	bool			mlip_changed;
>  
> -	if (!(lip->li_flags & XFS_LI_IN_AIL)) {
> +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
>  		spin_unlock(&ailp->xa_lock);
>  		if (!XFS_FORCED_SHUTDOWN(mp)) {
>  			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
> diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
> index 8ee29ca..15814b5 100644
> --- a/fs/xfs/xfs_trans_buf.c
> +++ b/fs/xfs/xfs_trans_buf.c
> @@ -433,7 +433,7 @@ xfs_trans_brelse(xfs_trans_t	*tp,
>  		ASSERT(bp->b_pincount == 0);
>  ***/
>  		ASSERT(atomic_read(&bip->bli_refcount) == 0);
> -		ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
>  		ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
>  		xfs_buf_item_relse(bp);
>  	}
> diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
> index d91706c..82ea000 100644
> --- a/fs/xfs/xfs_trans_priv.h
> +++ b/fs/xfs/xfs_trans_priv.h
> @@ -119,7 +119,7 @@ xfs_trans_ail_remove(
>  
>  	spin_lock(&ailp->xa_lock);
>  	/* xfs_trans_ail_delete() drops the AIL lock */
> -	if (lip->li_flags & XFS_LI_IN_AIL)
> +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
>  		xfs_trans_ail_delete(ailp, lip, shutdown_type);
>  	else
>  		spin_unlock(&ailp->xa_lock);
> -- 
> 2.9.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Carlos Maiolino June 5, 2017, 12:54 p.m. UTC | #5
On Wed, May 24, 2017 at 01:06:41PM -0400, Brian Foster wrote:
> On Mon, May 22, 2017 at 05:32:18PM +0200, Carlos Maiolino wrote:
> > In order to fix a bug during buffer retries, a new flag type will be
> > added to xfs_log_item, and such operations need to be atomic.
> > 
> > Change all operations in xfs_log_item flags to atomic operations
> > 
> > To use atomic operations, xfs_log_item->li_flags also needed to be
> > converted to unsigned long type.
> > 
> > There is a small whitespace cleanup in the patch too
> > 
> > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> > ---
> 
> As noted in the v1 discussion, I don't think this needs to be a
> dependency of the bug fix patch. Provided we can alleviate Dave's
> concerns over performance and not add any ->xa_lock acquisitions that
> aren't triggered by I/O errors, can we fix the bug using ->xa_lock and
> then port this on top? That way we have more of a backportable fix for
> older kernels affected by this problem.
> 

Hmm, I'm doing some tests with ->xa_lock, and I am actually deadlocking the
system when I try to acquire it in xfs_inode_item_push(), I wonder if ->xa_lock
is really correct to be used here, or maybe I'm doing something wrong? Still
checking what's going on though.

> (Please see my comments on patches 2 and 3 wrt proposed changes to avoid
> the custom callback and need for atomic flags..)
> 
> Brian
> 
> >  fs/xfs/xfs_bmap_item.c     |  4 ++--
> >  fs/xfs/xfs_buf_item.c      |  4 ++--
> >  fs/xfs/xfs_dquot.c         |  2 +-
> >  fs/xfs/xfs_extfree_item.c  |  4 ++--
> >  fs/xfs/xfs_icache.c        |  2 +-
> >  fs/xfs/xfs_icreate_item.c  |  2 +-
> >  fs/xfs/xfs_inode.c         |  4 ++--
> >  fs/xfs/xfs_inode_item.c    |  2 +-
> >  fs/xfs/xfs_qm.c            |  2 +-
> >  fs/xfs/xfs_refcount_item.c |  4 ++--
> >  fs/xfs/xfs_rmap_item.c     |  4 ++--
> >  fs/xfs/xfs_trace.h         |  4 ++--
> >  fs/xfs/xfs_trans.c         |  4 ++--
> >  fs/xfs/xfs_trans.h         |  2 +-
> >  fs/xfs/xfs_trans_ail.c     | 12 ++++++------
> >  fs/xfs/xfs_trans_buf.c     |  2 +-
> >  fs/xfs/xfs_trans_priv.h    |  2 +-
> >  17 files changed, 30 insertions(+), 30 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
> > index d419d23..9ebdca9 100644
> > --- a/fs/xfs/xfs_bmap_item.c
> > +++ b/fs/xfs/xfs_bmap_item.c
> > @@ -141,7 +141,7 @@ STATIC void
> >  xfs_bui_item_unlock(
> >  	struct xfs_log_item	*lip)
> >  {
> > -	if (lip->li_flags & XFS_LI_ABORTED)
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> >  		xfs_bui_item_free(BUI_ITEM(lip));
> >  }
> >  
> > @@ -304,7 +304,7 @@ xfs_bud_item_unlock(
> >  {
> >  	struct xfs_bud_log_item	*budp = BUD_ITEM(lip);
> >  
> > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> >  		xfs_bui_release(budp->bud_buip);
> >  		kmem_zone_free(xfs_bud_zone, budp);
> >  	}
> > diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
> > index 0306168..6ac3816 100644
> > --- a/fs/xfs/xfs_buf_item.c
> > +++ b/fs/xfs/xfs_buf_item.c
> > @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
> >  	 * (cancelled) buffers at unpin time, but we'll never go through the
> >  	 * pin/unpin cycle if we abort inside commit.
> >  	 */
> > -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> > +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
> >  	/*
> >  	 * Before possibly freeing the buf item, copy the per-transaction state
> >  	 * so we can reference it safely later after clearing it from the
> > @@ -975,7 +975,7 @@ xfs_buf_item_relse(
> >  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
> >  
> >  	trace_xfs_buf_item_relse(bp, _RET_IP_);
> > -	ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> > +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> >  
> >  	bp->b_fspriv = bip->bli_item.li_bio_list;
> >  	if (bp->b_fspriv == NULL)
> > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > index 9d06cc3..e8f2cbc 100644
> > --- a/fs/xfs/xfs_dquot.c
> > +++ b/fs/xfs/xfs_dquot.c
> > @@ -1003,7 +1003,7 @@ xfs_qm_dqflush_done(
> >  	 * since it's cheaper, and then we recheck while
> >  	 * holding the lock before removing the dquot from the AIL.
> >  	 */
> > -	if ((lip->li_flags & XFS_LI_IN_AIL) &&
> > +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) &&
> >  	    lip->li_lsn == qip->qli_flush_lsn) {
> >  
> >  		/* xfs_trans_ail_delete() drops the AIL lock. */
> > diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> > index 44f8c54..32a519d 100644
> > --- a/fs/xfs/xfs_extfree_item.c
> > +++ b/fs/xfs/xfs_extfree_item.c
> > @@ -150,7 +150,7 @@ STATIC void
> >  xfs_efi_item_unlock(
> >  	struct xfs_log_item	*lip)
> >  {
> > -	if (lip->li_flags & XFS_LI_ABORTED)
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> >  		xfs_efi_item_free(EFI_ITEM(lip));
> >  }
> >  
> > @@ -402,7 +402,7 @@ xfs_efd_item_unlock(
> >  {
> >  	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
> >  
> > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> >  		xfs_efi_release(efdp->efd_efip);
> >  		xfs_efd_item_free(efdp);
> >  	}
> > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> > index f61c84f8..23d750f 100644
> > --- a/fs/xfs/xfs_icache.c
> > +++ b/fs/xfs/xfs_icache.c
> > @@ -107,7 +107,7 @@ xfs_inode_free_callback(
> >  		xfs_idestroy_fork(ip, XFS_COW_FORK);
> >  
> >  	if (ip->i_itemp) {
> > -		ASSERT(!(ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL));
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
> >  		xfs_inode_item_destroy(ip);
> >  		ip->i_itemp = NULL;
> >  	}
> > diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
> > index 865ad13..e24cf83 100644
> > --- a/fs/xfs/xfs_icreate_item.c
> > +++ b/fs/xfs/xfs_icreate_item.c
> > @@ -91,7 +91,7 @@ xfs_icreate_item_unlock(
> >  {
> >  	struct xfs_icreate_item	*icp = ICR_ITEM(lip);
> >  
> > -	if (icp->ic_item.li_flags & XFS_LI_ABORTED)
> > +	if (test_bit(XFS_LI_ABORTED, &icp->ic_item.li_flags))
> >  		kmem_zone_free(xfs_icreate_zone, icp);
> >  	return;
> >  }
> > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> > index ec9826c..208c8c7 100644
> > --- a/fs/xfs/xfs_inode.c
> > +++ b/fs/xfs/xfs_inode.c
> > @@ -504,7 +504,7 @@ xfs_lock_inodes(
> >  		if (!try_lock) {
> >  			for (j = (i - 1); j >= 0 && !try_lock; j--) {
> >  				lp = (xfs_log_item_t *)ips[j]->i_itemp;
> > -				if (lp && (lp->li_flags & XFS_LI_IN_AIL))
> > +				if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags))
> >  					try_lock++;
> >  			}
> >  		}
> > @@ -601,7 +601,7 @@ xfs_lock_two_inodes(
> >  	 * and try again.
> >  	 */
> >  	lp = (xfs_log_item_t *)ip0->i_itemp;
> > -	if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
> > +	if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags)) {
> >  		if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
> >  			xfs_iunlock(ip0, lock_mode);
> >  			if ((++attempts % 5) == 0)
> > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> > index 08cb7d1..eeeadbb 100644
> > --- a/fs/xfs/xfs_inode_item.c
> > +++ b/fs/xfs/xfs_inode_item.c
> > @@ -783,7 +783,7 @@ xfs_iflush_abort(
> >  	xfs_inode_log_item_t	*iip = ip->i_itemp;
> >  
> >  	if (iip) {
> > -		if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
> > +		if (test_bit(XFS_LI_IN_AIL, &iip->ili_item.li_flags)) {
> >  			xfs_trans_ail_remove(&iip->ili_item,
> >  					     stale ? SHUTDOWN_LOG_IO_ERROR :
> >  						     SHUTDOWN_CORRUPT_INCORE);
> > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> > index 5fe6e70..da58263 100644
> > --- a/fs/xfs/xfs_qm.c
> > +++ b/fs/xfs/xfs_qm.c
> > @@ -169,7 +169,7 @@ xfs_qm_dqpurge(
> >  
> >  	ASSERT(atomic_read(&dqp->q_pincount) == 0);
> >  	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
> > -	       !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
> > +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
> >  
> >  	xfs_dqfunlock(dqp);
> >  	xfs_dqunlock(dqp);
> > diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
> > index 96fe209..5ecfd04 100644
> > --- a/fs/xfs/xfs_refcount_item.c
> > +++ b/fs/xfs/xfs_refcount_item.c
> > @@ -139,7 +139,7 @@ STATIC void
> >  xfs_cui_item_unlock(
> >  	struct xfs_log_item	*lip)
> >  {
> > -	if (lip->li_flags & XFS_LI_ABORTED)
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> >  		xfs_cui_item_free(CUI_ITEM(lip));
> >  }
> >  
> > @@ -308,7 +308,7 @@ xfs_cud_item_unlock(
> >  {
> >  	struct xfs_cud_log_item	*cudp = CUD_ITEM(lip);
> >  
> > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> >  		xfs_cui_release(cudp->cud_cuip);
> >  		kmem_zone_free(xfs_cud_zone, cudp);
> >  	}
> > diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
> > index f3b139c..ada5ec7 100644
> > --- a/fs/xfs/xfs_rmap_item.c
> > +++ b/fs/xfs/xfs_rmap_item.c
> > @@ -139,7 +139,7 @@ STATIC void
> >  xfs_rui_item_unlock(
> >  	struct xfs_log_item	*lip)
> >  {
> > -	if (lip->li_flags & XFS_LI_ABORTED)
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> >  		xfs_rui_item_free(RUI_ITEM(lip));
> >  }
> >  
> > @@ -330,7 +330,7 @@ xfs_rud_item_unlock(
> >  {
> >  	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);
> >  
> > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> >  		xfs_rui_release(rudp->rud_ruip);
> >  		kmem_zone_free(xfs_rud_zone, rudp);
> >  	}
> > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> > index 7c5a165..d09e539 100644
> > --- a/fs/xfs/xfs_trace.h
> > +++ b/fs/xfs/xfs_trace.h
> > @@ -1031,7 +1031,7 @@ DECLARE_EVENT_CLASS(xfs_log_item_class,
> >  		__field(dev_t, dev)
> >  		__field(void *, lip)
> >  		__field(uint, type)
> > -		__field(uint, flags)
> > +		__field(unsigned long, flags)
> >  		__field(xfs_lsn_t, lsn)
> >  	),
> >  	TP_fast_assign(
> > @@ -1083,7 +1083,7 @@ DECLARE_EVENT_CLASS(xfs_ail_class,
> >  		__field(dev_t, dev)
> >  		__field(void *, lip)
> >  		__field(uint, type)
> > -		__field(uint, flags)
> > +		__field(unsigned long, flags)
> >  		__field(xfs_lsn_t, old_lsn)
> >  		__field(xfs_lsn_t, new_lsn)
> >  	),
> > diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
> > index be86e4e..6c8f492 100644
> > --- a/fs/xfs/xfs_trans.c
> > +++ b/fs/xfs/xfs_trans.c
> > @@ -764,7 +764,7 @@ xfs_trans_free_items(
> >  		if (commit_lsn != NULLCOMMITLSN)
> >  			lip->li_ops->iop_committing(lip, commit_lsn);
> >  		if (abort)
> > -			lip->li_flags |= XFS_LI_ABORTED;
> > +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
> >  		lip->li_ops->iop_unlock(lip);
> >  
> >  		xfs_trans_free_item_desc(lidp);
> > @@ -835,7 +835,7 @@ xfs_trans_committed_bulk(
> >  		xfs_lsn_t		item_lsn;
> >  
> >  		if (aborted)
> > -			lip->li_flags |= XFS_LI_ABORTED;
> > +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
> >  		item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
> >  
> >  		/* item_lsn of -1 means the item needs no further processing */
> > diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> > index a07acbf..7ae04de 100644
> > --- a/fs/xfs/xfs_trans.h
> > +++ b/fs/xfs/xfs_trans.h
> > @@ -48,7 +48,7 @@ typedef struct xfs_log_item {
> >  	struct xfs_mount		*li_mountp;	/* ptr to fs mount */
> >  	struct xfs_ail			*li_ailp;	/* ptr to AIL */
> >  	uint				li_type;	/* item type */
> > -	uint				li_flags;	/* misc flags */
> > +	unsigned long			li_flags;	/* misc flags */
> >  	struct xfs_log_item		*li_bio_list;	/* buffer item list */
> >  	void				(*li_cb)(struct xfs_buf *,
> >  						 struct xfs_log_item *);
> > diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> > index 9056c0f..76e0de7 100644
> > --- a/fs/xfs/xfs_trans_ail.c
> > +++ b/fs/xfs/xfs_trans_ail.c
> > @@ -45,7 +45,7 @@ xfs_ail_check(
> >  	/*
> >  	 * Check the next and previous entries are valid.
> >  	 */
> > -	ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
> > +	ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
> >  	prev_lip = list_entry(lip->li_ail.prev, xfs_log_item_t, li_ail);
> >  	if (&prev_lip->li_ail != &ailp->xa_ail)
> >  		ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
> > @@ -653,7 +653,7 @@ xfs_trans_ail_update_bulk(
> >  
> >  	for (i = 0; i < nr_items; i++) {
> >  		struct xfs_log_item *lip = log_items[i];
> > -		if (lip->li_flags & XFS_LI_IN_AIL) {
> > +		if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
> >  			/* check if we really need to move the item */
> >  			if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0)
> >  				continue;
> > @@ -663,7 +663,7 @@ xfs_trans_ail_update_bulk(
> >  			if (mlip == lip)
> >  				mlip_changed = 1;
> >  		} else {
> > -			lip->li_flags |= XFS_LI_IN_AIL;
> > +			set_bit(XFS_LI_IN_AIL, &lip->li_flags);
> >  			trace_xfs_ail_insert(lip, 0, lsn);
> >  		}
> >  		lip->li_lsn = lsn;
> > @@ -687,13 +687,13 @@ xfs_trans_ail_update_bulk(
> >  bool
> >  xfs_ail_delete_one(
> >  	struct xfs_ail		*ailp,
> > -	struct xfs_log_item 	*lip)
> > +	struct xfs_log_item	*lip)
> >  {
> >  	struct xfs_log_item	*mlip = xfs_ail_min(ailp);
> >  
> >  	trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
> >  	xfs_ail_delete(ailp, lip);
> > -	lip->li_flags &= ~XFS_LI_IN_AIL;
> > +	clear_bit(XFS_LI_IN_AIL, &lip->li_flags);
> >  	lip->li_lsn = 0;
> >  
> >  	return mlip == lip;
> > @@ -729,7 +729,7 @@ xfs_trans_ail_delete(
> >  	struct xfs_mount	*mp = ailp->xa_mount;
> >  	bool			mlip_changed;
> >  
> > -	if (!(lip->li_flags & XFS_LI_IN_AIL)) {
> > +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
> >  		spin_unlock(&ailp->xa_lock);
> >  		if (!XFS_FORCED_SHUTDOWN(mp)) {
> >  			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
> > diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
> > index 8ee29ca..15814b5 100644
> > --- a/fs/xfs/xfs_trans_buf.c
> > +++ b/fs/xfs/xfs_trans_buf.c
> > @@ -433,7 +433,7 @@ xfs_trans_brelse(xfs_trans_t	*tp,
> >  		ASSERT(bp->b_pincount == 0);
> >  ***/
> >  		ASSERT(atomic_read(&bip->bli_refcount) == 0);
> > -		ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> >  		ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
> >  		xfs_buf_item_relse(bp);
> >  	}
> > diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
> > index d91706c..82ea000 100644
> > --- a/fs/xfs/xfs_trans_priv.h
> > +++ b/fs/xfs/xfs_trans_priv.h
> > @@ -119,7 +119,7 @@ xfs_trans_ail_remove(
> >  
> >  	spin_lock(&ailp->xa_lock);
> >  	/* xfs_trans_ail_delete() drops the AIL lock */
> > -	if (lip->li_flags & XFS_LI_IN_AIL)
> > +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
> >  		xfs_trans_ail_delete(ailp, lip, shutdown_type);
> >  	else
> >  		spin_unlock(&ailp->xa_lock);
> > -- 
> > 2.9.3
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
Carlos Maiolino June 5, 2017, 1:13 p.m. UTC | #6
On Mon, Jun 05, 2017 at 02:54:33PM +0200, Carlos Maiolino wrote:
> On Wed, May 24, 2017 at 01:06:41PM -0400, Brian Foster wrote:
> > On Mon, May 22, 2017 at 05:32:18PM +0200, Carlos Maiolino wrote:
> > > In order to fix a bug during buffer retries, a new flag type will be
> > > added to xfs_log_item, and such operations need to be atomic.
> > > 
> > > Change all operations in xfs_log_item flags to atomic operations
> > > 
> > > To use atomic operations, xfs_log_item->li_flags also needed to be
> > > converted to unsigned long type.
> > > 
> > > There is a small whitespace cleanup in the patch too
> > > 
> > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
> > > ---
> > 
> > As noted in the v1 discussion, I don't think this needs to be a
> > dependency of the bug fix patch. Provided we can alleviate Dave's
> > concerns over performance and not add any ->xa_lock acquisitions that
> > aren't triggered by I/O errors, can we fix the bug using ->xa_lock and
> > then port this on top? That way we have more of a backportable fix for
> > older kernels affected by this problem.
> > 
> 
> Hmm, I'm doing some tests with ->xa_lock, and I am actually deadlocking the
> system when I try to acquire it in xfs_inode_item_push(), I wonder if ->xa_lock
> is really correct to be used here, or maybe I'm doing something wrong? Still
> checking what's going on though.
> 

My bad actually, I didn't realize xa_lock was already acquired when
re-submitting a failed buffer, at least for resubmission, it's already protected

> > (Please see my comments on patches 2 and 3 wrt proposed changes to avoid
> > the custom callback and need for atomic flags..)
> > 
> > Brian
> > 
> > >  fs/xfs/xfs_bmap_item.c     |  4 ++--
> > >  fs/xfs/xfs_buf_item.c      |  4 ++--
> > >  fs/xfs/xfs_dquot.c         |  2 +-
> > >  fs/xfs/xfs_extfree_item.c  |  4 ++--
> > >  fs/xfs/xfs_icache.c        |  2 +-
> > >  fs/xfs/xfs_icreate_item.c  |  2 +-
> > >  fs/xfs/xfs_inode.c         |  4 ++--
> > >  fs/xfs/xfs_inode_item.c    |  2 +-
> > >  fs/xfs/xfs_qm.c            |  2 +-
> > >  fs/xfs/xfs_refcount_item.c |  4 ++--
> > >  fs/xfs/xfs_rmap_item.c     |  4 ++--
> > >  fs/xfs/xfs_trace.h         |  4 ++--
> > >  fs/xfs/xfs_trans.c         |  4 ++--
> > >  fs/xfs/xfs_trans.h         |  2 +-
> > >  fs/xfs/xfs_trans_ail.c     | 12 ++++++------
> > >  fs/xfs/xfs_trans_buf.c     |  2 +-
> > >  fs/xfs/xfs_trans_priv.h    |  2 +-
> > >  17 files changed, 30 insertions(+), 30 deletions(-)
> > > 
> > > diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
> > > index d419d23..9ebdca9 100644
> > > --- a/fs/xfs/xfs_bmap_item.c
> > > +++ b/fs/xfs/xfs_bmap_item.c
> > > @@ -141,7 +141,7 @@ STATIC void
> > >  xfs_bui_item_unlock(
> > >  	struct xfs_log_item	*lip)
> > >  {
> > > -	if (lip->li_flags & XFS_LI_ABORTED)
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> > >  		xfs_bui_item_free(BUI_ITEM(lip));
> > >  }
> > >  
> > > @@ -304,7 +304,7 @@ xfs_bud_item_unlock(
> > >  {
> > >  	struct xfs_bud_log_item	*budp = BUD_ITEM(lip);
> > >  
> > > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> > >  		xfs_bui_release(budp->bud_buip);
> > >  		kmem_zone_free(xfs_bud_zone, budp);
> > >  	}
> > > diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
> > > index 0306168..6ac3816 100644
> > > --- a/fs/xfs/xfs_buf_item.c
> > > +++ b/fs/xfs/xfs_buf_item.c
> > > @@ -587,7 +587,7 @@ xfs_buf_item_unlock(
> > >  	 * (cancelled) buffers at unpin time, but we'll never go through the
> > >  	 * pin/unpin cycle if we abort inside commit.
> > >  	 */
> > > -	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
> > > +	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
> > >  	/*
> > >  	 * Before possibly freeing the buf item, copy the per-transaction state
> > >  	 * so we can reference it safely later after clearing it from the
> > > @@ -975,7 +975,7 @@ xfs_buf_item_relse(
> > >  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
> > >  
> > >  	trace_xfs_buf_item_relse(bp, _RET_IP_);
> > > -	ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> > > +	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> > >  
> > >  	bp->b_fspriv = bip->bli_item.li_bio_list;
> > >  	if (bp->b_fspriv == NULL)
> > > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> > > index 9d06cc3..e8f2cbc 100644
> > > --- a/fs/xfs/xfs_dquot.c
> > > +++ b/fs/xfs/xfs_dquot.c
> > > @@ -1003,7 +1003,7 @@ xfs_qm_dqflush_done(
> > >  	 * since it's cheaper, and then we recheck while
> > >  	 * holding the lock before removing the dquot from the AIL.
> > >  	 */
> > > -	if ((lip->li_flags & XFS_LI_IN_AIL) &&
> > > +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) &&
> > >  	    lip->li_lsn == qip->qli_flush_lsn) {
> > >  
> > >  		/* xfs_trans_ail_delete() drops the AIL lock. */
> > > diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
> > > index 44f8c54..32a519d 100644
> > > --- a/fs/xfs/xfs_extfree_item.c
> > > +++ b/fs/xfs/xfs_extfree_item.c
> > > @@ -150,7 +150,7 @@ STATIC void
> > >  xfs_efi_item_unlock(
> > >  	struct xfs_log_item	*lip)
> > >  {
> > > -	if (lip->li_flags & XFS_LI_ABORTED)
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> > >  		xfs_efi_item_free(EFI_ITEM(lip));
> > >  }
> > >  
> > > @@ -402,7 +402,7 @@ xfs_efd_item_unlock(
> > >  {
> > >  	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
> > >  
> > > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> > >  		xfs_efi_release(efdp->efd_efip);
> > >  		xfs_efd_item_free(efdp);
> > >  	}
> > > diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> > > index f61c84f8..23d750f 100644
> > > --- a/fs/xfs/xfs_icache.c
> > > +++ b/fs/xfs/xfs_icache.c
> > > @@ -107,7 +107,7 @@ xfs_inode_free_callback(
> > >  		xfs_idestroy_fork(ip, XFS_COW_FORK);
> > >  
> > >  	if (ip->i_itemp) {
> > > -		ASSERT(!(ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL));
> > > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
> > >  		xfs_inode_item_destroy(ip);
> > >  		ip->i_itemp = NULL;
> > >  	}
> > > diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
> > > index 865ad13..e24cf83 100644
> > > --- a/fs/xfs/xfs_icreate_item.c
> > > +++ b/fs/xfs/xfs_icreate_item.c
> > > @@ -91,7 +91,7 @@ xfs_icreate_item_unlock(
> > >  {
> > >  	struct xfs_icreate_item	*icp = ICR_ITEM(lip);
> > >  
> > > -	if (icp->ic_item.li_flags & XFS_LI_ABORTED)
> > > +	if (test_bit(XFS_LI_ABORTED, &icp->ic_item.li_flags))
> > >  		kmem_zone_free(xfs_icreate_zone, icp);
> > >  	return;
> > >  }
> > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> > > index ec9826c..208c8c7 100644
> > > --- a/fs/xfs/xfs_inode.c
> > > +++ b/fs/xfs/xfs_inode.c
> > > @@ -504,7 +504,7 @@ xfs_lock_inodes(
> > >  		if (!try_lock) {
> > >  			for (j = (i - 1); j >= 0 && !try_lock; j--) {
> > >  				lp = (xfs_log_item_t *)ips[j]->i_itemp;
> > > -				if (lp && (lp->li_flags & XFS_LI_IN_AIL))
> > > +				if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags))
> > >  					try_lock++;
> > >  			}
> > >  		}
> > > @@ -601,7 +601,7 @@ xfs_lock_two_inodes(
> > >  	 * and try again.
> > >  	 */
> > >  	lp = (xfs_log_item_t *)ip0->i_itemp;
> > > -	if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
> > > +	if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags)) {
> > >  		if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
> > >  			xfs_iunlock(ip0, lock_mode);
> > >  			if ((++attempts % 5) == 0)
> > > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> > > index 08cb7d1..eeeadbb 100644
> > > --- a/fs/xfs/xfs_inode_item.c
> > > +++ b/fs/xfs/xfs_inode_item.c
> > > @@ -783,7 +783,7 @@ xfs_iflush_abort(
> > >  	xfs_inode_log_item_t	*iip = ip->i_itemp;
> > >  
> > >  	if (iip) {
> > > -		if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
> > > +		if (test_bit(XFS_LI_IN_AIL, &iip->ili_item.li_flags)) {
> > >  			xfs_trans_ail_remove(&iip->ili_item,
> > >  					     stale ? SHUTDOWN_LOG_IO_ERROR :
> > >  						     SHUTDOWN_CORRUPT_INCORE);
> > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> > > index 5fe6e70..da58263 100644
> > > --- a/fs/xfs/xfs_qm.c
> > > +++ b/fs/xfs/xfs_qm.c
> > > @@ -169,7 +169,7 @@ xfs_qm_dqpurge(
> > >  
> > >  	ASSERT(atomic_read(&dqp->q_pincount) == 0);
> > >  	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
> > > -	       !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
> > > +	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
> > >  
> > >  	xfs_dqfunlock(dqp);
> > >  	xfs_dqunlock(dqp);
> > > diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
> > > index 96fe209..5ecfd04 100644
> > > --- a/fs/xfs/xfs_refcount_item.c
> > > +++ b/fs/xfs/xfs_refcount_item.c
> > > @@ -139,7 +139,7 @@ STATIC void
> > >  xfs_cui_item_unlock(
> > >  	struct xfs_log_item	*lip)
> > >  {
> > > -	if (lip->li_flags & XFS_LI_ABORTED)
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> > >  		xfs_cui_item_free(CUI_ITEM(lip));
> > >  }
> > >  
> > > @@ -308,7 +308,7 @@ xfs_cud_item_unlock(
> > >  {
> > >  	struct xfs_cud_log_item	*cudp = CUD_ITEM(lip);
> > >  
> > > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> > >  		xfs_cui_release(cudp->cud_cuip);
> > >  		kmem_zone_free(xfs_cud_zone, cudp);
> > >  	}
> > > diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
> > > index f3b139c..ada5ec7 100644
> > > --- a/fs/xfs/xfs_rmap_item.c
> > > +++ b/fs/xfs/xfs_rmap_item.c
> > > @@ -139,7 +139,7 @@ STATIC void
> > >  xfs_rui_item_unlock(
> > >  	struct xfs_log_item	*lip)
> > >  {
> > > -	if (lip->li_flags & XFS_LI_ABORTED)
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
> > >  		xfs_rui_item_free(RUI_ITEM(lip));
> > >  }
> > >  
> > > @@ -330,7 +330,7 @@ xfs_rud_item_unlock(
> > >  {
> > >  	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);
> > >  
> > > -	if (lip->li_flags & XFS_LI_ABORTED) {
> > > +	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
> > >  		xfs_rui_release(rudp->rud_ruip);
> > >  		kmem_zone_free(xfs_rud_zone, rudp);
> > >  	}
> > > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> > > index 7c5a165..d09e539 100644
> > > --- a/fs/xfs/xfs_trace.h
> > > +++ b/fs/xfs/xfs_trace.h
> > > @@ -1031,7 +1031,7 @@ DECLARE_EVENT_CLASS(xfs_log_item_class,
> > >  		__field(dev_t, dev)
> > >  		__field(void *, lip)
> > >  		__field(uint, type)
> > > -		__field(uint, flags)
> > > +		__field(unsigned long, flags)
> > >  		__field(xfs_lsn_t, lsn)
> > >  	),
> > >  	TP_fast_assign(
> > > @@ -1083,7 +1083,7 @@ DECLARE_EVENT_CLASS(xfs_ail_class,
> > >  		__field(dev_t, dev)
> > >  		__field(void *, lip)
> > >  		__field(uint, type)
> > > -		__field(uint, flags)
> > > +		__field(unsigned long, flags)
> > >  		__field(xfs_lsn_t, old_lsn)
> > >  		__field(xfs_lsn_t, new_lsn)
> > >  	),
> > > diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
> > > index be86e4e..6c8f492 100644
> > > --- a/fs/xfs/xfs_trans.c
> > > +++ b/fs/xfs/xfs_trans.c
> > > @@ -764,7 +764,7 @@ xfs_trans_free_items(
> > >  		if (commit_lsn != NULLCOMMITLSN)
> > >  			lip->li_ops->iop_committing(lip, commit_lsn);
> > >  		if (abort)
> > > -			lip->li_flags |= XFS_LI_ABORTED;
> > > +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
> > >  		lip->li_ops->iop_unlock(lip);
> > >  
> > >  		xfs_trans_free_item_desc(lidp);
> > > @@ -835,7 +835,7 @@ xfs_trans_committed_bulk(
> > >  		xfs_lsn_t		item_lsn;
> > >  
> > >  		if (aborted)
> > > -			lip->li_flags |= XFS_LI_ABORTED;
> > > +			set_bit(XFS_LI_ABORTED, &lip->li_flags);
> > >  		item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
> > >  
> > >  		/* item_lsn of -1 means the item needs no further processing */
> > > diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> > > index a07acbf..7ae04de 100644
> > > --- a/fs/xfs/xfs_trans.h
> > > +++ b/fs/xfs/xfs_trans.h
> > > @@ -48,7 +48,7 @@ typedef struct xfs_log_item {
> > >  	struct xfs_mount		*li_mountp;	/* ptr to fs mount */
> > >  	struct xfs_ail			*li_ailp;	/* ptr to AIL */
> > >  	uint				li_type;	/* item type */
> > > -	uint				li_flags;	/* misc flags */
> > > +	unsigned long			li_flags;	/* misc flags */
> > >  	struct xfs_log_item		*li_bio_list;	/* buffer item list */
> > >  	void				(*li_cb)(struct xfs_buf *,
> > >  						 struct xfs_log_item *);
> > > diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
> > > index 9056c0f..76e0de7 100644
> > > --- a/fs/xfs/xfs_trans_ail.c
> > > +++ b/fs/xfs/xfs_trans_ail.c
> > > @@ -45,7 +45,7 @@ xfs_ail_check(
> > >  	/*
> > >  	 * Check the next and previous entries are valid.
> > >  	 */
> > > -	ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
> > > +	ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
> > >  	prev_lip = list_entry(lip->li_ail.prev, xfs_log_item_t, li_ail);
> > >  	if (&prev_lip->li_ail != &ailp->xa_ail)
> > >  		ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
> > > @@ -653,7 +653,7 @@ xfs_trans_ail_update_bulk(
> > >  
> > >  	for (i = 0; i < nr_items; i++) {
> > >  		struct xfs_log_item *lip = log_items[i];
> > > -		if (lip->li_flags & XFS_LI_IN_AIL) {
> > > +		if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
> > >  			/* check if we really need to move the item */
> > >  			if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0)
> > >  				continue;
> > > @@ -663,7 +663,7 @@ xfs_trans_ail_update_bulk(
> > >  			if (mlip == lip)
> > >  				mlip_changed = 1;
> > >  		} else {
> > > -			lip->li_flags |= XFS_LI_IN_AIL;
> > > +			set_bit(XFS_LI_IN_AIL, &lip->li_flags);
> > >  			trace_xfs_ail_insert(lip, 0, lsn);
> > >  		}
> > >  		lip->li_lsn = lsn;
> > > @@ -687,13 +687,13 @@ xfs_trans_ail_update_bulk(
> > >  bool
> > >  xfs_ail_delete_one(
> > >  	struct xfs_ail		*ailp,
> > > -	struct xfs_log_item 	*lip)
> > > +	struct xfs_log_item	*lip)
> > >  {
> > >  	struct xfs_log_item	*mlip = xfs_ail_min(ailp);
> > >  
> > >  	trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
> > >  	xfs_ail_delete(ailp, lip);
> > > -	lip->li_flags &= ~XFS_LI_IN_AIL;
> > > +	clear_bit(XFS_LI_IN_AIL, &lip->li_flags);
> > >  	lip->li_lsn = 0;
> > >  
> > >  	return mlip == lip;
> > > @@ -729,7 +729,7 @@ xfs_trans_ail_delete(
> > >  	struct xfs_mount	*mp = ailp->xa_mount;
> > >  	bool			mlip_changed;
> > >  
> > > -	if (!(lip->li_flags & XFS_LI_IN_AIL)) {
> > > +	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
> > >  		spin_unlock(&ailp->xa_lock);
> > >  		if (!XFS_FORCED_SHUTDOWN(mp)) {
> > >  			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
> > > diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
> > > index 8ee29ca..15814b5 100644
> > > --- a/fs/xfs/xfs_trans_buf.c
> > > +++ b/fs/xfs/xfs_trans_buf.c
> > > @@ -433,7 +433,7 @@ xfs_trans_brelse(xfs_trans_t	*tp,
> > >  		ASSERT(bp->b_pincount == 0);
> > >  ***/
> > >  		ASSERT(atomic_read(&bip->bli_refcount) == 0);
> > > -		ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
> > > +		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
> > >  		ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
> > >  		xfs_buf_item_relse(bp);
> > >  	}
> > > diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
> > > index d91706c..82ea000 100644
> > > --- a/fs/xfs/xfs_trans_priv.h
> > > +++ b/fs/xfs/xfs_trans_priv.h
> > > @@ -119,7 +119,7 @@ xfs_trans_ail_remove(
> > >  
> > >  	spin_lock(&ailp->xa_lock);
> > >  	/* xfs_trans_ail_delete() drops the AIL lock */
> > > -	if (lip->li_flags & XFS_LI_IN_AIL)
> > > +	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
> > >  		xfs_trans_ail_delete(ailp, lip, shutdown_type);
> > >  	else
> > >  		spin_unlock(&ailp->xa_lock);
> > > -- 
> > > 2.9.3
> > > 
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> > > the body of a message to majordomo@vger.kernel.org
> > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> -- 
> Carlos
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c
index d419d23..9ebdca9 100644
--- a/fs/xfs/xfs_bmap_item.c
+++ b/fs/xfs/xfs_bmap_item.c
@@ -141,7 +141,7 @@  STATIC void
 xfs_bui_item_unlock(
 	struct xfs_log_item	*lip)
 {
-	if (lip->li_flags & XFS_LI_ABORTED)
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
 		xfs_bui_item_free(BUI_ITEM(lip));
 }
 
@@ -304,7 +304,7 @@  xfs_bud_item_unlock(
 {
 	struct xfs_bud_log_item	*budp = BUD_ITEM(lip);
 
-	if (lip->li_flags & XFS_LI_ABORTED) {
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
 		xfs_bui_release(budp->bud_buip);
 		kmem_zone_free(xfs_bud_zone, budp);
 	}
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 0306168..6ac3816 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -587,7 +587,7 @@  xfs_buf_item_unlock(
 	 * (cancelled) buffers at unpin time, but we'll never go through the
 	 * pin/unpin cycle if we abort inside commit.
 	 */
-	aborted = (lip->li_flags & XFS_LI_ABORTED) ? true : false;
+	aborted = (test_bit(XFS_LI_ABORTED, &lip->li_flags)) ? true : false;
 	/*
 	 * Before possibly freeing the buf item, copy the per-transaction state
 	 * so we can reference it safely later after clearing it from the
@@ -975,7 +975,7 @@  xfs_buf_item_relse(
 	xfs_buf_log_item_t	*bip = bp->b_fspriv;
 
 	trace_xfs_buf_item_relse(bp, _RET_IP_);
-	ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
+	ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
 
 	bp->b_fspriv = bip->bli_item.li_bio_list;
 	if (bp->b_fspriv == NULL)
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 9d06cc3..e8f2cbc 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -1003,7 +1003,7 @@  xfs_qm_dqflush_done(
 	 * since it's cheaper, and then we recheck while
 	 * holding the lock before removing the dquot from the AIL.
 	 */
-	if ((lip->li_flags & XFS_LI_IN_AIL) &&
+	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags) &&
 	    lip->li_lsn == qip->qli_flush_lsn) {
 
 		/* xfs_trans_ail_delete() drops the AIL lock. */
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 44f8c54..32a519d 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -150,7 +150,7 @@  STATIC void
 xfs_efi_item_unlock(
 	struct xfs_log_item	*lip)
 {
-	if (lip->li_flags & XFS_LI_ABORTED)
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
 		xfs_efi_item_free(EFI_ITEM(lip));
 }
 
@@ -402,7 +402,7 @@  xfs_efd_item_unlock(
 {
 	struct xfs_efd_log_item	*efdp = EFD_ITEM(lip);
 
-	if (lip->li_flags & XFS_LI_ABORTED) {
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
 		xfs_efi_release(efdp->efd_efip);
 		xfs_efd_item_free(efdp);
 	}
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index f61c84f8..23d750f 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -107,7 +107,7 @@  xfs_inode_free_callback(
 		xfs_idestroy_fork(ip, XFS_COW_FORK);
 
 	if (ip->i_itemp) {
-		ASSERT(!(ip->i_itemp->ili_item.li_flags & XFS_LI_IN_AIL));
+		ASSERT(!(test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)));
 		xfs_inode_item_destroy(ip);
 		ip->i_itemp = NULL;
 	}
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c
index 865ad13..e24cf83 100644
--- a/fs/xfs/xfs_icreate_item.c
+++ b/fs/xfs/xfs_icreate_item.c
@@ -91,7 +91,7 @@  xfs_icreate_item_unlock(
 {
 	struct xfs_icreate_item	*icp = ICR_ITEM(lip);
 
-	if (icp->ic_item.li_flags & XFS_LI_ABORTED)
+	if (test_bit(XFS_LI_ABORTED, &icp->ic_item.li_flags))
 		kmem_zone_free(xfs_icreate_zone, icp);
 	return;
 }
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index ec9826c..208c8c7 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -504,7 +504,7 @@  xfs_lock_inodes(
 		if (!try_lock) {
 			for (j = (i - 1); j >= 0 && !try_lock; j--) {
 				lp = (xfs_log_item_t *)ips[j]->i_itemp;
-				if (lp && (lp->li_flags & XFS_LI_IN_AIL))
+				if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags))
 					try_lock++;
 			}
 		}
@@ -601,7 +601,7 @@  xfs_lock_two_inodes(
 	 * and try again.
 	 */
 	lp = (xfs_log_item_t *)ip0->i_itemp;
-	if (lp && (lp->li_flags & XFS_LI_IN_AIL)) {
+	if (lp && test_bit(XFS_LI_IN_AIL, &lp->li_flags)) {
 		if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) {
 			xfs_iunlock(ip0, lock_mode);
 			if ((++attempts % 5) == 0)
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 08cb7d1..eeeadbb 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -783,7 +783,7 @@  xfs_iflush_abort(
 	xfs_inode_log_item_t	*iip = ip->i_itemp;
 
 	if (iip) {
-		if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
+		if (test_bit(XFS_LI_IN_AIL, &iip->ili_item.li_flags)) {
 			xfs_trans_ail_remove(&iip->ili_item,
 					     stale ? SHUTDOWN_LOG_IO_ERROR :
 						     SHUTDOWN_CORRUPT_INCORE);
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 5fe6e70..da58263 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -169,7 +169,7 @@  xfs_qm_dqpurge(
 
 	ASSERT(atomic_read(&dqp->q_pincount) == 0);
 	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
-	       !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
+	       !(test_bit(XFS_LI_IN_AIL, &dqp->q_logitem.qli_item.li_flags)));
 
 	xfs_dqfunlock(dqp);
 	xfs_dqunlock(dqp);
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 96fe209..5ecfd04 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -139,7 +139,7 @@  STATIC void
 xfs_cui_item_unlock(
 	struct xfs_log_item	*lip)
 {
-	if (lip->li_flags & XFS_LI_ABORTED)
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
 		xfs_cui_item_free(CUI_ITEM(lip));
 }
 
@@ -308,7 +308,7 @@  xfs_cud_item_unlock(
 {
 	struct xfs_cud_log_item	*cudp = CUD_ITEM(lip);
 
-	if (lip->li_flags & XFS_LI_ABORTED) {
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
 		xfs_cui_release(cudp->cud_cuip);
 		kmem_zone_free(xfs_cud_zone, cudp);
 	}
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index f3b139c..ada5ec7 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -139,7 +139,7 @@  STATIC void
 xfs_rui_item_unlock(
 	struct xfs_log_item	*lip)
 {
-	if (lip->li_flags & XFS_LI_ABORTED)
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags))
 		xfs_rui_item_free(RUI_ITEM(lip));
 }
 
@@ -330,7 +330,7 @@  xfs_rud_item_unlock(
 {
 	struct xfs_rud_log_item	*rudp = RUD_ITEM(lip);
 
-	if (lip->li_flags & XFS_LI_ABORTED) {
+	if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) {
 		xfs_rui_release(rudp->rud_ruip);
 		kmem_zone_free(xfs_rud_zone, rudp);
 	}
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 7c5a165..d09e539 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -1031,7 +1031,7 @@  DECLARE_EVENT_CLASS(xfs_log_item_class,
 		__field(dev_t, dev)
 		__field(void *, lip)
 		__field(uint, type)
-		__field(uint, flags)
+		__field(unsigned long, flags)
 		__field(xfs_lsn_t, lsn)
 	),
 	TP_fast_assign(
@@ -1083,7 +1083,7 @@  DECLARE_EVENT_CLASS(xfs_ail_class,
 		__field(dev_t, dev)
 		__field(void *, lip)
 		__field(uint, type)
-		__field(uint, flags)
+		__field(unsigned long, flags)
 		__field(xfs_lsn_t, old_lsn)
 		__field(xfs_lsn_t, new_lsn)
 	),
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index be86e4e..6c8f492 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -764,7 +764,7 @@  xfs_trans_free_items(
 		if (commit_lsn != NULLCOMMITLSN)
 			lip->li_ops->iop_committing(lip, commit_lsn);
 		if (abort)
-			lip->li_flags |= XFS_LI_ABORTED;
+			set_bit(XFS_LI_ABORTED, &lip->li_flags);
 		lip->li_ops->iop_unlock(lip);
 
 		xfs_trans_free_item_desc(lidp);
@@ -835,7 +835,7 @@  xfs_trans_committed_bulk(
 		xfs_lsn_t		item_lsn;
 
 		if (aborted)
-			lip->li_flags |= XFS_LI_ABORTED;
+			set_bit(XFS_LI_ABORTED, &lip->li_flags);
 		item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
 
 		/* item_lsn of -1 means the item needs no further processing */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index a07acbf..7ae04de 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -48,7 +48,7 @@  typedef struct xfs_log_item {
 	struct xfs_mount		*li_mountp;	/* ptr to fs mount */
 	struct xfs_ail			*li_ailp;	/* ptr to AIL */
 	uint				li_type;	/* item type */
-	uint				li_flags;	/* misc flags */
+	unsigned long			li_flags;	/* misc flags */
 	struct xfs_log_item		*li_bio_list;	/* buffer item list */
 	void				(*li_cb)(struct xfs_buf *,
 						 struct xfs_log_item *);
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 9056c0f..76e0de7 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -45,7 +45,7 @@  xfs_ail_check(
 	/*
 	 * Check the next and previous entries are valid.
 	 */
-	ASSERT((lip->li_flags & XFS_LI_IN_AIL) != 0);
+	ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags));
 	prev_lip = list_entry(lip->li_ail.prev, xfs_log_item_t, li_ail);
 	if (&prev_lip->li_ail != &ailp->xa_ail)
 		ASSERT(XFS_LSN_CMP(prev_lip->li_lsn, lip->li_lsn) <= 0);
@@ -653,7 +653,7 @@  xfs_trans_ail_update_bulk(
 
 	for (i = 0; i < nr_items; i++) {
 		struct xfs_log_item *lip = log_items[i];
-		if (lip->li_flags & XFS_LI_IN_AIL) {
+		if (test_bit(XFS_LI_IN_AIL, &lip->li_flags)) {
 			/* check if we really need to move the item */
 			if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0)
 				continue;
@@ -663,7 +663,7 @@  xfs_trans_ail_update_bulk(
 			if (mlip == lip)
 				mlip_changed = 1;
 		} else {
-			lip->li_flags |= XFS_LI_IN_AIL;
+			set_bit(XFS_LI_IN_AIL, &lip->li_flags);
 			trace_xfs_ail_insert(lip, 0, lsn);
 		}
 		lip->li_lsn = lsn;
@@ -687,13 +687,13 @@  xfs_trans_ail_update_bulk(
 bool
 xfs_ail_delete_one(
 	struct xfs_ail		*ailp,
-	struct xfs_log_item 	*lip)
+	struct xfs_log_item	*lip)
 {
 	struct xfs_log_item	*mlip = xfs_ail_min(ailp);
 
 	trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn);
 	xfs_ail_delete(ailp, lip);
-	lip->li_flags &= ~XFS_LI_IN_AIL;
+	clear_bit(XFS_LI_IN_AIL, &lip->li_flags);
 	lip->li_lsn = 0;
 
 	return mlip == lip;
@@ -729,7 +729,7 @@  xfs_trans_ail_delete(
 	struct xfs_mount	*mp = ailp->xa_mount;
 	bool			mlip_changed;
 
-	if (!(lip->li_flags & XFS_LI_IN_AIL)) {
+	if (!(test_bit(XFS_LI_IN_AIL, &lip->li_flags))) {
 		spin_unlock(&ailp->xa_lock);
 		if (!XFS_FORCED_SHUTDOWN(mp)) {
 			xfs_alert_tag(mp, XFS_PTAG_AILDELETE,
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 8ee29ca..15814b5 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -433,7 +433,7 @@  xfs_trans_brelse(xfs_trans_t	*tp,
 		ASSERT(bp->b_pincount == 0);
 ***/
 		ASSERT(atomic_read(&bip->bli_refcount) == 0);
-		ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
+		ASSERT(!(test_bit(XFS_LI_IN_AIL, &bip->bli_item.li_flags)));
 		ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
 		xfs_buf_item_relse(bp);
 	}
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index d91706c..82ea000 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -119,7 +119,7 @@  xfs_trans_ail_remove(
 
 	spin_lock(&ailp->xa_lock);
 	/* xfs_trans_ail_delete() drops the AIL lock */
-	if (lip->li_flags & XFS_LI_IN_AIL)
+	if (test_bit(XFS_LI_IN_AIL, &lip->li_flags))
 		xfs_trans_ail_delete(ailp, lip, shutdown_type);
 	else
 		spin_unlock(&ailp->xa_lock);