From 9bef6258a840053b074ab2a4ebd4a171a8f64a6e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 16 Nov 2017 22:11:31 -0600 Subject: [PATCH] xfs: create block pointer check functions Source kernel commit: 21ec54168b368f1a98097dee00625ec8ec2d47f3 Create some helper functions to check that a block pointer points within the filesystem (or AG) and doesn't point at static metadata. We will use this for scrub. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Eric Sandeen --- libxfs/xfs_alloc.c | 49 +++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_alloc.h | 4 ++++ libxfs/xfs_rtbitmap.c | 12 +++++++++++ 3 files changed, 65 insertions(+) diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 4bd11d3d3..31058ab2f 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -2928,3 +2928,52 @@ xfs_alloc_query_all( query.fn = fn; return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query); } + +/* Find the size of the AG, in blocks. */ +xfs_agblock_t +xfs_ag_block_count( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + ASSERT(agno < mp->m_sb.sb_agcount); + + if (agno < mp->m_sb.sb_agcount - 1) + return mp->m_sb.sb_agblocks; + return mp->m_sb.sb_dblocks - (agno * mp->m_sb.sb_agblocks); +} + +/* + * Verify that an AG block number pointer neither points outside the AG + * nor points at static metadata. + */ +bool +xfs_verify_agbno( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agblock_t agbno) +{ + xfs_agblock_t eoag; + + eoag = xfs_ag_block_count(mp, agno); + if (agbno >= eoag) + return false; + if (agbno <= XFS_AGFL_BLOCK(mp)) + return false; + return true; +} + +/* + * Verify that an FS block number pointer neither points outside the + * filesystem nor points at static AG metadata. + */ +bool +xfs_verify_fsbno( + struct xfs_mount *mp, + xfs_fsblock_t fsbno) +{ + xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, fsbno); + + if (agno >= mp->m_sb.sb_agcount) + return false; + return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno)); +} diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index ef26edc2e..7ba2d129d 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -232,5 +232,9 @@ int xfs_alloc_query_range(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, void *priv); int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, void *priv); +xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno); +bool xfs_verify_agbno(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno); +bool xfs_verify_fsbno(struct xfs_mount *mp, xfs_fsblock_t fsbno); #endif /* __XFS_ALLOC_H__ */ diff --git a/libxfs/xfs_rtbitmap.c b/libxfs/xfs_rtbitmap.c index 453dbb9ae..8da151b7d 100644 --- a/libxfs/xfs_rtbitmap.c +++ b/libxfs/xfs_rtbitmap.c @@ -1081,3 +1081,15 @@ xfs_rtalloc_query_all( return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv); } + +/* + * Verify that an realtime block number pointer doesn't point off the + * end of the realtime device. + */ +bool +xfs_verify_rtbno( + struct xfs_mount *mp, + xfs_rtblock_t rtbno) +{ + return rtbno < mp->m_sb.sb_rblocks; +} -- 2.47.2