@@ -41,6 +41,7 @@
#include "xfs_rtgroup.h"
#include "xfs_rtalloc.h"
#include "xfs_imeta.h"
+#include "xfs_rtrefcount_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -1008,6 +1009,12 @@ xrep_rtgroup_btcur_init(
xfs_has_rtrmapbt(mp))
sr->rmap_cur = xfs_rtrmapbt_init_cursor(mp, sc->tp, sr->rtg,
sr->rtg->rtg_rmapip);
+
+ if (sc->sm->sm_type != XFS_SCRUB_TYPE_RTREFCBT &&
+ (sr->rtlock_flags & XFS_RTGLOCK_REFCOUNT) &&
+ xfs_has_rtreflink(mp))
+ sr->refc_cur = xfs_rtrefcountbt_init_cursor(mp, sc->tp,
+ sr->rtg, sr->rtg->rtg_refcountip);
}
/*
@@ -22,6 +22,7 @@
#include "xfs_swapext.h"
#include "xfs_rtbitmap.h"
#include "xfs_rtgroup.h"
+#include "xfs_refcount.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -418,7 +419,8 @@ xrep_rgbitmap_mark_free(
xfs_rgblock_t rgbno)
{
struct xfs_mount *mp = rgb->sc->mp;
- struct xfs_rtgroup *rtg = rgb->sc->sr.rtg;
+ struct xchk_rt *sr = &rgb->sc->sr;
+ struct xfs_rtgroup *rtg = sr->rtg;
xfs_rtblock_t rtbno;
xfs_rtxnum_t startrtx;
xfs_rtxnum_t nextrtx;
@@ -427,6 +429,7 @@ xrep_rgbitmap_mark_free(
unsigned int bufwsize;
xfs_extlen_t mod;
xfs_rtword_t mask;
+ enum xbtree_recpacking outcome;
int error;
if (!xfs_verify_rgbext(rtg, rgb->next_rgbno, rgbno - rgb->next_rgbno))
@@ -446,6 +449,25 @@ xrep_rgbitmap_mark_free(
if (mod != mp->m_sb.sb_rextsize - 1)
return -EFSCORRUPTED;
+ /* Must not be shared or CoW staging. */
+ if (sr->refc_cur) {
+ error = xfs_refcount_has_records(sr->refc_cur,
+ XFS_REFC_DOMAIN_SHARED, rgb->next_rgbno,
+ rgbno - rgb->next_rgbno, &outcome);
+ if (error)
+ return error;
+ if (outcome != XBTREE_RECPACKING_EMPTY)
+ return -EFSCORRUPTED;
+
+ error = xfs_refcount_has_records(sr->refc_cur,
+ XFS_REFC_DOMAIN_COW, rgb->next_rgbno,
+ rgbno - rgb->next_rgbno, &outcome);
+ if (error)
+ return error;
+ if (outcome != XBTREE_RECPACKING_EMPTY)
+ return -EFSCORRUPTED;
+ }
+
trace_xrep_rgbitmap_record_free(mp, startrtx, nextrtx - 1);
/* Set bits as needed to round startrtx up to the nearest word. */