From 3a0cf8af13ef1c70e15b38d06fc1238d50d0c65d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 3 Jul 2024 14:22:31 -0700 Subject: [PATCH] xfs: report realtime refcount btree corruption errors to the health system 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 --- libxfs/xfs_fs.h | 1 + libxfs/xfs_health.h | 4 +++- libxfs/xfs_inode_fork.c | 4 +++- libxfs/xfs_rtrefcount_btree.c | 6 +++++- man/man2/ioctl_xfs_rtgroup_geometry.2 | 3 +++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 51a4bff11..5351a253c 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -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 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 diff --git a/libxfs/xfs_health.h b/libxfs/xfs_health.h index c03a42032..89b80e957 100644 --- a/libxfs/xfs_health.h +++ b/libxfs/xfs_health.h @@ -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 | \ diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c index 88d36cd07..eb58647f1 100644 --- a/libxfs/xfs_inode_fork.c +++ b/libxfs/xfs_inode_fork.c @@ -275,8 +275,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__, diff --git a/libxfs/xfs_rtrefcount_btree.c b/libxfs/xfs_rtrefcount_btree.c index 4dcfd20c4..76fcd6ede 100644 --- a/libxfs/xfs_rtrefcount_btree.c +++ b/libxfs/xfs_rtrefcount_btree.c @@ -25,6 +25,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; @@ -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_imeta_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)); diff --git a/man/man2/ioctl_xfs_rtgroup_geometry.2 b/man/man2/ioctl_xfs_rtgroup_geometry.2 index 26cfb5a38..4edaa15db 100644 --- a/man/man2/ioctl_xfs_rtgroup_geometry.2 +++ b/man/man2/ioctl_xfs_rtgroup_geometry.2 @@ -74,6 +74,9 @@ Realtime bitmap for this group. .TP .B XFS_RTGROUP_GEOM_SICK_RTRMAPBT Reverse mapping btree for this group. +.TP +.B XFS_RTGROUP_GEOM_SICK_REFCNTBT +Reference count btree for this group. .RE .SH RETURN VALUE On error, \-1 is returned, and -- 2.50.1