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> --- 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 7b6933a7475..360426c5fb0 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 1ca8331bb04..814a385ce29 100644 --- a/scrub/repair.c +++ b/scrub/repair.c @@ -282,9 +282,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; @@ -293,25 +291,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 969871bd8bf..4c3fd718575 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