diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap_btree.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 58 | 
1 files changed, 24 insertions, 34 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index c10aecaaae44..9faf479aba49 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -425,33 +425,29 @@ xfs_bmbt_diff_two_keys(  			  be64_to_cpu(k2->bmbt.br_startoff);  } -static bool +static xfs_failaddr_t  xfs_bmbt_verify(  	struct xfs_buf		*bp)  {  	struct xfs_mount	*mp = bp->b_target->bt_mount;  	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp); +	xfs_failaddr_t		fa;  	unsigned int		level;  	switch (block->bb_magic) {  	case cpu_to_be32(XFS_BMAP_CRC_MAGIC): -		if (!xfs_sb_version_hascrc(&mp->m_sb)) -			return false; -		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid)) -			return false; -		if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn) -			return false;  		/*  		 * XXX: need a better way of verifying the owner here. Right now  		 * just make sure there has been one set.  		 */ -		if (be64_to_cpu(block->bb_u.l.bb_owner) == 0) -			return false; +		fa = xfs_btree_lblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN); +		if (fa) +			return fa;  		/* fall through */  	case cpu_to_be32(XFS_BMAP_MAGIC):  		break;  	default: -		return false; +		return __this_address;  	}  	/* @@ -463,46 +459,39 @@ xfs_bmbt_verify(  	 */  	level = be16_to_cpu(block->bb_level);  	if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1])) -		return false; -	if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) -		return false; - -	/* sibling pointer verification */ -	if (!block->bb_u.l.bb_leftsib || -	    (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) && -	     !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))) -		return false; -	if (!block->bb_u.l.bb_rightsib || -	    (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) && -	     !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))) -		return false; - -	return true; +		return __this_address; + +	return xfs_btree_lblock_verify(bp, mp->m_bmap_dmxr[level != 0]);  }  static void  xfs_bmbt_read_verify(  	struct xfs_buf	*bp)  { +	xfs_failaddr_t	fa; +  	if (!xfs_btree_lblock_verify_crc(bp)) -		xfs_buf_ioerror(bp, -EFSBADCRC); -	else if (!xfs_bmbt_verify(bp)) -		xfs_buf_ioerror(bp, -EFSCORRUPTED); +		xfs_verifier_error(bp, -EFSBADCRC, __this_address); +	else { +		fa = xfs_bmbt_verify(bp); +		if (fa) +			xfs_verifier_error(bp, -EFSCORRUPTED, fa); +	} -	if (bp->b_error) { +	if (bp->b_error)  		trace_xfs_btree_corrupt(bp, _RET_IP_); -		xfs_verifier_error(bp); -	}  }  static void  xfs_bmbt_write_verify(  	struct xfs_buf	*bp)  { -	if (!xfs_bmbt_verify(bp)) { +	xfs_failaddr_t	fa; + +	fa = xfs_bmbt_verify(bp); +	if (fa) {  		trace_xfs_btree_corrupt(bp, _RET_IP_); -		xfs_buf_ioerror(bp, -EFSCORRUPTED); -		xfs_verifier_error(bp); +		xfs_verifier_error(bp, -EFSCORRUPTED, fa);  		return;  	}  	xfs_btree_lblock_calc_crc(bp); @@ -512,6 +501,7 @@ const struct xfs_buf_ops xfs_bmbt_buf_ops = {  	.name = "xfs_bmbt",  	.verify_read = xfs_bmbt_read_verify,  	.verify_write = xfs_bmbt_write_verify, +	.verify_struct = xfs_bmbt_verify,  };  |