]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: refactor data device extent validation
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 7 Jan 2021 20:59:17 +0000 (15:59 -0500)
Source kernel commit: 67457eb0d225521a0e81327aef808cd0f9075880

Refactor all the open-coded validation of non-static data device extents
into a single helper.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_bmap.c
libxfs/xfs_types.c
libxfs/xfs_types.h

index 65cffb7b7d78fa1e0ba1a40553c59bf48e271182..92361f30f5f5490791929ed887a58e9a095590c3 100644 (file)
@@ -6235,12 +6235,8 @@ xfs_bmap_validate_extent(
                if (!xfs_verify_rtbno(mp, endfsb))
                        return __this_address;
        } else {
-               if (!xfs_verify_fsbno(mp, irec->br_startblock))
-                       return __this_address;
-               if (!xfs_verify_fsbno(mp, endfsb))
-                       return __this_address;
-               if (XFS_FSB_TO_AGNO(mp, irec->br_startblock) !=
-                   XFS_FSB_TO_AGNO(mp, endfsb))
+               if (!xfs_verify_fsbext(mp, irec->br_startblock,
+                                          irec->br_blockcount))
                        return __this_address;
        }
        if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK)
index fa113727b476062c5f5c3af2b92202410d289f28..3e6921e0137a0f75389059174c287cce835c6322 100644 (file)
@@ -61,6 +61,29 @@ xfs_verify_fsbno(
        return xfs_verify_agbno(mp, agno, XFS_FSB_TO_AGBNO(mp, fsbno));
 }
 
+/*
+ * Verify that a data device extent is fully contained inside the filesystem,
+ * does not cross an AG boundary, and does not point at static metadata.
+ */
+bool
+xfs_verify_fsbext(
+       struct xfs_mount        *mp,
+       xfs_fsblock_t           fsbno,
+       xfs_fsblock_t           len)
+{
+       if (fsbno + len <= fsbno)
+               return false;
+
+       if (!xfs_verify_fsbno(mp, fsbno))
+               return false;
+
+       if (!xfs_verify_fsbno(mp, fsbno + len - 1))
+               return false;
+
+       return  XFS_FSB_TO_AGNO(mp, fsbno) ==
+               XFS_FSB_TO_AGNO(mp, fsbno + len - 1);
+}
+
 /* Calculate the first and last possible inode number in an AG. */
 void
 xfs_agino_range(
index 397d94775440d039e43d05b37ebb68dac045459a..7feaaac25b3d76ee95c3c40463c4b99d08cb994b 100644 (file)
@@ -184,6 +184,8 @@ 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);
+bool xfs_verify_fsbext(struct xfs_mount *mp, xfs_fsblock_t fsbno,
+               xfs_fsblock_t len);
 
 void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
                xfs_agino_t *first, xfs_agino_t *last);