diff options
author | Dave Chinner <dchinner@redhat.com> | 2012-11-12 06:54:12 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-11-15 22:34:41 -0500 |
commit | 82025d7f79148fe66a1594a0ebe4ab38152cf9e6 (patch) | |
tree | fb47428d6604ebb5f941d3f8c58e1de9d54a4b59 /fs/xfs/xfs_dir2_block.c | |
parent | 20f7e9f3726a27cccade65c28265eef8ca50eecb (diff) |
xfs: verify dir2 block format buffers
Add a dir2 block format read verifier. To fully verify every block
when read, call xfs_dir2_data_check() on them. Change
xfs_dir2_data_check() to do runtime checking, convert ASSERT()
checks to XFS_WANT_CORRUPTED_RETURN(), which will trigger an ASSERT
failure on debug kernels, but on production kernels will dump an
error to dmesg and return EFSCORRUPTED to the caller.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Phil White <pwhite@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_block.c')
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 25ce409487be..57351b868861 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -56,6 +56,26 @@ xfs_dir_startup(void) | |||
56 | xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2); | 56 | xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void | ||
60 | xfs_dir2_block_verify( | ||
61 | struct xfs_buf *bp) | ||
62 | { | ||
63 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
64 | struct xfs_dir2_data_hdr *hdr = bp->b_addr; | ||
65 | int block_ok = 0; | ||
66 | |||
67 | block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); | ||
68 | block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0; | ||
69 | |||
70 | if (!block_ok) { | ||
71 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); | ||
72 | xfs_buf_ioerror(bp, EFSCORRUPTED); | ||
73 | } | ||
74 | |||
75 | bp->b_iodone = NULL; | ||
76 | xfs_buf_ioend(bp, 0); | ||
77 | } | ||
78 | |||
59 | static int | 79 | static int |
60 | xfs_dir2_block_read( | 80 | xfs_dir2_block_read( |
61 | struct xfs_trans *tp, | 81 | struct xfs_trans *tp, |
@@ -65,7 +85,7 @@ xfs_dir2_block_read( | |||
65 | struct xfs_mount *mp = dp->i_mount; | 85 | struct xfs_mount *mp = dp->i_mount; |
66 | 86 | ||
67 | return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, | 87 | return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, |
68 | XFS_DATA_FORK, NULL); | 88 | XFS_DATA_FORK, xfs_dir2_block_verify); |
69 | } | 89 | } |
70 | 90 | ||
71 | static void | 91 | static void |