[PATCHSET v29.0 28/40] xfs_scrub: track data dependencies for repairs

Darrick J. Wong
2023-12-31T19:47:00Z

Hi all,

Certain kinds of XFS metadata depend on the correctness of lower level
metadata. For example, directory indexes depends on the directory data
fork, which in turn depend on the directory inode to be correct. The
current scrub code does not strictly preserve these dependencies if it
has to defer a repair until phase 4, because phase 4 prioritizes repairs
by type (corruption, then cross referencing, and then preening) and
loses the ordering of in the previous phases. This leads to absurd
things like trying to repair a directory before repairing its corrupted
fork, which is absurd.

To solve this problem, introduce a repair ticket structure to track all
the repairs pending for a principal object (inode, AG, etc). This
reduces memory requirements if an object requires more than one type of
repair and makes it very easy to track the data dependencies between
sub-objects of a principal object. Repair dependencies between object
types (e.g. bnobt before inodes) must still be encoded statically into
phase 4.

A secondary benefit of this new ticket structure is that we can decide
to attempt a repair of an object A that was flagged for a cross
referencing error during the scan if a different object B depends on A
but only B showed definitive signs of corruption.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=scrub-repair-data-deps
---
libfrog/scrub.c | 1
scrub/phase1.c | 9 -
scrub/phase2.c | 46 ++--
scrub/phase3.c | 77 ++++---
scrub/phase4.c | 17 +-
scrub/phase5.c | 9 -
scrub/phase7.c | 9 -
scrub/repair.c | 530 +++++++++++++++++++++++++++++++++----------------
scrub/repair.h | 47 +++-
scrub/scrub.c | 136 ++++++-------
scrub/scrub.h | 108 ++++++++--
scrub/scrub_private.h | 37 +++
12 files changed, 664 insertions(+), 362 deletions(-)