summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2022-07-14 11:16:11 -0700
committerDarrick J. Wong <djwong@kernel.org>2022-10-14 14:17:25 -0700
commit4ebe8dbdf60bc1f6d46b600447649c06575ddb9f (patch)
tree00071df7ec74ee5a8b1fade7ffbe4c4bb624ea55
parent8fb03d32ddda1f4bffce455764bcd68a43d8fa56 (diff)
xfs: check new rtbitmap records against rt refcount btree
When we're rebuilding the realtime bitmap, check the proposed free extents against the rt refcount btree to make sure we don't commit any grievous errors. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/scrub/repair.c7
-rw-r--r--fs/xfs/scrub/rtbitmap_repair.c21
2 files changed, 28 insertions, 0 deletions
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index 55acb8f46098..3e70c5252d91 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -40,6 +40,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"
@@ -977,6 +978,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);
}
/*
diff --git a/fs/xfs/scrub/rtbitmap_repair.c b/fs/xfs/scrub/rtbitmap_repair.c
index 0fa8942d14e7..3fdd06acfa99 100644
--- a/fs/xfs/scrub/rtbitmap_repair.c
+++ b/fs/xfs/scrub/rtbitmap_repair.c
@@ -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"
@@ -447,6 +448,7 @@ xrep_rgbitmap_mark_free(
unsigned int bufwsize;
xfs_extlen_t mod;
xfs_rtword_t mask;
+ enum xfs_btree_keyfill keyfill;
int error;
if (!xfs_verify_rgbext(rtg, rb->next_rgbno, rgbno - rb->next_rgbno))
@@ -466,6 +468,25 @@ xrep_rgbitmap_mark_free(
if (mod != mp->m_sb.sb_rextsize - 1)
return -EFSCORRUPTED;
+ /* Must not be shared or CoW staging. */
+ if (rb->sc->sr.refc_cur) {
+ error = xfs_refcount_scan_keyfill(rb->sc->sr.refc_cur,
+ XFS_RCDOM_SHARED, rb->next_rgbno,
+ rgbno - rb->next_rgbno, &keyfill);
+ if (error)
+ return error;
+ if (keyfill != XFS_BTREE_KEYFILL_EMPTY)
+ return -EFSCORRUPTED;
+
+ error = xfs_refcount_scan_keyfill(rb->sc->sr.refc_cur,
+ XFS_RCDOM_COW, rb->next_rgbno,
+ rgbno - rb->next_rgbno, &keyfill);
+ if (error)
+ return error;
+ if (keyfill != XFS_BTREE_KEYFILL_EMPTY)
+ return -EFSCORRUPTED;
+ }
+
trace_xrep_rgbitmap_record_free(mp, startrtx, nextrtx - 1);
/* Set bits as needed to round startrtx up to the nearest word. */