[PATCH 32/38] xfs_repair: drop all the metadata directory files during pass 4

Darrick J. Wong
2024-10-11T01:22:30Z

Drop the entire metadata directory tree during pass 4 so that we can
reinitialize the entire tree in phase 6. The existing metadata files
(rtbitmap, rtsummary, quotas) will be reattached to the newly rebuilt
directory tree.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
repair/dinode.c | 14 +++++++++++++-
repair/scan.c | 2 +-
2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/repair/dinode.c b/repair/dinode.c
index 9d8a027610c601..fb234e259afd83 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -656,7 +656,7 @@ _("illegal state %d in block map %" PRIu64 "\n"),
break;
}
}
- if (collect_rmaps) /* && !check_dups */
+ if (collect_rmaps && !zap_metadata) /* && !check_dups */
rmap_add_rec(mp, ino, whichfork, &irec);
*tot += irec.br_blockcount;
}
@@ -3123,6 +3123,18 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "),
*/
*dirty += process_check_inode_nlink_version(dino, lino);

+ /*
+ * The entire metadata directory tree will be rebuilt during phase 6.
+ * Therefore, if we're at the end of phase 4 and this is a metadata
+ * file, zero the ondisk inode and the incore state.
+ */
+ if (check_dups && zap_metadata && !no_modify) {
+ clear_dinode(mp, dino, lino);
+ *dirty += 1;
+ *used = is_free;
+ *isa_dir = 0;
+ }
+
return retval;

clear_bad_out:
diff --git a/repair/scan.c b/repair/scan.c
index 0fec7c222ff156..ed73de4b2477bf 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -418,7 +418,7 @@ _("bad state %d, inode %" PRIu64 " bmap block 0x%" PRIx64 "\n"),
numrecs = be16_to_cpu(block->bb_numrecs);

/* Record BMBT blocks in the reverse-mapping data. */
- if (check_dups && collect_rmaps) {
+ if (check_dups && collect_rmaps && !zap_metadata) {
agno = XFS_FSB_TO_AGNO(mp, bno);
pthread_mutex_lock(&ag_locks[agno].lock);
rmap_add_bmbt_rec(mp, ino, whichfork, bno);