]> www.infradead.org Git - users/hch/xfs.git/commitdiff
xfs: report realtime refcount btree corruption errors to the health system
authorDarrick J. Wong <djwong@kernel.org>
Wed, 29 May 2024 04:13:21 +0000 (21:13 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 24 Jul 2024 05:33:56 +0000 (22:33 -0700)
Whenever we encounter corrupt realtime refcount 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_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_rtrefcount_btree.c
fs/xfs/xfs_health.c

index efee03ca1b6438eec57f3ecf489c815094a138c8..62d916cc5c5589d37d01b92263d925597b5831a7 100644 (file)
@@ -991,6 +991,7 @@ struct xfs_rtgroup_geometry {
 #define XFS_RTGROUP_GEOM_SICK_SUPER    (1U << 0)  /* superblock */
 #define XFS_RTGROUP_GEOM_SICK_BITMAP   (1U << 1)  /* rtbitmap for this group */
 #define XFS_RTGROUP_GEOM_SICK_RMAPBT   (1U << 2)  /* reverse mappings */
+#define XFS_RTGROUP_GEOM_SICK_REFCNTBT (1U << 3)  /* reference counts */
 
 /*
  * ioctl commands that are used by Linux filesystems
index c03a42032d7fad63ba8a3de6fbff7102cb7c6f29..89b80e957917e8df7d322c3f1832f48556eb8e84 100644 (file)
@@ -72,6 +72,7 @@ struct xfs_rtgroup;
 #define XFS_SICK_RG_SUPER      (1 << 0)  /* rt group superblock */
 #define XFS_SICK_RG_BITMAP     (1 << 1)  /* rt group part of rtbitmap */
 #define XFS_SICK_RG_RMAPBT     (1 << 2)  /* reverse mappings */
+#define XFS_SICK_RG_REFCNTBT   (1 << 3)  /* reference counts */
 
 /* Observable health issues for AG metadata. */
 #define XFS_SICK_AG_SB         (1 << 0)  /* superblock */
@@ -120,7 +121,8 @@ struct xfs_rtgroup;
 
 #define XFS_SICK_RG_PRIMARY    (XFS_SICK_RG_SUPER | \
                                 XFS_SICK_RG_BITMAP | \
-                                XFS_SICK_RG_RMAPBT)
+                                XFS_SICK_RG_RMAPBT | \
+                                XFS_SICK_RG_REFCNTBT)
 
 #define XFS_SICK_AG_PRIMARY    (XFS_SICK_AG_SB | \
                                 XFS_SICK_AG_AGF | \
index 7c1ab95788e07997e7ad949e6229cb3f37133585..b677c6a91563b3bb2549bcf8ec9f51023a8ff272 100644 (file)
@@ -277,8 +277,10 @@ xfs_iformat_data_fork(
                        }
                        return xfs_iformat_rtrmap(ip, dip);
                case XFS_DINODE_FMT_REFCOUNT:
-                       if (!xfs_has_rtreflink(ip->i_mount))
+                       if (!xfs_has_rtreflink(ip->i_mount)) {
+                               xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
                                return -EFSCORRUPTED;
+                       }
                        return xfs_iformat_rtrefcount(ip, dip);
                default:
                        xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
index c337118f45438068ebf6f5185a89a1c876ed4cbe..dd9c2ebaccff127e1e473df93a3dfbca94c800c1 100644 (file)
@@ -581,6 +581,7 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTG_MAX] = {
        [XFS_RTG_REFCOUNT] = {
                .name           = "refcount",
                .format         = XFS_DINODE_FMT_REFCOUNT,
+               .sick           = XFS_SICK_RG_REFCNTBT,
                .enabled        = xfs_has_rtreflink,
                .create         = xfs_rtrefcountbt_create,
        },
index 46d23e04f6fbec63f9b96abf095b0d4e66aa040c..d70dd48ee00075871538a83ac400c97b291d85b5 100644 (file)
@@ -27,6 +27,7 @@
 #include "xfs_rtgroup.h"
 #include "xfs_rtbitmap.h"
 #include "xfs_imeta.h"
+#include "xfs_health.h"
 
 static struct kmem_cache       *xfs_rtrefcountbt_cur_cache;
 
@@ -360,6 +361,7 @@ const struct xfs_btree_ops xfs_rtrefcountbt_ops = {
 
        .lru_refs               = XFS_REFC_BTREE_REF,
        .statoff                = XFS_STATS_CALC_INDEX(xs_rtrefcbt_2),
+       .sick_mask              = XFS_SICK_RG_REFCNTBT,
 
        .dup_cursor             = xfs_rtrefcountbt_dup_cursor,
        .alloc_block            = xfs_btree_alloc_imeta_block,
@@ -627,8 +629,10 @@ xfs_iformat_rtrefcount(
        level = be16_to_cpu(dfp->bb_level);
 
        if (level > mp->m_rtrefc_maxlevels ||
-           xfs_rtrefcount_droot_space_calc(level, numrecs) > dsize)
+           xfs_rtrefcount_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_rtrefcount_broot_space_calc(mp, level, numrecs));
index 41230ea2d201e227410f37a882d8622d43889d59..33059d979857ad7827c7f82b88b372f36d4a3bac 100644 (file)
@@ -551,6 +551,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_RMAPBT,   XFS_RTGROUP_GEOM_SICK_RMAPBT },
+       { XFS_SICK_RG_REFCNTBT, XFS_RTGROUP_GEOM_SICK_REFCNTBT },
        { 0, 0 },
 };