From: Darrick J. Wong <djwong@xxxxxxxxxx> Currently, action_list_find_mustfix does two things -- it figures out which repairs must be tried during phase 2 to enable the inode scan in phase 3; and it figures out if xfs_scrub should warn about secondary and primary metadata corruption that might make repair difficult. Split these into separate functions to make each more coherent. A long time from now we'll need this to enable warnings about difficult rt repairs, but for now this is merely a code cleanup. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> Reviewed-by: Christoph Hellwig <hch@xxxxxx> --- scrub/phase2.c | 15 +++++++-------- scrub/repair.c | 38 +++++++++++++++++++++++++++----------- scrub/repair.h | 10 +++++++--- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/scrub/phase2.c b/scrub/phase2.c index ec72bb5b7..4c0d20a8e 100644 --- a/scrub/phase2.c +++ b/scrub/phase2.c @@ -42,9 +42,8 @@ scan_ag_metadata( struct scan_ctl *sctl = arg; struct action_list alist; struct action_list immediate_alist; - unsigned long long broken_primaries; - unsigned long long broken_secondaries; char descr[DESCR_BUFSZ]; + unsigned int difficulty; int ret; if (sctl->aborted) @@ -79,12 +78,12 @@ scan_ag_metadata( * the inobt from rmapbt data, but if the rmapbt is broken even * at this early phase then we are sunk. */ - broken_secondaries = 0; - broken_primaries = 0; - action_list_find_mustfix(&alist, &immediate_alist, - &broken_primaries, &broken_secondaries); - if (broken_secondaries && !debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) { - if (broken_primaries) + difficulty = action_list_difficulty(&alist); + action_list_find_mustfix(&alist, &immediate_alist); + + if ((difficulty & REPAIR_DIFFICULTY_SECONDARY) && + !debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) { + if (difficulty & REPAIR_DIFFICULTY_PRIMARY) str_info(ctx, descr, _("Corrupt primary and secondary block mapping metadata.")); else diff --git a/scrub/repair.c b/scrub/repair.c index 50f168d24..8ee9102ab 100644 --- a/scrub/repair.c +++ b/scrub/repair.c @@ -290,9 +290,7 @@ xfs_action_item_compare( void action_list_find_mustfix( struct action_list *alist, - struct action_list *immediate_alist, - unsigned long long *broken_primaries, - unsigned long long *broken_secondaries) + struct action_list *immediate_alist) { struct action_item *n; struct action_item *aitem; @@ -301,25 +299,43 @@ action_list_find_mustfix( if (!(aitem->flags & XFS_SCRUB_OFLAG_CORRUPT)) continue; switch (aitem->type) { - case XFS_SCRUB_TYPE_RMAPBT: - (*broken_secondaries)++; - break; case XFS_SCRUB_TYPE_FINOBT: case XFS_SCRUB_TYPE_INOBT: alist->nr--; list_move_tail(&aitem->list, &immediate_alist->list); immediate_alist->nr++; - fallthrough; + break; + } + } +} + +/* Determine if primary or secondary metadata are inconsistent. */ +unsigned int +action_list_difficulty( + const struct action_list *alist) +{ + struct action_item *aitem, *n; + unsigned int ret = 0; + + list_for_each_entry_safe(aitem, n, &alist->list, list) { + if (!(aitem->flags & XFS_SCRUB_OFLAG_CORRUPT)) + continue; + + switch (aitem->type) { + case XFS_SCRUB_TYPE_RMAPBT: + ret |= REPAIR_DIFFICULTY_SECONDARY; + break; + case XFS_SCRUB_TYPE_FINOBT: + case XFS_SCRUB_TYPE_INOBT: case XFS_SCRUB_TYPE_BNOBT: case XFS_SCRUB_TYPE_CNTBT: case XFS_SCRUB_TYPE_REFCNTBT: - (*broken_primaries)++; - break; - default: - abort(); + ret |= REPAIR_DIFFICULTY_PRIMARY; break; } } + + return ret; } /* diff --git a/scrub/repair.h b/scrub/repair.h index 6b6f64691..b61bd29c8 100644 --- a/scrub/repair.h +++ b/scrub/repair.h @@ -28,9 +28,13 @@ void action_list_discard(struct action_list *alist); void action_list_splice(struct action_list *dest, struct action_list *src); void action_list_find_mustfix(struct action_list *actions, - struct action_list *immediate_alist, - unsigned long long *broken_primaries, - unsigned long long *broken_secondaries); + struct action_list *immediate_alist); + +/* Primary metadata is corrupt */ +#define REPAIR_DIFFICULTY_PRIMARY (1U << 0) +/* Secondary metadata is corrupt */ +#define REPAIR_DIFFICULTY_SECONDARY (1U << 1) +unsigned int action_list_difficulty(const struct action_list *actions); /* * Only ask the kernel to repair this object if the kernel directly told us it