diff options
author | Eric Sandeen <sandeen@sandeen.net> | 2017-10-10 00:08:06 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2017-10-11 13:21:07 -0400 |
commit | 93e8befc17f6d6ea92b0aee3741ceac8bca4590f (patch) | |
tree | 19412a90dafb857dd468dcddfbe4bd6f1ca14180 | |
parent | f35c5e10c6ed6ba52a8dd8573924a80b6a02f03f (diff) |
xfs: handle error if xfs_btree_get_bufs fails
Jason reported that a corrupted filesystem failed to replay
the log with a metadata block out of bounds warning:
XFS (dm-2): _xfs_buf_find: Block out of range: block 0x80270fff8, EOFS 0x9c40000
_xfs_buf_find() and xfs_btree_get_bufs() return NULL if
that happens, and then when xfs_alloc_fix_freelist() calls
xfs_trans_binval() on that NULL bp, we oops with:
BUG: unable to handle kernel NULL pointer dereference at 00000000000000f8
We don't handle _xfs_buf_find errors very well, every
caller higher up the stack gets to guess at why it failed.
But we should at least handle it somehow, so return
EFSCORRUPTED here.
Reported-by: Jason L Tibbitts III <tibbs@math.uh.edu>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 744dcaec34cc..f965ce832bc0 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
@@ -1584,6 +1584,10 @@ xfs_alloc_ag_vextent_small( | |||
1584 | 1584 | ||
1585 | bp = xfs_btree_get_bufs(args->mp, args->tp, | 1585 | bp = xfs_btree_get_bufs(args->mp, args->tp, |
1586 | args->agno, fbno, 0); | 1586 | args->agno, fbno, 0); |
1587 | if (!bp) { | ||
1588 | error = -EFSCORRUPTED; | ||
1589 | goto error0; | ||
1590 | } | ||
1587 | xfs_trans_binval(args->tp, bp); | 1591 | xfs_trans_binval(args->tp, bp); |
1588 | } | 1592 | } |
1589 | args->len = 1; | 1593 | args->len = 1; |
@@ -2141,6 +2145,10 @@ xfs_alloc_fix_freelist( | |||
2141 | if (error) | 2145 | if (error) |
2142 | goto out_agbp_relse; | 2146 | goto out_agbp_relse; |
2143 | bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); | 2147 | bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); |
2148 | if (!bp) { | ||
2149 | error = -EFSCORRUPTED; | ||
2150 | goto out_agbp_relse; | ||
2151 | } | ||
2144 | xfs_trans_binval(tp, bp); | 2152 | xfs_trans_binval(tp, bp); |
2145 | } | 2153 | } |
2146 | 2154 | ||