diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_btree.c')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 862084a47a7e..bddca9b92869 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "xfs_bmap.h" | 36 | #include "xfs_bmap.h" |
37 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
38 | #include "xfs_quota.h" | 38 | #include "xfs_quota.h" |
39 | #include "xfs_trace.h" | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Determine the extent state. | 42 | * Determine the extent state. |
@@ -707,6 +708,51 @@ xfs_bmbt_key_diff( | |||
707 | cur->bc_rec.b.br_startoff; | 708 | cur->bc_rec.b.br_startoff; |
708 | } | 709 | } |
709 | 710 | ||
711 | void | ||
712 | xfs_bmbt_read_verify( | ||
713 | struct xfs_buf *bp) | ||
714 | { | ||
715 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
716 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); | ||
717 | unsigned int level; | ||
718 | int lblock_ok; /* block passes checks */ | ||
719 | |||
720 | /* magic number and level verification. | ||
721 | * | ||
722 | * We don't know waht fork we belong to, so just verify that the level | ||
723 | * is less than the maximum of the two. Later checks will be more | ||
724 | * precise. | ||
725 | */ | ||
726 | level = be16_to_cpu(block->bb_level); | ||
727 | lblock_ok = block->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC) && | ||
728 | level < max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1]); | ||
729 | |||
730 | /* numrecs verification */ | ||
731 | lblock_ok = lblock_ok && | ||
732 | be16_to_cpu(block->bb_numrecs) <= mp->m_bmap_dmxr[level != 0]; | ||
733 | |||
734 | /* sibling pointer verification */ | ||
735 | lblock_ok = lblock_ok && | ||
736 | block->bb_u.l.bb_leftsib && | ||
737 | (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO) || | ||
738 | XFS_FSB_SANITY_CHECK(mp, | ||
739 | be64_to_cpu(block->bb_u.l.bb_leftsib))) && | ||
740 | block->bb_u.l.bb_rightsib && | ||
741 | (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO) || | ||
742 | XFS_FSB_SANITY_CHECK(mp, | ||
743 | be64_to_cpu(block->bb_u.l.bb_rightsib))); | ||
744 | |||
745 | if (!lblock_ok) { | ||
746 | trace_xfs_btree_corrupt(bp, _RET_IP_); | ||
747 | XFS_CORRUPTION_ERROR("xfs_bmbt_read_verify", | ||
748 | XFS_ERRLEVEL_LOW, mp, block); | ||
749 | xfs_buf_ioerror(bp, EFSCORRUPTED); | ||
750 | } | ||
751 | |||
752 | bp->b_iodone = NULL; | ||
753 | xfs_buf_ioend(bp, 0); | ||
754 | } | ||
755 | |||
710 | #ifdef DEBUG | 756 | #ifdef DEBUG |
711 | STATIC int | 757 | STATIC int |
712 | xfs_bmbt_keys_inorder( | 758 | xfs_bmbt_keys_inorder( |
@@ -746,6 +792,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { | |||
746 | .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, | 792 | .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, |
747 | .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, | 793 | .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, |
748 | .key_diff = xfs_bmbt_key_diff, | 794 | .key_diff = xfs_bmbt_key_diff, |
795 | .read_verify = xfs_bmbt_read_verify, | ||
749 | #ifdef DEBUG | 796 | #ifdef DEBUG |
750 | .keys_inorder = xfs_bmbt_keys_inorder, | 797 | .keys_inorder = xfs_bmbt_keys_inorder, |
751 | .recs_inorder = xfs_bmbt_recs_inorder, | 798 | .recs_inorder = xfs_bmbt_recs_inorder, |