[PATCH 3/6] xfs_repair: verify on-disk rmap btrees with in-memory btree data

Darrick J. Wong
2024-06-03T19:25:27Z

Check the on-disk reverse mappings with the observations we've recorded
in the in-memory btree during the filesystem walk.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
repair/rmap.c | 58 +++++++++++++++++++++++++++------------------------------
1 file changed, 27 insertions(+), 31 deletions(-)

diff --git a/repair/rmap.c b/repair/rmap.c
index c1ae7da1e..69f134ed0 100644
--- a/repair/rmap.c
+++ b/repair/rmap.c
@@ -1190,11 +1190,11 @@ rmaps_verify_btree(
struct xfs_mount *mp,
xfs_agnumber_t agno)
{
+ struct xfs_btree_cur *rm_cur;
+ struct xfs_rmap_irec rm_rec;
struct xfs_rmap_irec tmp;
- struct xfs_slab_cursor *rm_cur;
struct xfs_btree_cur *bt_cur = NULL;
struct xfs_buf *agbp = NULL;
- struct xfs_rmap_irec *rm_rec;
struct xfs_perag *pag = NULL;
int have;
int error;
@@ -1207,8 +1207,8 @@ rmaps_verify_btree(
return;
}

- /* Create cursors to refcount structures */
- error = rmap_init_cursor(agno, &rm_cur);
+ /* Create cursors to rmap structures */
+ error = rmap_init_mem_cursor(mp, NULL, agno, &rm_cur);
if (error) {
do_warn(_("Not enough memory to check reverse mappings.\n"));
return;
@@ -1231,13 +1231,12 @@ rmaps_verify_btree(
goto err_agf;
}

- rm_rec = pop_slab_cursor(rm_cur);
- while (rm_rec) {
- error = rmap_lookup(bt_cur, rm_rec, &tmp, &have);
+ while ((error = rmap_get_mem_rec(rm_cur, &rm_rec)) == 1) {
+ error = rmap_lookup(bt_cur, &rm_rec, &tmp, &have);
if (error) {
do_warn(
_("Could not read reverse-mapping record for (%u/%u).\n"),
- agno, rm_rec->rm_startblock);
+ agno, rm_rec.rm_startblock);
goto err_cur;
}

@@ -1247,13 +1246,13 @@ _("Could not read reverse-mapping record for (%u/%u).\n"),
* match the observed rmap.
*/
if (xfs_has_reflink(bt_cur->bc_mp) &&
- (!have || !rmap_is_good(rm_rec, &tmp))) {
- error = rmap_lookup_overlapped(bt_cur, rm_rec,
+ (!have || !rmap_is_good(&rm_rec, &tmp))) {
+ error = rmap_lookup_overlapped(bt_cur, &rm_rec,
&tmp, &have);
if (error) {
do_warn(
_("Could not read reverse-mapping record for (%u/%u).\n"),
- agno, rm_rec->rm_startblock);
+ agno, rm_rec.rm_startblock);
goto err_cur;
}
}
@@ -1261,21 +1260,21 @@ _("Could not read reverse-mapping record for (%u/%u).\n"),
do_warn(
_("Missing reverse-mapping record for (%u/%u) %slen %u owner %"PRId64" \
%s%soff %"PRIu64"\n"),
- agno, rm_rec->rm_startblock,
- (rm_rec->rm_flags & XFS_RMAP_UNWRITTEN) ?
+ agno, rm_rec.rm_startblock,
+ (rm_rec.rm_flags & XFS_RMAP_UNWRITTEN) ?
_("unwritten ") : "",
- rm_rec->rm_blockcount,
- rm_rec->rm_owner,
- (rm_rec->rm_flags & XFS_RMAP_ATTR_FORK) ?
+ rm_rec.rm_blockcount,
+ rm_rec.rm_owner,
+ (rm_rec.rm_flags & XFS_RMAP_ATTR_FORK) ?
_("attr ") : "",
- (rm_rec->rm_flags & XFS_RMAP_BMBT_BLOCK) ?
+ (rm_rec.rm_flags & XFS_RMAP_BMBT_BLOCK) ?
_("bmbt ") : "",
- rm_rec->rm_offset);
- goto next_loop;
+ rm_rec.rm_offset);
+ continue;
}

/* Compare each refcount observation against the btree's */
- if (!rmap_is_good(rm_rec, &tmp)) {
+ if (!rmap_is_good(&rm_rec, &tmp)) {
do_warn(
_("Incorrect reverse-mapping: saw (%u/%u) %slen %u owner %"PRId64" %s%soff \
%"PRIu64"; should be (%u/%u) %slen %u owner %"PRId64" %s%soff %"PRIu64"\n"),
@@ -1289,20 +1288,17 @@ _("Incorrect reverse-mapping: saw (%u/%u) %slen %u owner %"PRId64" %s%soff \
(tmp.rm_flags & XFS_RMAP_BMBT_BLOCK) ?
_("bmbt ") : "",
tmp.rm_offset,
- agno, rm_rec->rm_startblock,
- (rm_rec->rm_flags & XFS_RMAP_UNWRITTEN) ?
+ agno, rm_rec.rm_startblock,
+ (rm_rec.rm_flags & XFS_RMAP_UNWRITTEN) ?
_("unwritten ") : "",
- rm_rec->rm_blockcount,
- rm_rec->rm_owner,
- (rm_rec->rm_flags & XFS_RMAP_ATTR_FORK) ?
+ rm_rec.rm_blockcount,
+ rm_rec.rm_owner,
+ (rm_rec.rm_flags & XFS_RMAP_ATTR_FORK) ?
_("attr ") : "",
- (rm_rec->rm_flags & XFS_RMAP_BMBT_BLOCK) ?
+ (rm_rec.rm_flags & XFS_RMAP_BMBT_BLOCK) ?
_("bmbt ") : "",
- rm_rec->rm_offset);
- goto next_loop;
+ rm_rec.rm_offset);
}
-next_loop:
- rm_rec = pop_slab_cursor(rm_cur);
}

err_cur:
@@ -1311,7 +1307,7 @@ _("Incorrect reverse-mapping: saw (%u/%u) %slen %u owner %"PRId64" %s%soff \
libxfs_buf_relse(agbp);
err_pag:
libxfs_perag_put(pag);
- free_slab_cursor(&rm_cur);
+ libxfs_btree_del_cursor(rm_cur, error);
}

/*