@@ -42,6 +42,7 @@
#include "xfs_rtgroup.h"
#include "xfs_rtalloc.h"
#include "xfs_metafile.h"
+#include "xfs_rtrefcount_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -1009,6 +1010,11 @@ xrep_rtgroup_btcur_init(
(sr->rtlock_flags & XFS_RTGLOCK_RMAP) &&
xfs_has_rtrmapbt(mp))
sr->rmap_cur = xfs_rtrmapbt_init_cursor(sc->tp, sr->rtg);
+
+ 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(sc->tp, sr->rtg);
}
/*
@@ -23,6 +23,7 @@
#include "xfs_rtbitmap.h"
#include "xfs_rtgroup.h"
#include "xfs_extent_busy.h"
+#include "xfs_refcount.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -183,7 +184,8 @@ xrep_rtbitmap_mark_free(
xfs_rgblock_t rgbno)
{
struct xfs_mount *mp = rtb->sc->mp;
- struct xfs_rtgroup *rtg = rtb->sc->sr.rtg;
+ struct xchk_rt *sr = &rtb->sc->sr;
+ struct xfs_rtgroup *rtg = sr->rtg;
xfs_rtxnum_t startrtx;
xfs_rtxnum_t nextrtx;
xrep_wordoff_t wordoff, nextwordoff;
@@ -191,6 +193,7 @@ xrep_rtbitmap_mark_free(
unsigned int bufwsize;
xfs_extlen_t mod;
xfs_rtword_t mask;
+ enum xbtree_recpacking outcome;
int error;
if (!xfs_verify_rgbext(rtg, rtb->next_rgbno, rgbno - rtb->next_rgbno))
@@ -210,6 +213,25 @@ xrep_rtbitmap_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, rtb->next_rgbno,
+ rgbno - rtb->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, rtb->next_rgbno,
+ rgbno - rtb->next_rgbno, &outcome);
+ if (error)
+ return error;
+ if (outcome != XBTREE_RECPACKING_EMPTY)
+ return -EFSCORRUPTED;
+ }
+
trace_xrep_rtbitmap_record_free(mp, startrtx, nextrtx - 1);
/* Set bits as needed to round startrtx up to the nearest word. */