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 mess, you probably ought to just pull from my git trees, which are linked below. This is an extraordinary way to destroy everything. 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(-)