]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: report realtime rmap btree corruption errors to the health system
authorDarrick J. Wong <djwong@kernel.org>
Mon, 24 Feb 2025 18:21:50 +0000 (10:21 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 25 Feb 2025 17:15:58 +0000 (09:15 -0800)
Source kernel commit: 6d4933c221958d1e1848d5092a3e3d1c6e4a6f92

Whenever we encounter corrupt realtime rmap btree blocks, we should
report that to the health monitoring system for later reporting.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
libxfs/xfs_btree.h
libxfs/xfs_fs.h
libxfs/xfs_health.h
libxfs/xfs_rtgroup.c
libxfs/xfs_rtrmap_btree.c

index ee82dc777d6d5bda4f042289e8890759e3250134..dbc047b2fb2cf5a86064147aec440d0b54741867 100644 (file)
@@ -135,7 +135,7 @@ struct xfs_btree_ops {
        /* offset of btree stats array */
        unsigned int            statoff;
 
-       /* sick mask for health reporting (only for XFS_BTREE_TYPE_AG) */
+       /* sick mask for health reporting (not for bmap btrees) */
        unsigned int            sick_mask;
 
        /* cursor operations */
index 41ce4d3d650ec704786ff00a89b265bb1cf21cd7..7cca458ff8124562df19ba6fbc00ad4c9fc83607 100644 (file)
@@ -993,6 +993,7 @@ struct xfs_rtgroup_geometry {
 #define XFS_RTGROUP_GEOM_SICK_SUPER    (1U << 0)  /* superblock */
 #define XFS_RTGROUP_GEOM_SICK_BITMAP   (1U << 1)  /* rtbitmap */
 #define XFS_RTGROUP_GEOM_SICK_SUMMARY  (1U << 2)  /* rtsummary */
+#define XFS_RTGROUP_GEOM_SICK_RMAPBT   (1U << 3)  /* reverse mappings */
 
 /*
  * ioctl commands that are used by Linux filesystems
index d34986ac18c3fad50af20dd81333ac9a581fbb74..5c8a0aff6ba6e9d0eca20ed0ea7be2c8e8cadedf 100644 (file)
@@ -70,6 +70,7 @@ struct xfs_rtgroup;
 #define XFS_SICK_RG_SUPER      (1 << 0)  /* rt group superblock */
 #define XFS_SICK_RG_BITMAP     (1 << 1)  /* rt group bitmap */
 #define XFS_SICK_RG_SUMMARY    (1 << 2)  /* rt groups summary */
+#define XFS_SICK_RG_RMAPBT     (1 << 3)  /* reverse mappings */
 
 /* Observable health issues for AG metadata. */
 #define XFS_SICK_AG_SB         (1 << 0)  /* superblock */
@@ -115,7 +116,8 @@ struct xfs_rtgroup;
 
 #define XFS_SICK_RG_PRIMARY    (XFS_SICK_RG_SUPER | \
                                 XFS_SICK_RG_BITMAP | \
-                                XFS_SICK_RG_SUMMARY)
+                                XFS_SICK_RG_SUMMARY | \
+                                XFS_SICK_RG_RMAPBT)
 
 #define XFS_SICK_AG_PRIMARY    (XFS_SICK_AG_SB | \
                                 XFS_SICK_AG_AGF | \
index c40b02be0f41b97fc8671aa15cfbe427565ebb7e..7e69b6bf96f1ac411b212173448bd22d8b0aef33 100644 (file)
@@ -354,6 +354,7 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
        [XFS_RTGI_RMAP] = {
                .name           = "rmap",
                .metafile_type  = XFS_METAFILE_RTRMAP,
+               .sick           = XFS_SICK_RG_RMAPBT,
                .fmt_mask       = 1U << XFS_DINODE_FMT_META_BTREE,
                /*
                 * growfs must create the rtrmap inodes before adding a
index a14f2bec8aaa526cd81a49324a29b48f09c3e031..387c9f17118d521ef3d784c36ea26e5d81c9552f 100644 (file)
@@ -25,6 +25,7 @@
 #include "xfs_cksum.h"
 #include "xfs_rtgroup.h"
 #include "xfs_bmap.h"
+#include "xfs_health.h"
 
 static struct kmem_cache       *xfs_rtrmapbt_cur_cache;
 
@@ -494,6 +495,7 @@ const struct xfs_btree_ops xfs_rtrmapbt_ops = {
 
        .lru_refs               = XFS_RMAP_BTREE_REF,
        .statoff                = XFS_STATS_CALC_INDEX(xs_rtrmap_2),
+       .sick_mask              = XFS_SICK_RG_RMAPBT,
 
        .dup_cursor             = xfs_rtrmapbt_dup_cursor,
        .alloc_block            = xfs_btree_alloc_metafile_block,
@@ -753,16 +755,20 @@ xfs_iformat_rtrmap(
         * growfs must create the rtrmap inodes before adding a realtime volume
         * to the filesystem, so we cannot use the rtrmapbt predicate here.
         */
-       if (!xfs_has_rmapbt(ip->i_mount))
+       if (!xfs_has_rmapbt(ip->i_mount)) {
+               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
                return -EFSCORRUPTED;
+       }
 
        dsize = XFS_DFORK_SIZE(dip, mp, XFS_DATA_FORK);
        numrecs = be16_to_cpu(dfp->bb_numrecs);
        level = be16_to_cpu(dfp->bb_level);
 
        if (level > mp->m_rtrmap_maxlevels ||
-           xfs_rtrmap_droot_space_calc(level, numrecs) > dsize)
+           xfs_rtrmap_droot_space_calc(level, numrecs) > dsize) {
+               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
                return -EFSCORRUPTED;
+       }
 
        broot = xfs_broot_alloc(xfs_ifork_ptr(ip, XFS_DATA_FORK),
                        xfs_rtrmap_broot_space_calc(mp, level, numrecs));