summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_btree.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 16:54:53 +1100
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 16:54:53 +1100
commita23f6ef8ce966abc0f6e24a81ceb6a74ed30693b (patch)
treefa0d60a742dd47a966c177298268ca956c8bae4b /fs/xfs/xfs_btree.c
parentb524bfeee2152fa64b6210f28ced80489b9d2439 (diff)
[XFS] refactor btree validation helpers
Move the various btree validation helpers around in xfs_btree.c so that they are close to each other and in common #ifdef DEBUG sections. Also add a new xfs_btree_check_ptr helper to check a btree ptr that can be either long or short form. Split out from a bigger patch from Dave Chinner with various small changes applied by me. SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32183a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Bill O'Donnell <billodo@sgi.com> Signed-off-by: David Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_btree.c')
-rw-r--r--fs/xfs/xfs_btree.c196
1 files changed, 101 insertions, 95 deletions
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 4d793e4ccdc..966d58d50fa 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -81,24 +81,6 @@ xfs_btree_maxrecs(
#ifdef DEBUG
/*
- * Debug routine: check that block header is ok.
- */
-void
-xfs_btree_check_block(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_block_t *block, /* generic btree block pointer */
- int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer containing block, if any */
-{
- if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
- xfs_btree_check_lblock(cur, (xfs_btree_lblock_t *)block, level,
- bp);
- else
- xfs_btree_check_sblock(cur, (xfs_btree_sblock_t *)block, level,
- bp);
-}
-
-/*
* Debug routine: check that keys are in the right order.
*/
void
@@ -150,66 +132,8 @@ xfs_btree_check_key(
ASSERT(0);
}
}
-#endif /* DEBUG */
-
-/*
- * Checking routine: check that long form block header is ok.
- */
-/* ARGSUSED */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_lblock_t *block, /* btree long form block pointer */
- int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer for block, if any */
-{
- int lblock_ok; /* block passes checks */
- xfs_mount_t *mp; /* file system mount point */
-
- mp = cur->bc_mp;
- lblock_ok =
- be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
- be16_to_cpu(block->bb_level) == level &&
- be16_to_cpu(block->bb_numrecs) <=
- xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
- block->bb_leftsib &&
- (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
- block->bb_rightsib &&
- (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
- XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
- if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
- XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
- if (bp)
- xfs_buftrace("LBTREE ERROR", bp);
- XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
- mp);
- return XFS_ERROR(EFSCORRUPTED);
- }
- return 0;
-}
/*
- * Checking routine: check that (long) pointer is ok.
- */
-int /* error (0 or EFSCORRUPTED) */
-xfs_btree_check_lptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_dfsbno_t ptr, /* btree block disk address */
- int level) /* btree block level */
-{
- xfs_mount_t *mp; /* file system mount point */
-
- mp = cur->bc_mp;
- XFS_WANT_CORRUPTED_RETURN(
- level > 0 &&
- ptr != NULLDFSBNO &&
- XFS_FSB_SANITY_CHECK(mp, ptr));
- return 0;
-}
-
-#ifdef DEBUG
-/*
* Debug routine: check that records are in the right order.
*/
void
@@ -268,19 +192,49 @@ xfs_btree_check_rec(
}
#endif /* DEBUG */
-/*
- * Checking routine: check that block header is ok.
- */
-/* ARGSUSED */
+int /* error (0 or EFSCORRUPTED) */
+xfs_btree_check_lblock(
+ struct xfs_btree_cur *cur, /* btree cursor */
+ struct xfs_btree_lblock *block, /* btree long form block pointer */
+ int level, /* level of the btree block */
+ struct xfs_buf *bp) /* buffer for block, if any */
+{
+ int lblock_ok; /* block passes checks */
+ struct xfs_mount *mp; /* file system mount point */
+
+ mp = cur->bc_mp;
+ lblock_ok =
+ be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
+ be16_to_cpu(block->bb_level) == level &&
+ be16_to_cpu(block->bb_numrecs) <=
+ xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
+ block->bb_leftsib &&
+ (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
+ XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
+ block->bb_rightsib &&
+ (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
+ XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
+ if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
+ XFS_ERRTAG_BTREE_CHECK_LBLOCK,
+ XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
+ if (bp)
+ xfs_buftrace("LBTREE ERROR", bp);
+ XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
+ mp);
+ return XFS_ERROR(EFSCORRUPTED);
+ }
+ return 0;
+}
+
int /* error (0 or EFSCORRUPTED) */
xfs_btree_check_sblock(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_btree_sblock_t *block, /* btree short form block pointer */
+ struct xfs_btree_cur *cur, /* btree cursor */
+ struct xfs_btree_sblock *block, /* btree short form block pointer */
int level, /* level of the btree block */
- xfs_buf_t *bp) /* buffer containing block */
+ struct xfs_buf *bp) /* buffer containing block */
{
- xfs_buf_t *agbp; /* buffer for ag. freespace struct */
- xfs_agf_t *agf; /* ag. freespace structure */
+ struct xfs_buf *agbp; /* buffer for ag. freespace struct */
+ struct xfs_agf *agf; /* ag. freespace structure */
xfs_agblock_t agflen; /* native ag. freespace length */
int sblock_ok; /* block passes checks */
@@ -311,27 +265,79 @@ xfs_btree_check_sblock(
}
/*
- * Checking routine: check that (short) pointer is ok.
+ * Debug routine: check that block header is ok.
+ */
+int
+xfs_btree_check_block(
+ struct xfs_btree_cur *cur, /* btree cursor */
+ struct xfs_btree_block *block, /* generic btree block pointer */
+ int level, /* level of the btree block */
+ struct xfs_buf *bp) /* buffer containing block, if any */
+{
+ if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ return xfs_btree_check_lblock(cur,
+ (struct xfs_btree_lblock *)block, level, bp);
+ } else {
+ return xfs_btree_check_sblock(cur,
+ (struct xfs_btree_sblock *)block, level, bp);
+ }
+}
+
+/*
+ * Check that (long) pointer is ok.
+ */
+int /* error (0 or EFSCORRUPTED) */
+xfs_btree_check_lptr(
+ struct xfs_btree_cur *cur, /* btree cursor */
+ xfs_dfsbno_t bno, /* btree block disk address */
+ int level) /* btree block level */
+{
+ XFS_WANT_CORRUPTED_RETURN(
+ level > 0 &&
+ bno != NULLDFSBNO &&
+ XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
+ return 0;
+}
+
+/*
+ * Check that (short) pointer is ok.
*/
int /* error (0 or EFSCORRUPTED) */
xfs_btree_check_sptr(
- xfs_btree_cur_t *cur, /* btree cursor */
- xfs_agblock_t ptr, /* btree block disk address */
- int level) /* btree block level */
+ struct xfs_btree_cur *cur, /* btree cursor */
+ xfs_agblock_t bno, /* btree block disk address */
+ int level) /* btree block level */
{
- xfs_buf_t *agbp; /* buffer for ag. freespace struct */
- xfs_agf_t *agf; /* ag. freespace structure */
+ xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks;
- agbp = cur->bc_private.a.agbp;
- agf = XFS_BUF_TO_AGF(agbp);
XFS_WANT_CORRUPTED_RETURN(
level > 0 &&
- ptr != NULLAGBLOCK && ptr != 0 &&
- ptr < be32_to_cpu(agf->agf_length));
+ bno != NULLAGBLOCK &&
+ bno != 0 &&
+ bno < agblocks);
return 0;
}
/*
+ * Check that block ptr is ok.
+ */
+int /* error (0 or EFSCORRUPTED) */
+xfs_btree_check_ptr(
+ struct xfs_btree_cur *cur, /* btree cursor */
+ union xfs_btree_ptr *ptr, /* btree block disk address */
+ int index, /* offset from ptr to check */
+ int level) /* btree block level */
+{
+ if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
+ return xfs_btree_check_lptr(cur,
+ be64_to_cpu((&ptr->l)[index]), level);
+ } else {
+ return xfs_btree_check_sptr(cur,
+ be32_to_cpu((&ptr->s)[index]), level);
+ }
+}
+
+/*
* Delete the btree cursor.
*/
void