summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_rmap_item.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index 19d2dc285ed6..6f3250a22093 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -466,11 +466,9 @@ xfs_rui_validate_map(
struct xfs_mount *mp,
struct xfs_map_extent *rmap)
{
- xfs_fsblock_t startblock_fsb;
- bool op_ok;
+ if (rmap->me_flags & ~XFS_RMAP_EXTENT_FLAGS)
+ return false;
- startblock_fsb = XFS_BB_TO_FSB(mp,
- XFS_FSB_TO_DADDR(mp, rmap->me_startblock));
switch (rmap->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {
case XFS_RMAP_EXTENT_MAP:
case XFS_RMAP_EXTENT_MAP_SHARED:
@@ -480,17 +478,25 @@ xfs_rui_validate_map(
case XFS_RMAP_EXTENT_CONVERT_SHARED:
case XFS_RMAP_EXTENT_ALLOC:
case XFS_RMAP_EXTENT_FREE:
- op_ok = true;
break;
default:
- op_ok = false;
- break;
+ return false;
}
- if (!op_ok || startblock_fsb == 0 ||
- rmap->me_len == 0 ||
- startblock_fsb >= mp->m_sb.sb_dblocks ||
- rmap->me_len >= mp->m_sb.sb_agblocks ||
- (rmap->me_flags & ~XFS_RMAP_EXTENT_FLAGS))
+
+ if (!XFS_RMAP_NON_INODE_OWNER(rmap->me_owner) &&
+ !xfs_verify_ino(mp, rmap->me_owner))
+ return false;
+
+ if (rmap->me_startoff + rmap->me_len <= rmap->me_startoff)
+ return false;
+
+ if (rmap->me_startblock + rmap->me_len <= rmap->me_startblock)
+ return false;
+
+ if (!xfs_verify_fsbno(mp, rmap->me_startblock))
+ return false;
+
+ if (!xfs_verify_fsbno(mp, rmap->me_startblock + rmap->me_len - 1))
return false;
return true;