@@ -313,6 +313,7 @@ struct xfs_rtgroup_geometry {
};
#define XFS_RTGROUP_GEOM_SICK_SUPER (1 << 0) /* superblock */
#define XFS_RTGROUP_GEOM_SICK_BITMAP (1 << 1) /* rtbitmap for this group */
+#define XFS_RTGROUP_GEOM_SICK_RMAPBT (1 << 2) /* reverse mappings */
/*
* Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
@@ -67,6 +67,7 @@ struct xfs_rtgroup;
#define XFS_SICK_RT_BITMAP (1 << 0) /* realtime bitmap */
#define XFS_SICK_RT_SUMMARY (1 << 1) /* realtime summary */
#define XFS_SICK_RT_SUPER (1 << 2) /* rt group superblock */
+#define XFS_SICK_RT_RMAPBT (1 << 3) /* reverse mappings */
/* Observable health issues for AG metadata. */
#define XFS_SICK_AG_SB (1 << 0) /* superblock */
@@ -104,7 +105,8 @@ struct xfs_rtgroup;
#define XFS_SICK_RT_PRIMARY (XFS_SICK_RT_BITMAP | \
XFS_SICK_RT_SUMMARY | \
- XFS_SICK_RT_SUPER)
+ XFS_SICK_RT_SUPER | \
+ XFS_SICK_RT_RMAPBT)
#define XFS_SICK_AG_PRIMARY (XFS_SICK_AG_SB | \
XFS_SICK_AG_AGF | \
@@ -261,8 +261,10 @@ xfs_iformat_data_fork(
case XFS_DINODE_FMT_BTREE:
return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
case XFS_DINODE_FMT_RMAP:
- if (!xfs_has_rtrmapbt(ip->i_mount))
+ if (!xfs_has_rtrmapbt(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__,
@@ -28,6 +28,7 @@
#include "xfs_rtgroup.h"
#include "xfs_bmap.h"
#include "xfs_imeta.h"
+#include "xfs_health.h"
static struct kmem_cache *xfs_rtrmapbt_cur_cache;
@@ -800,8 +801,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;
+ }
xfs_iroot_alloc(ip, XFS_DATA_FORK,
xfs_rtrmap_broot_space_calc(mp, level, numrecs));
@@ -531,6 +531,7 @@ xfs_ag_geom_health(
static const struct ioctl_sick_map rtgroup_map[] = {
{ XFS_SICK_RT_SUPER, XFS_RTGROUP_GEOM_SICK_SUPER },
{ XFS_SICK_RT_BITMAP, XFS_RTGROUP_GEOM_SICK_BITMAP },
+ { XFS_SICK_RT_RMAPBT, XFS_RTGROUP_GEOM_SICK_RMAPBT },
{ 0, 0 },
};
@@ -630,6 +631,9 @@ xfs_btree_mark_sick(
case XFS_BTNUM_BMAP:
xfs_bmap_mark_sick(cur->bc_ino.ip, cur->bc_ino.whichfork);
return;
+ case XFS_BTNUM_RTRMAP:
+ xfs_rtgroup_mark_sick(cur->bc_ino.rtg, XFS_SICK_RT_RMAPBT);
+ return;
case XFS_BTNUM_BNO:
mask = XFS_SICK_AG_BNOBT;
break;
@@ -1806,6 +1806,7 @@ xfs_rtmount_rmapbt(
goto out_path;
if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_RMAP)) {
+ xfs_rtgroup_mark_sick(rtg, XFS_SICK_RT_RMAPBT);
error = -EFSCORRUPTED;
goto out_rele;
}