]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: check that rtblock extents do not break rtsupers or rtgroups
authorDarrick J. Wong <djwong@kernel.org>
Mon, 25 Nov 2024 21:14:21 +0000 (13:14 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 24 Dec 2024 02:01:29 +0000 (18:01 -0800)
Source kernel commit: 9bb512734722d2815bb79e27850dddeeff10db90

Check that rt block pointers do not point to the realtime superblock and
that allocated rt space extents do not cross rtgroup boundaries.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_types.c

index a70c0395979cf89aaa5e71592f8b9d2586ebdfa3..4e366e62eb2ae8de9085a86fed3a8502c0af9534 100644 (file)
@@ -12,6 +12,8 @@
 #include "xfs_bit.h"
 #include "xfs_mount.h"
 #include "xfs_ag.h"
+#include "xfs_rtbitmap.h"
+#include "xfs_rtgroup.h"
 
 
 /*
@@ -135,18 +137,37 @@ xfs_verify_dir_ino(
 }
 
 /*
- * Verify that an realtime block number pointer doesn't point off the
- * end of the realtime device.
+ * Verify that a realtime block number pointer neither points outside the
+ * allocatable areas of the rtgroup nor off the end of the realtime
+ * device.
  */
 inline bool
 xfs_verify_rtbno(
        struct xfs_mount        *mp,
        xfs_rtblock_t           rtbno)
 {
-       return rtbno < mp->m_sb.sb_rblocks;
+       if (rtbno >= mp->m_sb.sb_rblocks)
+               return false;
+
+       if (xfs_has_rtgroups(mp)) {
+               xfs_rgnumber_t  rgno = xfs_rtb_to_rgno(mp, rtbno);
+               xfs_rtxnum_t    rtx = xfs_rtb_to_rtx(mp, rtbno);
+
+               if (rgno >= mp->m_sb.sb_rgcount)
+                       return false;
+               if (rtx >= xfs_rtgroup_extents(mp, rgno))
+                       return false;
+               if (xfs_has_rtsb(mp) && rgno == 0 && rtx == 0)
+                       return false;
+       }
+       return true;
 }
 
-/* Verify that a realtime device extent is fully contained inside the volume. */
+/*
+ * Verify that an allocated realtime device extent neither points outside
+ * allocatable areas of the rtgroup, across an rtgroup boundary, nor off the
+ * end of the realtime device.
+ */
 bool
 xfs_verify_rtbext(
        struct xfs_mount        *mp,
@@ -159,7 +180,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. */