summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 11:19:43 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-17 18:55:24 -0700
commitde4cfc3f472289fdae99ea8f78901f36c3513483 (patch)
treed4c6d26af1a2be02aa1e9191c2cf83b1a9684540
parent0276aeeda0035cc21ae1ca1a99e814fee6ac104b (diff)
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 <djwong@kernel.org>
-rw-r--r--fs/xfs/libxfs/xfs_fs.h1
-rw-r--r--fs/xfs/libxfs/xfs_health.h4
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c4
-rw-r--r--fs/xfs/xfs_health.c4
-rw-r--r--fs/xfs/xfs_rtalloc.c1
5 files changed, 12 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index efdfaff00384..953e3a386550 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -212,6 +212,7 @@ struct xfs_fsop_geom {
#define XFS_FSOP_GEOM_SICK_RT_SUMMARY (1 << 5) /* realtime summary */
#define XFS_FSOP_GEOM_SICK_QUOTACHECK (1 << 6) /* quota counts */
#define XFS_FSOP_GEOM_SICK_RT_RMAPBT (1 << 7) /* realtime rmapbt */
+#define XFS_FSOP_GEOM_SICK_RT_REFCNTBT (1 << 8) /* realtime refcountbt */
/* Output for XFS_FS_COUNTS */
typedef struct xfs_fsop_counts {
diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h
index 968fd6c389d7..2619f34ff965 100644
--- a/fs/xfs/libxfs/xfs_health.h
+++ b/fs/xfs/libxfs/xfs_health.h
@@ -64,6 +64,7 @@ struct xfs_da_args;
#define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */
#define XFS_SICK_RT_SUMMARY (1 << 1) /* realtime summary */
#define XFS_SICK_RT_RMAPBT (1 << 2) /* realtime rmapbt */
+#define XFS_SICK_RT_REFCNTBT (1 << 3) /* realtime refcountbt */
/* Observable health issues for AG metadata. */
#define XFS_SICK_AG_SB (1 << 0) /* superblock */
@@ -99,7 +100,8 @@ struct xfs_da_args;
#define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \
XFS_SICK_RT_SUMMARY | \
- XFS_SICK_RT_RMAPBT)
+ XFS_SICK_RT_RMAPBT | \
+ XFS_SICK_RT_REFCNTBT)
#define XFS_SICK_AG_PRIMARY (XFS_SICK_AG_SB | \
XFS_SICK_AG_AGF | \
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 9d7c0302c424..f1d62db45b1b 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -267,8 +267,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/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c
index 5d07eca12981..4edba222e94d 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -366,6 +366,7 @@ static const struct ioctl_sick_map rt_map[] = {
{ XFS_SICK_RT_BITMAP, XFS_FSOP_GEOM_SICK_RT_BITMAP },
{ XFS_SICK_RT_SUMMARY, XFS_FSOP_GEOM_SICK_RT_SUMMARY },
{ XFS_SICK_RT_RMAPBT, XFS_FSOP_GEOM_SICK_RT_RMAPBT },
+ { XFS_SICK_RT_REFCNTBT, XFS_FSOP_GEOM_SICK_RT_REFCNTBT },
{ 0, 0 },
};
@@ -515,6 +516,9 @@ xfs_btree_mark_sick(
case XFS_BTNUM_RTRMAP:
xfs_rt_mark_sick(cur->bc_mp, XFS_SICK_RT_RMAPBT);
return;
+ case XFS_BTNUM_RTREFC:
+ xfs_rt_mark_sick(cur->bc_mp, XFS_SICK_RT_REFCNTBT);
+ return;
case XFS_BTNUM_BNO:
mask = XFS_SICK_AG_BNOBT;
break;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 0297d1e4da5d..15f5a405d7d4 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1514,6 +1514,7 @@ xfs_rtmount_inodes(
if (XFS_IS_CORRUPT(mp,
mp->m_rrefcountip->i_df.if_format !=
XFS_DINODE_FMT_REFCOUNT)) {
+ xfs_rt_mark_sick(mp, XFS_SICK_RT_REFCNTBT);
error = -EFSCORRUPTED;
goto out_rrefcount;
}