diff options
author | Darrick J. Wong <djwong@kernel.org> | 2022-08-18 15:43:48 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2022-10-14 14:17:10 -0700 |
commit | 7ec8c51db9d5cdda459c990e13498d7572a7ed74 (patch) | |
tree | 367496fa2b6bea57cc1d76d8a690098024ac86e5 /fs | |
parent | a1d668b6d7f774e6a4cd11536b091c8ce6334727 (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.c | 46 |
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. */ |