]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: report realtime rmap btree corruption errors to the health system
authorDarrick J. Wong <djwong@kernel.org>
Thu, 15 Aug 2024 18:48:58 +0000 (11:48 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 16 Aug 2024 21:54:25 +0000 (14:54 -0700)
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>
fs/xfs/libxfs/xfs_btree.h
fs/xfs/libxfs/xfs_fs.h
fs/xfs/libxfs/xfs_health.h
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_rtgroup.c
fs/xfs/libxfs/xfs_rtrmap_btree.c
fs/xfs/xfs_health.c

index 85cf533093ceb2e8390bf9a691b104779949e1be..a2a7c11e86bd0638e4027bd6d530ab61540b7b19 100644 (file)
@@ -136,7 +136,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 11fa3d0c38086d3d9dbff162b9b3fc12bddb7fde..3c6fc5bbae06d3ffd9caa036435441259897011d 100644 (file)
@@ -990,6 +990,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 2da64555434d5a9c81ee13d939e2a1459dfbc1d2..87b38d0bcb310cc47ebb8817d6477a124f1618da 100644 (file)
@@ -68,6 +68,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 */
@@ -113,7 +114,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 ae25b1bc81c659b067ffc896040db057d8edec23..681ee1e5cdd55327b7db74c5c6aeaf08ff81da92 100644 (file)
@@ -275,8 +275,10 @@ xfs_iformat_data_fork(
                         * 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;
+                       }
                        return xfs_iformat_rtrmap(ip, dip);
                default:
                        xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
index 56b8f37ea2a13feb618b9a428fca6ab4fc2cc3ea..4f0215273e821688fee031763d74828b106e774b 100644 (file)
@@ -396,6 +396,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_RMAP,
                /*
                 * growfs must create the rtrmap inodes before adding a
index b4b316ecd972dce70256565b1397fe1ba9e49663..edfc1b6bff6f6ead84e3d06d4b688d99f620c210 100644 (file)
@@ -27,6 +27,7 @@
 #include "xfs_extent_busy.h"
 #include "xfs_rtgroup.h"
 #include "xfs_bmap.h"
+#include "xfs_health.h"
 
 static struct kmem_cache       *xfs_rtrmapbt_cur_cache;
 
@@ -478,6 +479,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,
@@ -737,8 +739,10 @@ xfs_iformat_rtrmap(
        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;
+       }
 
        xfs_iroot_alloc(ip, XFS_DATA_FORK,
                        xfs_rtrmap_broot_space_calc(mp, level, numrecs));
index b3d288df4ca20173d83ab5f6114638f68b08ee7f..86fa4c15fba506a04ccae23f2d9368fea5cb73d2 100644 (file)
@@ -489,6 +489,7 @@ static const struct ioctl_sick_map rtgroup_map[] = {
        { XFS_SICK_RG_SUPER,    XFS_RTGROUP_GEOM_SICK_SUPER },
        { XFS_SICK_RG_BITMAP,   XFS_RTGROUP_GEOM_SICK_BITMAP },
        { XFS_SICK_RG_SUMMARY,  XFS_RTGROUP_GEOM_SICK_SUMMARY },
+       { XFS_SICK_RG_RMAPBT,   XFS_RTGROUP_GEOM_SICK_RMAPBT },
 };
 
 /* Fill out rtgroup geometry health info. */
@@ -596,7 +597,11 @@ xfs_btree_mark_sick(
                                           cur->bc_ino.whichfork);
                        return;
                }
-               fallthrough;
+
+               /* The only non-bmap inode btrees are rtgroup metadata */
+               ASSERT(cur->bc_ops->sick_mask);
+               xfs_rtgroup_mark_sick(cur->bc_ino.rtg, cur->bc_ops->sick_mask);
+               return;
        default:
                ASSERT(0);
                return;