summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-08-18 15:43:48 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-10-14 14:17:10 -0700
commit7ec8c51db9d5cdda459c990e13498d7572a7ed74 (patch)
tree367496fa2b6bea57cc1d76d8a690098024ac86e5 /fs
parenta1d668b6d7f774e6a4cd11536b091c8ce6334727 (diff)
xfs: check that rtblock extents do not overlap with the rt group metadata
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/libxfs/xfs_types.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c
index b1fa715e5f39..34d02b2bfdd1 100644
--- a/fs/xfs/libxfs/xfs_types.c
+++ b/fs/xfs/libxfs/xfs_types.c
@@ -13,6 +13,8 @@
#include "xfs_mount.h"
#include "xfs_ag.h"
#include "xfs_imeta.h"
+#include "xfs_rtbitmap.h"
+#include "xfs_rtgroup.h"
/*
@@ -134,6 +136,26 @@ xfs_verify_dir_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. */