]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: check that rtblock extents do not overlap with the rt group metadata
authorDarrick J. Wong <djwong@kernel.org>
Tue, 9 Jan 2024 17:39:55 +0000 (09:39 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 10 Apr 2024 00:21:38 +0000 (17:21 -0700)
The ondisk format specifies that the start of each realtime group must
have a superblock so that rt space mappings never cross an rtgroup
boundary.  Check that rt block pointers obey this.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
libxfs/xfs_types.c

index f5eab8839e3611fcf2f3420967e495892417bb09..6488cda24e8670b9efb966c3c51e780367a1eea7 100644 (file)
@@ -13,6 +13,8 @@
 #include "xfs_mount.h"
 #include "xfs_ag.h"
 #include "xfs_imeta.h"
+#include "xfs_rtbitmap.h"
+#include "xfs_rtgroup.h"
 
 
 /*
@@ -133,6 +135,26 @@ xfs_verify_dir_ino(
        return xfs_verify_ino(mp, ino);
 }
 
+/*
+ * Verify that an rtgroup block number pointer neither points outside the
+ * rtgroup nor points at static metadata.
+ */
+static inline bool
+xfs_verify_rgno_rgbno(
+       struct xfs_mount        *mp,
+       xfs_rgnumber_t          rgno,
+       xfs_rgblock_t           rgbno)
+{
+       xfs_rgblock_t           eorg;
+
+       eorg = xfs_rtgroup_block_count(mp, rgno);
+       if (rgbno >= eorg)
+               return false;
+       if (rgbno < mp->m_sb.sb_rextsize)
+               return false;
+       return true;
+}
+
 /*
  * Verify that an realtime block number pointer doesn't point off the
  * end of the realtime device.
@@ -142,7 +164,20 @@ xfs_verify_rtbno(
        struct xfs_mount        *mp,
        xfs_rtblock_t           rtbno)
 {
-       return rtbno < mp->m_sb.sb_rblocks;
+       xfs_rgnumber_t          rgno;
+       xfs_rgblock_t           rgbno;
+
+       if (rtbno >= mp->m_sb.sb_rblocks)
+               return false;
+
+       if (!xfs_has_rtgroups(mp))
+               return true;
+
+       rgbno = xfs_rtb_to_rgbno(mp, rtbno, &rgno);
+       if (rgno >= mp->m_sb.sb_rgcount)
+               return false;
+
+       return xfs_verify_rgno_rgbno(mp, rgno, rgbno);
 }
 
 /* Verify that a realtime device extent is fully contained inside the volume. */
@@ -158,7 +193,14 @@ xfs_verify_rtbext(
        if (!xfs_verify_rtbno(mp, rtbno))
                return false;
 
-       return xfs_verify_rtbno(mp, rtbno + len - 1);
+       if (!xfs_verify_rtbno(mp, rtbno + len - 1))
+               return false;
+
+       if (xfs_has_rtgroups(mp) &&
+           xfs_rtb_to_rgno(mp, rtbno) != xfs_rtb_to_rgno(mp, rtbno + len - 1))
+               return false;
+
+       return true;
 }
 
 /* Calculate the range of valid icount values. */