]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: prepare rmap functions to deal with rtrmapbt
authorDarrick J. Wong <djwong@kernel.org>
Tue, 15 Oct 2024 19:39:49 +0000 (12:39 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 5 Nov 2024 21:36:23 +0000 (13:36 -0800)
Prepare the high-level rmap functions to deal with the new realtime
rmapbt and its slightly different conventions.  Provide the ability
to talk to either rmapbt or rtrmapbt formats from the same high
level code.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_rmap.c
fs/xfs/libxfs/xfs_rmap.h
fs/xfs/libxfs/xfs_rtgroup.h

index 57dbf99ce004530f5c5a30b4a507a45f962dfff2..b107adc9ecd4a3edafbd240d34bfc35d8808b66a 100644 (file)
@@ -25,6 +25,7 @@
 #include "xfs_ag.h"
 #include "xfs_health.h"
 #include "xfs_rmap_item.h"
+#include "xfs_rtgroup.h"
 
 struct kmem_cache      *xfs_rmap_intent_cache;
 
@@ -264,11 +265,71 @@ xfs_rmap_check_irec(
        return NULL;
 }
 
+xfs_failaddr_t
+xfs_rtrmap_check_irec(
+       struct xfs_rtgroup              *rtg,
+       const struct xfs_rmap_irec      *irec)
+{
+       struct xfs_mount                *mp = rtg_mount(rtg);
+       bool                            is_inode;
+       bool                            is_unwritten;
+       bool                            is_bmbt;
+       bool                            is_attr;
+
+       if (irec->rm_blockcount == 0)
+               return __this_address;
+
+       if (irec->rm_owner == XFS_RMAP_OWN_FS) {
+               if (irec->rm_startblock != 0)
+                       return __this_address;
+               if (irec->rm_blockcount != mp->m_sb.sb_rextsize)
+                       return __this_address;
+               if (irec->rm_offset != 0)
+                       return __this_address;
+       } else {
+               if (!xfs_verify_rgbext(rtg, irec->rm_startblock,
+                                           irec->rm_blockcount))
+                       return __this_address;
+       }
+
+       if (!(xfs_verify_ino(mp, irec->rm_owner) ||
+             (irec->rm_owner <= XFS_RMAP_OWN_FS &&
+              irec->rm_owner >= XFS_RMAP_OWN_MIN)))
+               return __this_address;
+
+       /* Check flags. */
+       is_inode = !XFS_RMAP_NON_INODE_OWNER(irec->rm_owner);
+       is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK;
+       is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK;
+       is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN;
+
+       if (!is_inode && irec->rm_owner != XFS_RMAP_OWN_FS)
+               return __this_address;
+
+       if (!is_inode && irec->rm_offset != 0)
+               return __this_address;
+
+       if (is_bmbt || is_attr)
+               return __this_address;
+
+       if (is_unwritten && !is_inode)
+               return __this_address;
+
+       /* Check for a valid fork offset, if applicable. */
+       if (is_inode &&
+           !xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount))
+               return __this_address;
+
+       return NULL;
+}
+
 static inline xfs_failaddr_t
 xfs_rmap_check_btrec(
        struct xfs_btree_cur            *cur,
        const struct xfs_rmap_irec      *irec)
 {
+       if (xfs_btree_is_rtrmap(cur->bc_ops))
+               return xfs_rtrmap_check_irec(to_rtg(cur->bc_group), irec);
        return xfs_rmap_check_irec(to_perag(cur->bc_group), irec);
 }
 
@@ -283,6 +344,10 @@ xfs_rmap_complain_bad_rec(
        if (xfs_btree_is_mem_rmap(cur->bc_ops))
                xfs_warn(mp,
  "In-Memory Reverse Mapping BTree record corruption detected at %pS!", fa);
+       else if (xfs_btree_is_rtrmap(cur->bc_ops))
+               xfs_warn(mp,
+ "RT Reverse Mapping BTree record corruption in rtgroup %u detected at %pS!",
+                               cur->bc_group->xg_gno, fa);
        else
                xfs_warn(mp,
  "Reverse Mapping BTree record corruption in AG %d detected at %pS!",
index 8e2657af038e9e6aae2be38b4c7b7564ce769e4a..1b19f54b65047f3e38903b0a56aaf46b37f116f9 100644 (file)
@@ -7,6 +7,7 @@
 #define __XFS_RMAP_H__
 
 struct xfs_perag;
+struct xfs_rtgroup;
 
 static inline void
 xfs_rmap_ino_bmbt_owner(
@@ -206,6 +207,8 @@ xfs_failaddr_t xfs_rmap_btrec_to_irec(const union xfs_btree_rec *rec,
                struct xfs_rmap_irec *irec);
 xfs_failaddr_t xfs_rmap_check_irec(struct xfs_perag *pag,
                const struct xfs_rmap_irec *irec);
+xfs_failaddr_t xfs_rtrmap_check_irec(struct xfs_rtgroup *rtg,
+               const struct xfs_rmap_irec *irec);
 
 int xfs_rmap_has_records(struct xfs_btree_cur *cur, xfs_agblock_t bno,
                xfs_extlen_t len, enum xbtree_recpacking *outcome);
index 7e7e491ff06fa5bbe0dbbe8c437e23e866b1077d..6d65bc1f0b6c5c17cbf15586e0531d70f51ecbdc 100644 (file)
@@ -122,6 +122,32 @@ xfs_rtgroup_next(
        return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1);
 }
 
+static inline bool
+xfs_verify_rgbno(
+       struct xfs_rtgroup      *rtg,
+       xfs_rgblock_t           rgbno)
+{
+       ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
+
+       return xfs_verify_gbno(rtg_group(rtg), rgbno);
+}
+
+/*
+ * Check that [@rgbno,@len] is a valid extent range in @rtg.
+ *
+ * Must only be used for RTG-enabled file systems.
+ */
+static inline bool
+xfs_verify_rgbext(
+       struct xfs_rtgroup      *rtg,
+       xfs_rgblock_t           rgbno,
+       xfs_extlen_t            len)
+{
+       ASSERT(xfs_has_rtgroups(rtg_mount(rtg)));
+
+       return xfs_verify_gbext(rtg_group(rtg), rgbno, len);
+}
+
 static inline xfs_rtblock_t
 xfs_rgbno_to_rtb(
        struct xfs_rtgroup      *rtg,