public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Brian Foster <bfoster@redhat.com>
To: Dave Chinner <david@fromorbit.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 5/9] xfs: xfs_bioerror can die.
Date: Fri, 15 Aug 2014 10:35:41 -0400	[thread overview]
Message-ID: <20140815143540.GD4096@laptop.bfoster> (raw)
In-Reply-To: <1408084747-4540-6-git-send-email-david@fromorbit.com>

On Fri, Aug 15, 2014 at 04:39:03PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> Internal buffer write error handling is a mess due to the unnatural
> split between xfs_bioerror and xfs_bioerror_relse(). The buffer
> reference counting is also wrong for the xfs_bioerror path for
> xfs_bwrite - it uses sync IO and so xfs_buf_ioend will release a
> hold count that was never taken.
> 
> Further, xfs_bwrite only does sync IO and determines the handler to
> call based on b_iodone, so for this caller the only difference
> between xfs_bioerror() and xfs_bioerror_release() is the XBF_DONE
> flag. We don't care what the XBF_DONE flag state is because we stale
> the buffer in both paths - the next buffer lookup will clear
> XBF_DONE anyway because XBF_STALE is set. Hence we can use common
> error handling for xfs_bwrite().
> 
> __xfs_buf_delwri_submit() is a similar - it's only ever called
> on writes - all sync or async - and again there's no reason to
> handle them any differently at all.
> 
> Clean up the nasty error handling and remove xfs_bioerror().
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/xfs_buf.c | 67 +++++++++++++++++---------------------------------------
>  1 file changed, 20 insertions(+), 47 deletions(-)
> 
> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
> index 98fcf5a..f444285 100644
> --- a/fs/xfs/xfs_buf.c
> +++ b/fs/xfs/xfs_buf.c
> @@ -1072,36 +1072,6 @@ xfs_buf_ioerror_alert(
>  }
>  
>  /*
> - * Called when we want to stop a buffer from getting written or read.
> - * We attach the EIO error, muck with its flags, and call xfs_buf_ioend
> - * so that the proper iodone callbacks get called.
> - */
> -STATIC int
> -xfs_bioerror(
> -	xfs_buf_t *bp)
> -{
> -#ifdef XFSERRORDEBUG
> -	ASSERT(XFS_BUF_ISREAD(bp) || bp->b_iodone);
> -#endif
> -
> -	/*
> -	 * No need to wait until the buffer is unpinned, we aren't flushing it.
> -	 */
> -	xfs_buf_ioerror(bp, -EIO);
> -
> -	/*
> -	 * We're calling xfs_buf_ioend, so delete XBF_DONE flag.
> -	 */
> -	XFS_BUF_UNREAD(bp);
> -	XFS_BUF_UNDONE(bp);
> -	xfs_buf_stale(bp);
> -
> -	xfs_buf_ioend(bp);
> -
> -	return -EIO;
> -}
> -
> -/*
>   * Same as xfs_bioerror, except that we are releasing the buffer
>   * here ourselves, and avoiding the xfs_buf_ioend call.
>   * This is meant for userdata errors; metadata bufs come with
> @@ -1149,19 +1119,19 @@ xfs_bwrite(
>  	ASSERT(xfs_buf_islocked(bp));
>  
>  	bp->b_flags |= XBF_WRITE;
> -	bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL);
> +	bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q |
> +			 XBF_WRITE_FAIL | XBF_DONE);
>  
>  	if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
>  		trace_xfs_bdstrat_shut(bp, _RET_IP_);
>  
> -		/*
> -		 * Metadata write that didn't get logged but written anyway.
> -		 * These aren't associated with a transaction, and can be
> -		 * ignored.
> -		 */
> -		if (!bp->b_iodone)
> -			return xfs_bioerror_relse(bp);
> -		return xfs_bioerror(bp);
> +		xfs_buf_ioerror(bp, -EIO);
> +		xfs_buf_stale(bp);
> +
> +		/* sync IO, xfs_buf_ioend is going to remove a ref here */
> +		xfs_buf_hold(bp);

Looks correct, but that's kind of ugly. The reference serves no purpose
except to appease the error sequence. It gives the impression that the
reference management should be handled at a higher level (and with truly
synchronous I/O primitives/mechanisms, it is ;).

At the very least, can we reorganize the ioend side of things to handle
this? We already have the duplicate execution issue previously mentioned
that has to get resolved. Some duplicate code is fine if it improves
clarity, imo.

Brian

> +		xfs_buf_ioend(bp);
> +		return -EIO;
>  	}
>  
>  	xfs_buf_iorequest(bp);
> @@ -1848,16 +1818,19 @@ __xfs_buf_delwri_submit(
>  		if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) {
>  			trace_xfs_bdstrat_shut(bp, _RET_IP_);
>  
> +			xfs_buf_ioerror(bp, -EIO);
> +			xfs_buf_stale(bp);
> +
>  			/*
> -			 * Metadata write that didn't get logged but written anyway.
> -			 * These aren't associated with a transaction, and can be
> -			 * ignored.
> +			 * if sync IO, xfs_buf_ioend is going to remove a
> +			 * ref here. We need to add that so we can collect
> +			 * all the buffer errors in the wait loop.
>  			 */
> -			if (!bp->b_iodone)
> -				return xfs_bioerror_relse(bp);
> -			return xfs_bioerror(bp);
> -		}
> -		xfs_buf_iorequest(bp);
> +			if (wait)
> +				xfs_buf_hold(bp);
> +			xfs_buf_ioend(bp);
> +		} else
> +			xfs_buf_iorequest(bp);
>  	}
>  	blk_finish_plug(&plug);
>  
> -- 
> 2.0.0
> 
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2014-08-15 14:35 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-15  6:38 [RFC PATCH 0/9] xfs: clean up xfs_buf io interfaces Dave Chinner
2014-08-15  6:38 ` [PATCH 1/9] xfs: synchronous buffer IO needs a reference Dave Chinner
2014-08-15 13:18   ` Brian Foster
2014-08-15 23:17     ` Dave Chinner
2014-08-18 14:15       ` Brian Foster
2014-08-29  0:18   ` Christoph Hellwig
2014-08-15  6:39 ` [PATCH 2/9] xfs: xfs_buf_ioend and xfs_buf_iodone_work duplicate functionality Dave Chinner
2014-08-15 13:18   ` Brian Foster
2014-08-15 23:21     ` Dave Chinner
2014-08-18 14:15       ` Brian Foster
2014-08-29  0:22   ` Christoph Hellwig
2014-08-29  0:55     ` Dave Chinner
2014-08-15  6:39 ` [PATCH 3/9] xfs: rework xfs_buf_bio_endio error handling Dave Chinner
2014-08-15 13:18   ` Brian Foster
2014-08-15 23:25     ` Dave Chinner
2014-08-29  0:23   ` Christoph Hellwig
2014-08-15  6:39 ` [PATCH 4/9] xfs: kill xfs_bdstrat_cb Dave Chinner
2014-08-29  0:24   ` Christoph Hellwig
2014-08-15  6:39 ` [PATCH 5/9] xfs: xfs_bioerror can die Dave Chinner
2014-08-15 14:35   ` Brian Foster [this message]
2014-08-15 23:27     ` Dave Chinner
2014-08-29  0:28   ` Christoph Hellwig
2014-08-29  1:05     ` Dave Chinner
2014-08-15  6:39 ` [PATCH 6/9] xfs: kill xfs_bioerror_relse Dave Chinner
2014-08-29  0:32   ` Christoph Hellwig
2014-08-29  1:12     ` Dave Chinner
2014-08-29 18:26       ` Christoph Hellwig
2014-08-30  0:05         ` Dave Chinner
2014-08-15  6:39 ` [PATCH 7/9] xfs: clean up xfs_trans_buf_read_map Dave Chinner
2014-08-15  6:39 ` [PATCH 8/9] xfs: introduce xfs_buf_submit[_wait] Dave Chinner
2014-08-15 13:10   ` Christoph Hellwig
2014-08-15 23:37     ` Dave Chinner
2014-08-16  4:55       ` Christoph Hellwig
2014-08-15 14:35   ` Brian Foster
2014-08-15 23:39     ` Dave Chinner
2014-08-18 14:16       ` Brian Foster
2014-08-15 16:13   ` Brian Foster
2014-08-15 23:58     ` Dave Chinner
2014-08-18 14:26       ` Brian Foster
2014-08-15  6:39 ` [PATCH 9/9] xfs: check xfs_buf_read_uncached returns correctly Dave Chinner
2014-08-15 12:56   ` Christoph Hellwig
2014-08-15 23:58     ` Dave Chinner
2014-08-29  0:37       ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140815143540.GD4096@laptop.bfoster \
    --to=bfoster@redhat.com \
    --cc=david@fromorbit.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox