* [PATCH 1/4] xfs: cross-reference rmap records with ag btrees
2022-10-02 18:20 [PATCHSET v23.1 0/4] xfs: strengthen rmapbt scrubbing Darrick J. Wong
@ 2022-10-02 18:20 ` Darrick J. Wong
2022-10-02 18:20 ` [PATCH 3/4] xfs: cross-reference rmap records with inode btrees Darrick J. Wong
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2022-10-02 18:20 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Strengthen the rmap btree record checker a little more by comparing
OWN_FS and OWN_LOG reverse mappings against the AG headers and internal
logs, respectively.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/Makefile | 2 -
fs/xfs/scrub/bitmap.c | 22 +++++++
fs/xfs/scrub/bitmap.h | 1
fs/xfs/scrub/rmap.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 183 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 03135a1c31b6..7b54cdbe8c9c 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -145,6 +145,7 @@ xfs-y += $(addprefix scrub/, \
agheader.o \
alloc.o \
attr.o \
+ bitmap.o \
bmap.o \
btree.o \
common.o \
@@ -168,7 +169,6 @@ xfs-$(CONFIG_XFS_QUOTA) += scrub/quota.o
ifeq ($(CONFIG_XFS_ONLINE_REPAIR),y)
xfs-y += $(addprefix scrub/, \
agheader_repair.o \
- bitmap.o \
repair.o \
)
endif
diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c
index 1b04d2ce020a..14caff0a28ce 100644
--- a/fs/xfs/scrub/bitmap.c
+++ b/fs/xfs/scrub/bitmap.c
@@ -396,3 +396,25 @@ xbitmap_empty(
{
return bitmap->xb_root.rb_root.rb_node == NULL;
}
+
+/* Is the start of the range set or clear? And for how long? */
+bool
+xbitmap_test(
+ struct xbitmap *bitmap,
+ uint64_t start,
+ uint64_t *len)
+{
+ struct xbitmap_node *bn;
+ uint64_t last = start + *len - 1;
+
+ bn = xbitmap_tree_iter_first(&bitmap->xb_root, start, last);
+ if (!bn)
+ return false;
+ if (bn->bn_start <= start) {
+ if (bn->bn_last < last)
+ *len = bn->bn_last - start + 1;
+ return true;
+ }
+ *len = bn->bn_start - start;
+ return false;
+}
diff --git a/fs/xfs/scrub/bitmap.h b/fs/xfs/scrub/bitmap.h
index 7afd64a318d1..2da3d6b87565 100644
--- a/fs/xfs/scrub/bitmap.h
+++ b/fs/xfs/scrub/bitmap.h
@@ -38,5 +38,6 @@ int xbitmap_walk_bits(struct xbitmap *bitmap, xbitmap_walk_bits_fn fn,
void *priv);
bool xbitmap_empty(struct xbitmap *bitmap);
+bool xbitmap_test(struct xbitmap *bitmap, uint64_t start, uint64_t *len);
#endif /* __XFS_SCRUB_BITMAP_H__ */
diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c
index 76ac2279e37d..8205086aac49 100644
--- a/fs/xfs/scrub/rmap.c
+++ b/fs/xfs/scrub/rmap.c
@@ -12,10 +12,12 @@
#include "xfs_btree.h"
#include "xfs_rmap.h"
#include "xfs_refcount.h"
+#include "xfs_ag.h"
+#include "xfs_bit.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
-#include "xfs_ag.h"
+#include "scrub/bitmap.h"
/*
* Set us up to scrub reverse mapping btrees.
@@ -45,6 +47,13 @@ struct xchk_rmap {
* that could be one.
*/
struct xfs_rmap_irec prev_rec;
+
+ /* Bitmaps containing all blocks for each type of AG metadata. */
+ struct xbitmap fs_owned;
+ struct xbitmap log_owned;
+
+ /* Did we complete the AG space metadata bitmaps? */
+ bool bitmaps_complete;
};
/* Cross-reference a rmap against the refcount btree. */
@@ -197,6 +206,68 @@ xchk_rmapbt_check_mergeable(
memcpy(&cr->prev_rec, irec, sizeof(struct xfs_rmap_irec));
}
+/* Compare an rmap for AG metadata against the metadata walk. */
+STATIC int
+xchk_rmapbt_mark_bitmap(
+ struct xchk_btree *bs,
+ struct xchk_rmap *cr,
+ const struct xfs_rmap_irec *irec)
+{
+ struct xfs_scrub *sc = bs->sc;
+ struct xbitmap *bmp = NULL;
+ uint64_t fsbcount = irec->rm_blockcount;
+
+ /*
+ * Skip corrupt records. It is essential that we detect records in the
+ * btree that cannot overlap but do, flag those as CORRUPT, and skip
+ * the bitmap comparison to avoid generating false XCORRUPT reports.
+ */
+ if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
+ return 0;
+
+ /*
+ * If the AG metadata walk didn't complete, there's no point in
+ * comparing against partial results.
+ */
+ if (!cr->bitmaps_complete)
+ return 0;
+
+ switch (irec->rm_owner) {
+ case XFS_RMAP_OWN_FS:
+ bmp = &cr->fs_owned;
+ break;
+ case XFS_RMAP_OWN_LOG:
+ bmp = &cr->log_owned;
+ break;
+ }
+
+ if (!bmp)
+ return 0;
+
+ if (xbitmap_test(bmp, irec->rm_startblock, &fsbcount)) {
+ /*
+ * The start of this reverse mapping corresponds to a set
+ * region in the bitmap. If the mapping covers more area than
+ * the set region, then it covers space that wasn't found by
+ * the AG metadata walk.
+ */
+ if (fsbcount < irec->rm_blockcount)
+ xchk_btree_xref_set_corrupt(bs->sc,
+ bs->sc->sa.rmap_cur, 0);
+ } else {
+ /*
+ * The start of this reverse mapping does not correspond to a
+ * completely set region in the bitmap. The region wasn't
+ * fully set by walking the AG metadata, so this is a
+ * cross-referencing corruption.
+ */
+ xchk_btree_xref_set_corrupt(bs->sc, bs->sc->sa.rmap_cur, 0);
+ }
+
+ /* Unset the region so that we can detect missing rmap records. */
+ return xbitmap_clear(bmp, irec->rm_startblock, irec->rm_blockcount);
+}
+
/* Scrub an rmapbt record. */
STATIC int
xchk_rmapbt_rec(
@@ -272,10 +343,82 @@ xchk_rmapbt_rec(
xchk_rmapbt_check_mergeable(bs, cr, &irec);
xchk_rmapbt_check_overlapping(bs, cr, &irec);
xchk_rmapbt_xref(bs->sc, &irec);
+
+ error = xchk_rmapbt_mark_bitmap(bs, cr, &irec);
out:
return error;
}
+/*
+ * Set up bitmaps mapping all the AG metadata to compare with the rmapbt
+ * records.
+ */
+STATIC int
+xchk_rmapbt_walk_ag_metadata(
+ struct xfs_scrub *sc,
+ struct xchk_rmap *cr)
+{
+ struct xfs_mount *mp = sc->mp;
+ int error;
+
+ /* OWN_FS: AG headers */
+ error = xbitmap_set(&cr->fs_owned, XFS_SB_BLOCK(mp),
+ XFS_AGFL_BLOCK(mp) - XFS_SB_BLOCK(mp) + 1);
+ if (error)
+ goto out;
+
+ /* OWN_LOG: Internal log */
+ if (xfs_ag_contains_log(mp, sc->sa.pag->pag_agno)) {
+ error = xbitmap_set(&cr->log_owned,
+ XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart),
+ mp->m_sb.sb_logblocks);
+ if (error)
+ goto out;
+ }
+
+out:
+ /*
+ * If there's an error, set XFAIL and disable the bitmap
+ * cross-referencing checks, but proceed with the scrub anyway.
+ */
+ if (error)
+ xchk_btree_xref_process_error(sc, sc->sa.rmap_cur,
+ sc->sa.rmap_cur->bc_nlevels - 1, &error);
+ else
+ cr->bitmaps_complete = true;
+ return 0;
+}
+
+/*
+ * Check for set regions in the bitmaps; if there are any, the rmap records do
+ * not describe all the AG metadata.
+ */
+STATIC void
+xchk_rmapbt_check_bitmaps(
+ struct xfs_scrub *sc,
+ struct xchk_rmap *cr)
+{
+ struct xfs_btree_cur *cur = sc->sa.rmap_cur;
+ unsigned int level;
+
+ if (sc->sm->sm_flags & (XFS_SCRUB_OFLAG_CORRUPT |
+ XFS_SCRUB_OFLAG_XFAIL))
+ return;
+ if (!cur)
+ return;
+ level = cur->bc_nlevels - 1;
+
+ /*
+ * Any bitmap with bits still set indicates that the reverse mapping
+ * doesn't cover the entire primary structure.
+ */
+ if (xbitmap_hweight(&cr->fs_owned) != 0)
+ xchk_btree_xref_set_corrupt(sc, cur, level);
+
+ if (xbitmap_hweight(&cr->log_owned) != 0)
+ xchk_btree_xref_set_corrupt(sc, cur, level);
+}
+
/* Scrub the rmap btree for some AG. */
int
xchk_rmapbt(
@@ -288,8 +431,23 @@ xchk_rmapbt(
if (!cr)
return -ENOMEM;
+ xbitmap_init(&cr->fs_owned);
+ xbitmap_init(&cr->log_owned);
+
+ error = xchk_rmapbt_walk_ag_metadata(sc, cr);
+ if (error)
+ goto out;
+
error = xchk_btree(sc, sc->sa.rmap_cur, xchk_rmapbt_rec,
&XFS_RMAP_OINFO_AG, cr);
+ if (error)
+ goto out;
+
+ xchk_rmapbt_check_bitmaps(sc, cr);
+
+out:
+ xbitmap_destroy(&cr->log_owned);
+ xbitmap_destroy(&cr->fs_owned);
kfree(cr);
return error;
}
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/4] xfs: cross-reference rmap records with inode btrees
2022-10-02 18:20 [PATCHSET v23.1 0/4] xfs: strengthen rmapbt scrubbing Darrick J. Wong
2022-10-02 18:20 ` [PATCH 1/4] xfs: cross-reference rmap records with ag btrees Darrick J. Wong
@ 2022-10-02 18:20 ` Darrick J. Wong
2022-10-02 18:20 ` [PATCH 2/4] xfs: cross-reference rmap records with free space btrees Darrick J. Wong
2022-10-02 18:20 ` [PATCH 4/4] xfs: cross-reference rmap records with refcount btrees Darrick J. Wong
3 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2022-10-02 18:20 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Strengthen the rmap btree record checker a little more by comparing
OWN_INOBT reverse mappings against the inode btrees.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/scrub/rmap.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c
index 20a6905c2f0d..fcda958ce1af 100644
--- a/fs/xfs/scrub/rmap.c
+++ b/fs/xfs/scrub/rmap.c
@@ -18,6 +18,7 @@
#include "xfs_bit.h"
#include "xfs_alloc.h"
#include "xfs_alloc_btree.h"
+#include "xfs_ialloc_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
@@ -56,6 +57,7 @@ struct xchk_rmap {
struct xbitmap fs_owned;
struct xbitmap log_owned;
struct xbitmap ag_owned;
+ struct xbitmap inobt_owned;
/* Did we complete the AG space metadata bitmaps? */
bool bitmaps_complete;
@@ -247,6 +249,9 @@ xchk_rmapbt_mark_bitmap(
case XFS_RMAP_OWN_AG:
bmp = &cr->ag_owned;
break;
+ case XFS_RMAP_OWN_INOBT:
+ bmp = &cr->inobt_owned;
+ break;
}
if (!bmp)
@@ -461,6 +466,34 @@ xchk_rmapbt_walk_ag_metadata(
error = xfs_agfl_walk(sc->mp, agf, agfl_bp, xchk_rmapbt_walk_agfl,
&cr->ag_owned);
xfs_trans_brelse(sc->tp, agfl_bp);
+ if (error)
+ goto out;
+
+ /* OWN_INOBT: inobt, finobt */
+ cur = sc->sa.ino_cur;
+ if (!cur)
+ cur = xfs_inobt_init_cursor(sc->mp, sc->tp, sc->sa.agi_bp,
+ sc->sa.pag, XFS_BTNUM_INO);
+ error = xfs_btree_visit_blocks(cur, xchk_rmapbt_visit_btblock,
+ XFS_BTREE_VISIT_ALL, &cr->inobt_owned);
+ if (cur != sc->sa.ino_cur)
+ xfs_btree_del_cursor(cur, error);
+ if (error)
+ goto out;
+
+ if (xfs_has_finobt(sc->mp)) {
+ cur = sc->sa.fino_cur;
+ if (!cur)
+ cur = xfs_inobt_init_cursor(sc->mp, sc->tp,
+ sc->sa.agi_bp, sc->sa.pag,
+ XFS_BTNUM_FINO);
+ error = xfs_btree_visit_blocks(cur, xchk_rmapbt_visit_btblock,
+ XFS_BTREE_VISIT_ALL, &cr->inobt_owned);
+ if (cur != sc->sa.fino_cur)
+ xfs_btree_del_cursor(cur, error);
+ if (error)
+ goto out;
+ }
out:
/*
@@ -506,6 +539,9 @@ xchk_rmapbt_check_bitmaps(
if (xbitmap_hweight(&cr->ag_owned) != 0)
xchk_btree_xref_set_corrupt(sc, cur, level);
+
+ if (xbitmap_hweight(&cr->inobt_owned) != 0)
+ xchk_btree_xref_set_corrupt(sc, cur, level);
}
/* Scrub the rmap btree for some AG. */
@@ -523,6 +559,7 @@ xchk_rmapbt(
xbitmap_init(&cr->fs_owned);
xbitmap_init(&cr->log_owned);
xbitmap_init(&cr->ag_owned);
+ xbitmap_init(&cr->inobt_owned);
error = xchk_rmapbt_walk_ag_metadata(sc, cr);
if (error)
@@ -536,6 +573,7 @@ xchk_rmapbt(
xchk_rmapbt_check_bitmaps(sc, cr);
out:
+ xbitmap_destroy(&cr->inobt_owned);
xbitmap_destroy(&cr->ag_owned);
xbitmap_destroy(&cr->log_owned);
xbitmap_destroy(&cr->fs_owned);
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/4] xfs: cross-reference rmap records with free space btrees
2022-10-02 18:20 [PATCHSET v23.1 0/4] xfs: strengthen rmapbt scrubbing Darrick J. Wong
2022-10-02 18:20 ` [PATCH 1/4] xfs: cross-reference rmap records with ag btrees Darrick J. Wong
2022-10-02 18:20 ` [PATCH 3/4] xfs: cross-reference rmap records with inode btrees Darrick J. Wong
@ 2022-10-02 18:20 ` Darrick J. Wong
2022-10-02 18:20 ` [PATCH 4/4] xfs: cross-reference rmap records with refcount btrees Darrick J. Wong
3 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2022-10-02 18:20 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Strengthen the rmap btree record checker a little more by comparing
OWN_AG reverse mappings against the free space btrees, the rmap btree,
and the AGFL.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/scrub/rmap.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c
index 8205086aac49..20a6905c2f0d 100644
--- a/fs/xfs/scrub/rmap.c
+++ b/fs/xfs/scrub/rmap.c
@@ -7,13 +7,17 @@
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
+#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
+#include "xfs_trans.h"
#include "xfs_btree.h"
#include "xfs_rmap.h"
#include "xfs_refcount.h"
#include "xfs_ag.h"
#include "xfs_bit.h"
+#include "xfs_alloc.h"
+#include "xfs_alloc_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
@@ -51,6 +55,7 @@ struct xchk_rmap {
/* Bitmaps containing all blocks for each type of AG metadata. */
struct xbitmap fs_owned;
struct xbitmap log_owned;
+ struct xbitmap ag_owned;
/* Did we complete the AG space metadata bitmaps? */
bool bitmaps_complete;
@@ -239,6 +244,9 @@ xchk_rmapbt_mark_bitmap(
case XFS_RMAP_OWN_LOG:
bmp = &cr->log_owned;
break;
+ case XFS_RMAP_OWN_AG:
+ bmp = &cr->ag_owned;
+ break;
}
if (!bmp)
@@ -349,9 +357,47 @@ xchk_rmapbt_rec(
return error;
}
+/* Add a btree block to the rmap list. */
+STATIC int
+xchk_rmapbt_visit_btblock(
+ struct xfs_btree_cur *cur,
+ int level,
+ void *priv)
+{
+ struct xbitmap *bitmap = priv;
+ struct xfs_buf *bp;
+ xfs_fsblock_t fsbno;
+ xfs_agblock_t agbno;
+
+ xfs_btree_get_block(cur, level, &bp);
+ if (!bp)
+ return 0;
+
+ fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp));
+ agbno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
+ return xbitmap_set(bitmap, agbno, 1);
+}
+
+/* Add an AGFL block to the rmap list. */
+STATIC int
+xchk_rmapbt_walk_agfl(
+ struct xfs_mount *mp,
+ xfs_agblock_t bno,
+ void *priv)
+{
+ struct xbitmap *bitmap = priv;
+
+ return xbitmap_set(bitmap, bno, 1);
+}
+
/*
* Set up bitmaps mapping all the AG metadata to compare with the rmapbt
* records.
+ *
+ * Grab our own btree cursors here if the scrub setup function didn't give us a
+ * btree cursor due to reports of poor health. We need to find out if the
+ * rmapbt disagrees with primary metadata btrees to tag the rmapbt as being
+ * XCORRUPT.
*/
STATIC int
xchk_rmapbt_walk_ag_metadata(
@@ -359,6 +405,9 @@ xchk_rmapbt_walk_ag_metadata(
struct xchk_rmap *cr)
{
struct xfs_mount *mp = sc->mp;
+ struct xfs_buf *agfl_bp;
+ struct xfs_agf *agf = sc->sa.agf_bp->b_addr;
+ struct xfs_btree_cur *cur;
int error;
/* OWN_FS: AG headers */
@@ -376,6 +425,43 @@ xchk_rmapbt_walk_ag_metadata(
goto out;
}
+ /* OWN_AG: bnobt, cntbt, rmapbt, and AGFL */
+ cur = sc->sa.bno_cur;
+ if (!cur)
+ cur = xfs_allocbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp,
+ sc->sa.pag, XFS_BTNUM_BNO);
+ error = xfs_btree_visit_blocks(cur, xchk_rmapbt_visit_btblock,
+ XFS_BTREE_VISIT_ALL, &cr->ag_owned);
+ if (cur != sc->sa.bno_cur)
+ xfs_btree_del_cursor(cur, error);
+ if (error)
+ goto out;
+
+ cur = sc->sa.cnt_cur;
+ if (!cur)
+ cur = xfs_allocbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp,
+ sc->sa.pag, XFS_BTNUM_CNT);
+ error = xfs_btree_visit_blocks(cur, xchk_rmapbt_visit_btblock,
+ XFS_BTREE_VISIT_ALL, &cr->ag_owned);
+ if (cur != sc->sa.cnt_cur)
+ xfs_btree_del_cursor(cur, error);
+ if (error)
+ goto out;
+
+ error = xfs_btree_visit_blocks(sc->sa.rmap_cur,
+ xchk_rmapbt_visit_btblock, XFS_BTREE_VISIT_ALL,
+ &cr->ag_owned);
+ if (error)
+ goto out;
+
+ error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp);
+ if (error)
+ goto out;
+
+ error = xfs_agfl_walk(sc->mp, agf, agfl_bp, xchk_rmapbt_walk_agfl,
+ &cr->ag_owned);
+ xfs_trans_brelse(sc->tp, agfl_bp);
+
out:
/*
* If there's an error, set XFAIL and disable the bitmap
@@ -417,6 +503,9 @@ xchk_rmapbt_check_bitmaps(
if (xbitmap_hweight(&cr->log_owned) != 0)
xchk_btree_xref_set_corrupt(sc, cur, level);
+
+ if (xbitmap_hweight(&cr->ag_owned) != 0)
+ xchk_btree_xref_set_corrupt(sc, cur, level);
}
/* Scrub the rmap btree for some AG. */
@@ -433,6 +522,7 @@ xchk_rmapbt(
xbitmap_init(&cr->fs_owned);
xbitmap_init(&cr->log_owned);
+ xbitmap_init(&cr->ag_owned);
error = xchk_rmapbt_walk_ag_metadata(sc, cr);
if (error)
@@ -446,6 +536,7 @@ xchk_rmapbt(
xchk_rmapbt_check_bitmaps(sc, cr);
out:
+ xbitmap_destroy(&cr->ag_owned);
xbitmap_destroy(&cr->log_owned);
xbitmap_destroy(&cr->fs_owned);
kfree(cr);
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/4] xfs: cross-reference rmap records with refcount btrees
2022-10-02 18:20 [PATCHSET v23.1 0/4] xfs: strengthen rmapbt scrubbing Darrick J. Wong
` (2 preceding siblings ...)
2022-10-02 18:20 ` [PATCH 2/4] xfs: cross-reference rmap records with free space btrees Darrick J. Wong
@ 2022-10-02 18:20 ` Darrick J. Wong
3 siblings, 0 replies; 5+ messages in thread
From: Darrick J. Wong @ 2022-10-02 18:20 UTC (permalink / raw)
To: djwong; +Cc: linux-xfs
From: Darrick J. Wong <djwong@kernel.org>
Strengthen the rmap btree record checker a little more by comparing
OWN_REFCBT reverse mappings against the refcount btrees.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/scrub/rmap.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c
index fcda958ce1af..c63db6595e5d 100644
--- a/fs/xfs/scrub/rmap.c
+++ b/fs/xfs/scrub/rmap.c
@@ -19,6 +19,7 @@
#include "xfs_alloc.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
+#include "xfs_refcount_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
@@ -58,6 +59,7 @@ struct xchk_rmap {
struct xbitmap log_owned;
struct xbitmap ag_owned;
struct xbitmap inobt_owned;
+ struct xbitmap refcbt_owned;
/* Did we complete the AG space metadata bitmaps? */
bool bitmaps_complete;
@@ -252,6 +254,9 @@ xchk_rmapbt_mark_bitmap(
case XFS_RMAP_OWN_INOBT:
bmp = &cr->inobt_owned;
break;
+ case XFS_RMAP_OWN_REFC:
+ bmp = &cr->refcbt_owned;
+ break;
}
if (!bmp)
@@ -495,6 +500,20 @@ xchk_rmapbt_walk_ag_metadata(
goto out;
}
+ /* OWN_REFC: refcountbt */
+ if (xfs_has_reflink(sc->mp)) {
+ cur = sc->sa.refc_cur;
+ if (!cur)
+ cur = xfs_refcountbt_init_cursor(sc->mp, sc->tp,
+ sc->sa.agf_bp, sc->sa.pag);
+ error = xfs_btree_visit_blocks(cur, xchk_rmapbt_visit_btblock,
+ XFS_BTREE_VISIT_ALL, &cr->refcbt_owned);
+ if (cur != sc->sa.refc_cur)
+ xfs_btree_del_cursor(cur, error);
+ if (error)
+ goto out;
+ }
+
out:
/*
* If there's an error, set XFAIL and disable the bitmap
@@ -542,6 +561,9 @@ xchk_rmapbt_check_bitmaps(
if (xbitmap_hweight(&cr->inobt_owned) != 0)
xchk_btree_xref_set_corrupt(sc, cur, level);
+
+ if (xbitmap_hweight(&cr->refcbt_owned) != 0)
+ xchk_btree_xref_set_corrupt(sc, cur, level);
}
/* Scrub the rmap btree for some AG. */
@@ -560,6 +582,7 @@ xchk_rmapbt(
xbitmap_init(&cr->log_owned);
xbitmap_init(&cr->ag_owned);
xbitmap_init(&cr->inobt_owned);
+ xbitmap_init(&cr->refcbt_owned);
error = xchk_rmapbt_walk_ag_metadata(sc, cr);
if (error)
@@ -573,6 +596,7 @@ xchk_rmapbt(
xchk_rmapbt_check_bitmaps(sc, cr);
out:
+ xbitmap_destroy(&cr->refcbt_owned);
xbitmap_destroy(&cr->inobt_owned);
xbitmap_destroy(&cr->ag_owned);
xbitmap_destroy(&cr->log_owned);
^ permalink raw reply related [flat|nested] 5+ messages in thread