summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_block.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-12 22:54:12 +1100
committerBen Myers <bpm@sgi.com>2012-11-15 21:34:41 -0600
commit82025d7f79148fe66a1594a0ebe4ab38152cf9e6 (patch)
treefb47428d6604ebb5f941d3f8c58e1de9d54a4b59 /fs/xfs/xfs_dir2_block.c
parent20f7e9f3726a27cccade65c28265eef8ca50eecb (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.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 25ce409487b..57351b86886 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -56,6 +56,26 @@ xfs_dir_startup(void)
xfs_dir_hash_dotdot = xfs_da_hashname((unsigned char *)"..", 2);
}
+static void
+xfs_dir2_block_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_dir2_data_hdr *hdr = bp->b_addr;
+ int block_ok = 0;
+
+ block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
+ block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0;
+
+ if (!block_ok) {
+ XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
+ xfs_buf_ioerror(bp, EFSCORRUPTED);
+ }
+
+ bp->b_iodone = NULL;
+ xfs_buf_ioend(bp, 0);
+}
+
static int
xfs_dir2_block_read(
struct xfs_trans *tp,
@@ -65,7 +85,7 @@ xfs_dir2_block_read(
struct xfs_mount *mp = dp->i_mount;
return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
- XFS_DATA_FORK, NULL);
+ XFS_DATA_FORK, xfs_dir2_block_verify);
}
static void