diff options
Diffstat (limited to 'fs/xfs/xfs_buf.c')
| -rw-r--r-- | fs/xfs/xfs_buf.c | 16 | 
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 107f2fdfe41f..cb10a0aaab3a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1372,21 +1372,29 @@ xfs_buf_iorequest(  		xfs_buf_wait_unpin(bp);  	xfs_buf_hold(bp); -	/* Set the count to 1 initially, this will stop an I/O +	/* +	 * Set the count to 1 initially, this will stop an I/O  	 * completion callout which happens before we have started  	 * all the I/O from calling xfs_buf_ioend too early.  	 */  	atomic_set(&bp->b_io_remaining, 1);  	_xfs_buf_ioapply(bp); -	_xfs_buf_ioend(bp, 1); +	/* +	 * If _xfs_buf_ioapply failed, we'll get back here with +	 * only the reference we took above.  _xfs_buf_ioend will +	 * drop it to zero, so we'd better not queue it for later, +	 * or we'll free it before it's done. +	 */ +	_xfs_buf_ioend(bp, bp->b_error ? 0 : 1);  	xfs_buf_rele(bp);  }  /*   * Waits for I/O to complete on the buffer supplied.  It returns immediately if - * no I/O is pending or there is already a pending error on the buffer.  It - * returns the I/O error code, if any, or 0 if there was no error. + * no I/O is pending or there is already a pending error on the buffer, in which + * case nothing will ever complete.  It returns the I/O error code, if any, or + * 0 if there was no error.   */  int  xfs_buf_iowait(  | 
