]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: report realtime refcount btree corruption errors to the health system
authorDarrick J. Wong <djwong@kernel.org>
Thu, 15 Aug 2024 18:49:36 +0000 (11:49 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 16 Aug 2024 21:57:43 +0000 (14:57 -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>
libxfs/xfs_fs.h
libxfs/xfs_health.h
libxfs/xfs_inode_fork.c
libxfs/xfs_refcount.c
libxfs/xfs_rtgroup.c
libxfs/xfs_rtrefcount_btree.c

index a89f4261a9838bacd361772654fb87b0ccff1413..99d4a03c34d7b5ce02c704dbb84d21db9d726576 100644 (file)
@@ -993,6 +993,7 @@ struct xfs_rtgroup_geometry {
 #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 */
+#define XFS_RTGROUP_GEOM_SICK_REFCNTBT (1U << 4)  /* reference counts */
 
 /*
  * ioctl commands that are used by Linux filesystems
index 87b38d0bcb310cc47ebb8817d6477a124f1618da..65a4af590d05dc4e1c71ede04ce0ee4a992e6dda 100644 (file)
@@ -69,6 +69,7 @@ struct xfs_rtgroup;
 #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 */
+#define XFS_SICK_RG_REFCNTBT   (1 << 4)  /* reference counts */
 
 /* 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_RMAPBT)
+                                XFS_SICK_RG_RMAPBT | \
+                                XFS_SICK_RG_REFCNTBT)
 
 #define XFS_SICK_AG_PRIMARY    (XFS_SICK_AG_SB | \
                                 XFS_SICK_AG_AGF | \
index 39cf5ef466c9c69e890b8a498a729ec8c509be6f..bffcb05ba167cfb5ca3af29fbcf195e70a01b65e 100644 (file)
@@ -281,8 +281,10 @@ xfs_iformat_data_fork(
                        return xfs_iformat_rtrmap(ip, dip);
                case XFS_DINODE_FMT_REFCOUNT:
                        /* same comment about growfs and rmap inodes applies */
-                       if (!xfs_has_reflink(ip->i_mount))
+                       if (!xfs_has_reflink(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 bc759e7db3bce622cc4c38aa12a37a26f0f792b2..e5035bb8a8f7f483e08d63e8b6cf4483f25cc488 100644 (file)
@@ -2194,6 +2194,8 @@ xfs_refcount_recover_rtcow_leftovers(
        struct xfs_mount                *mp,
        struct xfs_rtgroup              *rtg)
 {
+       if (!xfs_has_rtgroups(mp))
+               return 0;
        return xfs_refcount_recover_group_cow_leftovers(mp, NULL, rtg);
 }
 
index 3f1fdd4d373bbc45e06e6248a6b9a1dd6fd0cf51..36e193d307dfd15bd2ee3dd15bf2c83c4daded59 100644 (file)
@@ -429,6 +429,7 @@ static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
        [XFS_RTGI_REFCOUNT] = {
                .name           = "refcount",
                .metafile_type  = XFS_METAFILE_RTREFCOUNT,
+               .sick           = XFS_SICK_RG_REFCNTBT,
                .fmt_mask       = 1U << XFS_DINODE_FMT_REFCOUNT,
                /* same comment about growfs and rmap inodes applies here */
                .enabled        = xfs_has_reflink,
index ed6ef03566b44a18b45e8a20e6d092b6c16596f8..1b98570e6da16021b83513333832f61e4f208132 100644 (file)
@@ -25,6 +25,7 @@
 #include "xfs_rtgroup.h"
 #include "xfs_rtbitmap.h"
 #include "xfs_metafile.h"
+#include "xfs_health.h"
 
 static struct kmem_cache       *xfs_rtrefcountbt_cur_cache;
 
@@ -358,6 +359,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_metafile_block,
@@ -625,8 +627,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));