Commit 18695ad4 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: refactor realtime volume extent validation

Refactor all the open-coded validation of realtime device extents into a
single helper.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 67457eb0
...@@ -6226,20 +6226,13 @@ xfs_bmap_validate_extent( ...@@ -6226,20 +6226,13 @@ xfs_bmap_validate_extent(
struct xfs_bmbt_irec *irec) struct xfs_bmbt_irec *irec)
{ {
struct xfs_mount *mp = ip->i_mount; 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) if (irec->br_startoff + irec->br_blockcount <= irec->br_startoff)
return __this_address; return __this_address;
isrt = XFS_IS_REALTIME_INODE(ip); if (XFS_IS_REALTIME_INODE(ip) && whichfork == XFS_DATA_FORK) {
endfsb = irec->br_startblock + irec->br_blockcount - 1; if (!xfs_verify_rtext(mp, irec->br_startblock,
if (isrt && whichfork == XFS_DATA_FORK) { irec->br_blockcount))
if (!xfs_verify_rtbno(mp, irec->br_startblock))
return __this_address;
if (!xfs_verify_rtbno(mp, endfsb))
return __this_address; return __this_address;
} else { } else {
if (!xfs_verify_fsbext(mp, irec->br_startblock, if (!xfs_verify_fsbext(mp, irec->br_startblock,
......
...@@ -198,6 +198,22 @@ xfs_verify_rtbno( ...@@ -198,6 +198,22 @@ xfs_verify_rtbno(
return rtbno < mp->m_sb.sb_rblocks; 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. */ /* Calculate the range of valid icount values. */
void void
xfs_icount_range( xfs_icount_range(
......
...@@ -197,6 +197,8 @@ bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); ...@@ -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_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_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_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_icount(struct xfs_mount *mp, unsigned long long icount);
bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off); bool xfs_verify_dablk(struct xfs_mount *mp, xfs_fileoff_t off);
void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min, void xfs_icount_range(struct xfs_mount *mp, unsigned long long *min,
......
...@@ -319,7 +319,6 @@ xchk_bmap_iextent( ...@@ -319,7 +319,6 @@ xchk_bmap_iextent(
struct xfs_bmbt_irec *irec) struct xfs_bmbt_irec *irec)
{ {
struct xfs_mount *mp = info->sc->mp; struct xfs_mount *mp = info->sc->mp;
xfs_filblks_t end;
int error = 0; int error = 0;
/* /*
...@@ -349,13 +348,8 @@ xchk_bmap_iextent( ...@@ -349,13 +348,8 @@ xchk_bmap_iextent(
if (irec->br_blockcount > MAXEXTLEN) if (irec->br_blockcount > MAXEXTLEN)
xchk_fblock_set_corrupt(info->sc, info->whichfork, xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff); 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 && if (info->is_rt &&
(!xfs_verify_rtbno(mp, irec->br_startblock) || !xfs_verify_rtext(mp, irec->br_startblock, irec->br_blockcount))
!xfs_verify_rtbno(mp, end)))
xchk_fblock_set_corrupt(info->sc, info->whichfork, xchk_fblock_set_corrupt(info->sc, info->whichfork,
irec->br_startoff); irec->br_startoff);
if (!info->is_rt && if (!info->is_rt &&
......
...@@ -52,9 +52,7 @@ xchk_rtbitmap_rec( ...@@ -52,9 +52,7 @@ xchk_rtbitmap_rec(
startblock = rec->ar_startext * tp->t_mountp->m_sb.sb_rextsize; startblock = rec->ar_startext * tp->t_mountp->m_sb.sb_rextsize;
blockcount = rec->ar_extcount * tp->t_mountp->m_sb.sb_rextsize; blockcount = rec->ar_extcount * tp->t_mountp->m_sb.sb_rextsize;
if (startblock + blockcount <= startblock || if (!xfs_verify_rtext(sc->mp, startblock, blockcount))
!xfs_verify_rtbno(sc->mp, startblock) ||
!xfs_verify_rtbno(sc->mp, startblock + blockcount - 1))
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0); xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment