summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-01-05 17:47:07 -0800
committerDarrick J. Wong <djwong@kernel.org>2021-03-25 17:08:51 -0700
commit88bf463ea9b07365ad61d2cef1ca9d3c5ee650e7 (patch)
tree29f03ecb587df6b4315421f149967122cbb46066
parentc2e32ee66600eb06b45f816e3e38e6722a347638 (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 f45358df4b94..f696a8c8136b 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 b9404c01b329..ac8a95342b9b 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -270,8 +270,10 @@ xfs_iformat_data_fork(
}
return xfs_iformat_rtrmap(ip, dip);
case XFS_DINODE_FMT_REFCOUNT:
- if (!xfs_sb_version_hasrtreflink(&ip->i_mount->m_sb))
+ if (!xfs_sb_version_hasrtreflink(&ip->i_mount->m_sb)) {
+ 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 dbcf95407c4a..6da36068f9ca 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -359,6 +359,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 },
};
@@ -508,6 +509,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 299eb1c77384..a4ee08e5d734 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1369,6 +1369,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;
}