xfs: refactor realtime volume extent validation

Refactor all the open-coded validation of realtime device extents into a
single helper.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong 2020-12-04 13:24:22 -08:00
parent 67457eb0d2
commit 18695ad425
5 changed files with 23 additions and 20 deletions

View File

@ -6226,20 +6226,13 @@ xfs_bmap_validate_extent(
struct xfs_bmbt_irec *irec)
{
struct xfs_mount *mp = ip->i_mount;
xfs_fsblock_t endfsb;
bool isrt;
if (irec->br_startblock + irec->br_blockcount <= irec->br_startblock)
return __this_address;
if (irec->br_startoff + irec->br_blockcount <= irec->br_startoff)
return __this_address;
isrt = XFS_IS_REALTIME_INODE(ip);
endfsb = irec->br_startblock + irec->br_blockcount - 1;
if (isrt && whichfork == XFS_DATA_FORK) {
if (!xfs_verify_rtbno(mp, irec->br_startblock))
return __this_address;
if (!xfs_verify_rtbno(mp, endfsb))
if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) {
if (!xfs_verify_rtext(mp, irec->br_startblock,
irec->br_blockcount))
return __this_address;
} else {
if (!xfs_verify_fsbext(mp, irec->br_startblock,

View File

@ -198,6 +198,22 @@ xfs_verify_rtbno(
return rtbno < mp->m_sb.sb_rblocks;
}
/* Verify that a realtime device extent is fully contained inside the volume. */
bool
xfs_verify_rtext(
struct xfs_mount *mp,
xfs_rtblock_t rtbno,
xfs_rtblock_t len)
{
if (rtbno + len <= rtbno)
return false;
if (!xfs_verify_rtbno(mp, rtbno))
return false;
return xfs_verify_rtbno(mp, rtbno + len - 1);
}
/* Calculate the range of valid icount values. */
void
xfs_icount_range(

View File

@ -197,6 +197,8 @@ bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino);
bool xfs_verify_rtbno(struct xfs_mount *mp, xfs_rtblock_t rtbno);
bool xfs_verify_rtext(struct xfs_mount *mp, xfs_rtblock_t rtbno,
xfs_rtblock_t len);
bool xfs_verify_icount(struct xfs_mount *mp, unsigned long long icount);
bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off);
void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min,

View File

@ -319,7 +319,6 @@ xchk_bmap_iextent(
struct xfs_bmbt_irec *irec)
{
struct xfs_mount *mp = info->sc->mp;
xfs_filblks_t end;
int error = 0;
/*
@ -349,13 +348,8 @@ xchk_bmap_iextent(
if (irec->br_blockcount > MAXEXTLEN)
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
if (irec->br_startblock + irec->br_blockcount <= irec->br_startblock)
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
end = irec->br_startblock + irec->br_blockcount - 1;
if (info->is_rt &&
(!xfs_verify_rtbno(mp, irec->br_startblock) ||
!xfs_verify_rtbno(mp, end)))
!xfs_verify_rtext(mp, irec->br_startblock, irec->br_blockcount))
xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff);
if (!info->is_rt &&

View File

@ -52,9 +52,7 @@ xchk_rtbitmap_rec(
startblock = rec->ar_startext * tp->t_mountp->m_sb.sb_rextsize;
blockcount = rec->ar_extcount * tp->t_mountp->m_sb.sb_rextsize;
if (startblock + blockcount <= startblock ||
!xfs_verify_rtbno(sc->mp, startblock) ||
!xfs_verify_rtbno(sc->mp, startblock + blockcount - 1))
if (!xfs_verify_rtext(sc->mp, startblock, blockcount))
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
return 0;
}