Commit f135761a authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: refactor btree pointer checks



Refactor the btree pointer checks so that we can call them from the
scrub code without logging errors to dmesg.  Preserve the existing error
reporting for regular operations.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 21ec5416
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -646,8 +646,8 @@ xfs_bmap_btree_to_extents(
	cbno = be64_to_cpu(*pp);
	*logflagsp = 0;
#ifdef DEBUG
	if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
		return error;
	XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
			xfs_btree_check_lptr(cur, cbno, 1));
#endif
	error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
				&xfs_bmbt_buf_ops);
+32 −38
Original line number Diff line number Diff line
@@ -177,59 +177,53 @@ xfs_btree_check_block(
		return xfs_btree_check_sblock(cur, block, level, bp);
}

/*
 * Check that (long) pointer is ok.
 */
int					/* error (0 or EFSCORRUPTED) */
/* Check that this long pointer is valid and points within the fs. */
bool
xfs_btree_check_lptr(
	struct xfs_btree_cur	*cur,	/* btree cursor */
	xfs_fsblock_t		bno,	/* btree block disk address */
	int			level)	/* btree block level */
	struct xfs_btree_cur	*cur,
	xfs_fsblock_t		fsbno,
	int			level)
{
	XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
		level > 0 &&
		bno != NULLFSBLOCK &&
		XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
	return 0;
	if (level <= 0)
		return false;
	return xfs_verify_fsbno(cur->bc_mp, fsbno);
}

#ifdef DEBUG
/*
 * Check that (short) pointer is ok.
 */
STATIC int				/* error (0 or EFSCORRUPTED) */
/* Check that this short pointer is valid and points within the AG. */
bool
xfs_btree_check_sptr(
	struct xfs_btree_cur	*cur,	/* btree cursor */
	xfs_agblock_t		bno,	/* btree block disk address */
	int			level)	/* btree block level */
	struct xfs_btree_cur	*cur,
	xfs_agblock_t		agbno,
	int			level)
{
	xfs_agblock_t		agblocks = cur->bc_mp->m_sb.sb_agblocks;

	XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
		level > 0 &&
		bno != NULLAGBLOCK &&
		bno != 0 &&
		bno < agblocks);
	return 0;
	if (level <= 0)
		return false;
	return xfs_verify_agbno(cur->bc_mp, cur->bc_private.a.agno, agbno);
}

#ifdef DEBUG
/*
 * Check that block ptr is ok.
 * Check that a given (indexed) btree pointer at a certain level of a
 * btree is valid and doesn't point past where it should.
 */
STATIC int				/* error (0 or EFSCORRUPTED) */
int
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 */
	struct xfs_btree_cur	*cur,
	union xfs_btree_ptr	*ptr,
	int			index,
	int			level)
{
	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
		return xfs_btree_check_lptr(cur,
				be64_to_cpu((&ptr->l)[index]), level);
		XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
				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);
		XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
				xfs_btree_check_sptr(cur,
					be32_to_cpu((&ptr->s)[index]), level));
	}

	return 0;
}
#endif

+11 −2
Original line number Diff line number Diff line
@@ -269,10 +269,19 @@ xfs_btree_check_block(
/*
 * Check that (long) pointer is ok.
 */
int					/* error (0 or EFSCORRUPTED) */
bool					/* error (0 or EFSCORRUPTED) */
xfs_btree_check_lptr(
	struct xfs_btree_cur	*cur,	/* btree cursor */
	xfs_fsblock_t		ptr,	/* btree block disk address */
	xfs_fsblock_t		fsbno,	/* btree block disk address */
	int			level);	/* btree block level */

/*
 * Check that (short) pointer is ok.
 */
bool					/* error (0 or EFSCORRUPTED) */
xfs_btree_check_sptr(
	struct xfs_btree_cur	*cur,	/* btree cursor */
	xfs_agblock_t		agbno,	/* btree block disk address */
	int			level);	/* btree block level */

/*