Commit eab4e63368b4cfa597dbdac66d1a7a836a693b7d
Committed by
Ben Myers
1 parent
c3f8fc73ac
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
fs/xfs/xfs_buf.c
... | ... | @@ -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 |
fs/xfs/xfs_fsops.c
... | ... | @@ -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 */ |
fs/xfs/xfs_mount.c
... | ... | @@ -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); |