Commit eab4e63368b4cfa597dbdac66d1a7a836a693b7d

Authored by Dave Chinner
Committed by Ben Myers
1 parent c3f8fc73ac

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>

Showing 4 changed files with 21 additions and 8 deletions Side-by-side Diff

... ... @@ -715,8 +715,7 @@
715 715 int flags,
716 716 xfs_buf_iodone_t verify)
717 717 {
718   - xfs_buf_t *bp;
719   - int error;
  718 + struct xfs_buf *bp;
720 719  
721 720 bp = xfs_buf_get_uncached(target, numblks, flags);
722 721 if (!bp)
... ... @@ -730,11 +729,7 @@
730 729 bp->b_iodone = verify;
731 730  
732 731 xfsbdstrat(target->bt_mount, bp);
733   - error = xfs_buf_iowait(bp);
734   - if (error) {
735   - xfs_buf_relse(bp);
736   - return NULL;
737   - }
  732 + xfs_buf_iowait(bp);
738 733 return bp;
739 734 }
740 735  
... ... @@ -171,6 +171,11 @@
171 171 XFS_FSS_TO_BB(mp, 1), 0, NULL);
172 172 if (!bp)
173 173 return EIO;
  174 + if (bp->b_error) {
  175 + int error = bp->b_error;
  176 + xfs_buf_relse(bp);
  177 + return error;
  178 + }
174 179 xfs_buf_relse(bp);
175 180  
176 181 new = nb; /* use new as a temporary here */
... ... @@ -658,6 +658,12 @@
658 658 xfs_warn(mp, "SB buffer read failed");
659 659 return EIO;
660 660 }
  661 + if (bp->b_error) {
  662 + error = bp->b_error;
  663 + if (loud)
  664 + xfs_warn(mp, "SB validate failed");
  665 + goto release_buf;
  666 + }
661 667  
662 668 /*
663 669 * Initialize the mount structure from the superblock.
fs/xfs/xfs_rtalloc.c
... ... @@ -1876,6 +1876,11 @@
1876 1876 XFS_FSB_TO_BB(mp, 1), 0, NULL);
1877 1877 if (!bp)
1878 1878 return EIO;
  1879 + if (bp->b_error) {
  1880 + error = bp->b_error;
  1881 + xfs_buf_relse(bp);
  1882 + return error;
  1883 + }
1879 1884 xfs_buf_relse(bp);
1880 1885  
1881 1886 /*
1882 1887  
... ... @@ -2221,8 +2226,10 @@
2221 2226 bp = xfs_buf_read_uncached(mp->m_rtdev_targp,
2222 2227 d - XFS_FSB_TO_BB(mp, 1),
2223 2228 XFS_FSB_TO_BB(mp, 1), 0, NULL);
2224   - if (!bp) {
  2229 + if (!bp || bp->b_error) {
2225 2230 xfs_warn(mp, "realtime device size check failed");
  2231 + if (bp)
  2232 + xfs_buf_relse(bp);
2226 2233 return EIO;
2227 2234 }
2228 2235 xfs_buf_relse(bp);