From 4d099c7869b3a9b70bee32d96ce287a2e3eacf90 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 15 Oct 2024 12:44:35 -0700 Subject: [PATCH] xfs: report realtime rmap btree corruption errors to the health system 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 --- libxfs/xfs_btree.h | 2 +- libxfs/xfs_fs.h | 1 + libxfs/xfs_health.h | 4 +++- libxfs/xfs_inode_fork.c | 4 +++- libxfs/xfs_rtgroup.c | 1 + libxfs/xfs_rtrmap_btree.c | 6 +++++- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h index 1454d8b41..99624cd8b 100644 --- a/libxfs/xfs_btree.h +++ b/libxfs/xfs_btree.h @@ -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 */ diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 41ce4d3d6..7cca458ff 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -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 diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h index d34986ac1..5c8a0aff6 100644 --- a/libxfs/xfs_health.h +++ b/libxfs/xfs_health.h @@ -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 | \ diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c index ea06655d9..ef4f52603 100644 --- a/libxfs/xfs_inode_fork.c +++ b/libxfs/xfs_inode_fork.c @@ -273,8 +273,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__, diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c index c8b3ae7af..441f6d97e 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -365,6 +365,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 diff --git a/libxfs/xfs_rtrmap_btree.c b/libxfs/xfs_rtrmap_btree.c index 323fe99d5..d4674e39b 100644 --- a/libxfs/xfs_rtrmap_btree.c +++ b/libxfs/xfs_rtrmap_btree.c @@ -26,6 +26,7 @@ #include "xfs_group.h" #include "xfs_rtgroup.h" #include "xfs_bmap.h" +#include "xfs_health.h" static struct kmem_cache *xfs_rtrmapbt_cur_cache; @@ -497,6 +498,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, @@ -757,8 +759,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; + } broot = xfs_broot_realloc(xfs_ifork_ptr(ip, XFS_DATA_FORK), xfs_rtrmap_broot_space_calc(mp, level, numrecs)); -- 2.50.1