mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	xfs: uncached buffer reads need to return an error
With verification being done as an IO completion callback, different errors can be returned from a read. Uncached reads only return a buffer or NULL on failure, which means the verification error cannot be returned to the caller. Split the error handling for these reads into two - a failure to get a buffer will still return NULL, but a read error will return a referenced buffer with b_error set rather than NULL. The caller is responsible for checking the error state of the buffer returned. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Phil White <pwhite@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
		
							parent
							
								
									c3f8fc73ac
								
							
						
					
					
						commit
						eab4e63368
					
				
					 4 changed files with 21 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -715,8 +715,7 @@ xfs_buf_read_uncached(
 | 
			
		|||
	int			flags,
 | 
			
		||||
	xfs_buf_iodone_t	verify)
 | 
			
		||||
{
 | 
			
		||||
	xfs_buf_t		*bp;
 | 
			
		||||
	int			error;
 | 
			
		||||
	struct xfs_buf		*bp;
 | 
			
		||||
 | 
			
		||||
	bp = xfs_buf_get_uncached(target, numblks, flags);
 | 
			
		||||
	if (!bp)
 | 
			
		||||
| 
						 | 
				
			
			@ -730,11 +729,7 @@ xfs_buf_read_uncached(
 | 
			
		|||
	bp->b_iodone = verify;
 | 
			
		||||
 | 
			
		||||
	xfsbdstrat(target->bt_mount, bp);
 | 
			
		||||
	error = xfs_buf_iowait(bp);
 | 
			
		||||
	if (error) {
 | 
			
		||||
		xfs_buf_relse(bp);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	xfs_buf_iowait(bp);
 | 
			
		||||
	return bp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,6 +171,11 @@ xfs_growfs_data_private(
 | 
			
		|||
				XFS_FSS_TO_BB(mp, 1), 0, NULL);
 | 
			
		||||
	if (!bp)
 | 
			
		||||
		return EIO;
 | 
			
		||||
	if (bp->b_error) {
 | 
			
		||||
		int	error = bp->b_error;
 | 
			
		||||
		xfs_buf_relse(bp);
 | 
			
		||||
		return error;
 | 
			
		||||
	}
 | 
			
		||||
	xfs_buf_relse(bp);
 | 
			
		||||
 | 
			
		||||
	new = nb;	/* use new as a temporary here */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -658,6 +658,12 @@ xfs_readsb(xfs_mount_t *mp, int flags)
 | 
			
		|||
			xfs_warn(mp, "SB buffer read failed");
 | 
			
		||||
		return EIO;
 | 
			
		||||
	}
 | 
			
		||||
	if (bp->b_error) {
 | 
			
		||||
		error = bp->b_error;
 | 
			
		||||
		if (loud)
 | 
			
		||||
			xfs_warn(mp, "SB validate failed");
 | 
			
		||||
		goto release_buf;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Initialize the mount structure from the superblock.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1876,6 +1876,11 @@ xfs_growfs_rt(
 | 
			
		|||
				XFS_FSB_TO_BB(mp, 1), 0, NULL);
 | 
			
		||||
	if (!bp)
 | 
			
		||||
		return EIO;
 | 
			
		||||
	if (bp->b_error) {
 | 
			
		||||
		error = bp->b_error;
 | 
			
		||||
		xfs_buf_relse(bp);
 | 
			
		||||
		return error;
 | 
			
		||||
	}
 | 
			
		||||
	xfs_buf_relse(bp);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -2221,8 +2226,10 @@ xfs_rtmount_init(
 | 
			
		|||
	bp = xfs_buf_read_uncached(mp->m_rtdev_targp,
 | 
			
		||||
					d - XFS_FSB_TO_BB(mp, 1),
 | 
			
		||||
					XFS_FSB_TO_BB(mp, 1), 0, NULL);
 | 
			
		||||
	if (!bp) {
 | 
			
		||||
	if (!bp || bp->b_error) {
 | 
			
		||||
		xfs_warn(mp, "realtime device size check failed");
 | 
			
		||||
		if (bp)
 | 
			
		||||
			xfs_buf_relse(bp);
 | 
			
		||||
		return EIO;
 | 
			
		||||
	}
 | 
			
		||||
	xfs_buf_relse(bp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue