xfs: create block pointer check functions

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 <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong 2017-10-17 21:37:32 -07:00
parent ed438b476b
commit 21ec54168b
4 changed files with 67 additions and 0 deletions

View File

@ -2931,3 +2931,52 @@ xfs_alloc_query_all(
query.fn = fn; query.fn = fn;
return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query); 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));
}

View File

@ -232,5 +232,9 @@ int xfs_alloc_query_range(struct xfs_btree_cur *cur,
xfs_alloc_query_range_fn fn, void *priv); xfs_alloc_query_range_fn fn, void *priv);
int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn, int xfs_alloc_query_all(struct xfs_btree_cur *cur, xfs_alloc_query_range_fn fn,
void *priv); 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__ */ #endif /* __XFS_ALLOC_H__ */

View File

@ -1086,3 +1086,15 @@ xfs_rtalloc_query_all(
return xfs_rtalloc_query_range(tp, &keys[0], &keys[1], fn, priv); 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;
}

View File

@ -138,6 +138,7 @@ int xfs_rtalloc_query_range(struct xfs_trans *tp,
int xfs_rtalloc_query_all(struct xfs_trans *tp, int xfs_rtalloc_query_all(struct xfs_trans *tp,
xfs_rtalloc_query_range_fn fn, xfs_rtalloc_query_range_fn fn,
void *priv); void *priv);
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
#else #else
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS) # define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS)
# define xfs_rtfree_extent(t,b,l) (ENOSYS) # define xfs_rtfree_extent(t,b,l) (ENOSYS)
@ -146,6 +147,7 @@ int xfs_rtalloc_query_all(struct xfs_trans *tp,
# define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS) # define xfs_rtalloc_query_range(t,l,h,f,p) (ENOSYS)
# define xfs_rtalloc_query_all(t,f,p) (ENOSYS) # define xfs_rtalloc_query_all(t,f,p) (ENOSYS)
# define xfs_rtbuf_get(m,t,b,i,p) (ENOSYS) # define xfs_rtbuf_get(m,t,b,i,p) (ENOSYS)
# define xfs_verify_rtbno(m, r) (false)
static inline int /* error */ static inline int /* error */
xfs_rtmount_init( xfs_rtmount_init(
xfs_mount_t *mp) /* file system mount structure */ xfs_mount_t *mp) /* file system mount structure */