Get rid of this enumeration, and just do what we will directly.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
#undef DEP
/* Repair some metadata. */
-static enum check_outcome
+static int
xfs_repair_metadata(
struct scrub_ctx *ctx,
struct xfs_fd *xfdp,
}
if (!is_corrupt(&meta) && repair_only)
- return CHECK_RETRY;
+ return 0;
memcpy(&oldm, &meta, sizeof(oldm));
oldm.sm_flags = sri->sri_state[scrub_type] & SCRUB_ITEM_REPAIR_ANY;
if (debug || verbose)
str_info(ctx, descr_render(&dsc),
_("Filesystem is busy, deferring repair."));
- return CHECK_RETRY;
+ return 0;
case ESHUTDOWN:
/* Filesystem is already shut down, abort. */
str_error(ctx, descr_render(&dsc),
_("Filesystem is shut down, aborting."));
- return CHECK_ABORT;
+ return ECANCELED;
case ENOTTY:
case EOPNOTSUPP:
/*
if (is_unoptimized(&oldm) ||
debug_tweak_on("XFS_SCRUB_FORCE_REPAIR")) {
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
}
/*
* If we're in no-complain mode, requeue the check for
* again to see if another repair fixed it.
*/
if (!(repair_flags & XRM_FINAL_WARNING))
- return CHECK_RETRY;
+ return 0;
fallthrough;
case EINVAL:
/* Kernel doesn't know how to repair this? */
str_corrupt(ctx, descr_render(&dsc),
_("Don't know how to fix; offline repair required."));
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
case EROFS:
/* Read-only filesystem, can't fix. */
if (verbose || debug || needs_repair(&oldm))
str_error(ctx, descr_render(&dsc),
_("Read-only filesystem; cannot make changes."));
- return CHECK_ABORT;
+ return ECANCELED;
case ENOENT:
/* Metadata not present, just skip it. */
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
case ENOMEM:
case ENOSPC:
/* Don't care if preen fails due to low resources. */
if (is_unoptimized(&oldm) && !needs_repair(&oldm)) {
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
}
fallthrough;
default:
* trying to repair it, and bail out.
*/
if (!(repair_flags & XRM_FINAL_WARNING))
- return CHECK_RETRY;
+ return 0;
str_liberror(ctx, error, descr_render(&dsc));
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
}
/*
* log the error loudly and don't try again.
*/
if (!(repair_flags & XRM_FINAL_WARNING))
- return CHECK_RETRY;
+ return 0;
str_corrupt(ctx, descr_render(&dsc),
_("Repair unsuccessful; offline repair required."));
} else if (xref_failed(&meta)) {
if (verbose)
str_info(ctx, descr_render(&dsc),
_("Seems correct but cross-referencing failed; will keep checking."));
- return CHECK_RETRY;
+ return 0;
}
} else if (meta.sm_flags & XFS_SCRUB_OFLAG_NO_REPAIR_NEEDED) {
if (verbose)
}
scrub_item_clean_state(sri, scrub_type);
- return CHECK_DONE;
+ return 0;
}
/*
struct xfs_fd xfd;
struct xfs_fd *xfdp = &ctx->mnt;
unsigned int scrub_type;
+ int error = 0;
if (ctx->mode < SCRUB_MODE_REPAIR)
return 0;
}
foreach_scrub_type(scrub_type) {
- enum check_outcome fix;
-
if (scrub_excessive_errors(ctx))
return ECANCELED;
!repair_item_dependencies_ok(sri, scrub_type))
continue;
- fix = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags);
- switch (fix) {
- case CHECK_DONE:
- if (!(flags & XRM_NOPROGRESS))
- progress_add(1);
- continue;
- case CHECK_ABORT:
- return ECANCELED;
- case CHECK_RETRY:
- continue;
- case CHECK_REPAIR:
- abort();
- }
+ error = xfs_repair_metadata(ctx, xfdp, scrub_type, sri, flags);
+ if (error)
+ break;
+
+ /* Maybe update progress if we fixed the problem. */
+ if (!(flags & XRM_NOPROGRESS) &&
+ !(sri->sri_state[scrub_type] & SCRUB_ITEM_REPAIR_ANY))
+ progress_add(1);
}
- return 0;
+ return error;
}
/*
}
/* Do a read-only check of some metadata. */
-static enum check_outcome
+static int
xfs_check_metadata(
struct scrub_ctx *ctx,
struct xfs_fd *xfdp,
struct xfs_scrub_metadata *meta,
- bool is_inode)
+ struct scrub_item *sri)
{
DEFINE_DESCR(dsc, ctx, format_scrub_descr);
enum xfrog_scrub_group group;
break;
case ENOENT:
/* Metadata not present, just skip it. */
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
case ESHUTDOWN:
/* FS already crashed, give up. */
str_error(ctx, descr_render(&dsc),
_("Filesystem is shut down, aborting."));
- return CHECK_ABORT;
+ return ECANCELED;
case EIO:
case ENOMEM:
/* Abort on I/O errors or insufficient memory. */
str_liberror(ctx, error, descr_render(&dsc));
- return CHECK_ABORT;
+ return ECANCELED;
case EDEADLOCK:
case EBUSY:
case EFSBADCRC:
/*
* The first two should never escape the kernel,
* and the other two should be reported via sm_flags.
+ * Log it and move on.
*/
str_liberror(ctx, error, _("Kernel bug"));
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
default:
- /* Operational error. */
+ /* Operational error. Log it and move on. */
str_liberror(ctx, error, descr_render(&dsc));
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
}
/*
*/
if (is_corrupt(meta) || xref_disagrees(meta)) {
if (ctx->mode < SCRUB_MODE_REPAIR) {
+ /* Dry-run mode, so log an error and forget it. */
str_corrupt(ctx, descr_render(&dsc),
_("Repairs are required."));
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
}
- return CHECK_REPAIR;
+ /* Schedule repairs. */
+ scrub_item_save_state(sri, meta->sm_type, meta->sm_flags);
+ return 0;
}
/*
*/
if (is_unoptimized(meta)) {
if (ctx->mode != SCRUB_MODE_REPAIR) {
+ /* Dry-run mode, so log an error and forget it. */
if (group != XFROG_SCRUB_GROUP_INODE) {
/* AG or FS metadata, always warn. */
str_info(ctx, descr_render(&dsc),
ctx->preen_triggers[meta->sm_type] = true;
pthread_mutex_unlock(&ctx->lock);
}
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
}
- return CHECK_REPAIR;
+ /* Schedule optimizations. */
+ scrub_item_save_state(sri, meta->sm_type, meta->sm_flags);
+ return 0;
}
/*
* re-examine the object as repairs progress to see if the kernel will
* deem it completely consistent at some point.
*/
- if (xref_failed(meta) && ctx->mode == SCRUB_MODE_REPAIR)
- return CHECK_REPAIR;
+ if (xref_failed(meta) && ctx->mode == SCRUB_MODE_REPAIR) {
+ scrub_item_save_state(sri, meta->sm_type, meta->sm_flags);
+ return 0;
+ }
/* Everything is ok. */
- return CHECK_DONE;
+ scrub_item_clean_state(sri, meta->sm_type);
+ return 0;
}
/* Bulk-notify user about things that could be optimized. */
struct xfs_scrub_metadata meta = {
.sm_type = type,
};
- enum check_outcome fix;
+ int error;
background_sleep();
}
/* Check the item. */
- fix = xfs_check_metadata(ctx, xfdp, &meta, false);
+ error = xfs_check_metadata(ctx, xfdp, &meta, sri);
if (xfrog_scrubbers[type].group != XFROG_SCRUB_GROUP_INODE)
progress_add(1);
- switch (fix) {
- case CHECK_ABORT:
- return ECANCELED;
- case CHECK_REPAIR:
- scrub_item_save_state(sri, type, meta.sm_flags);
- return 0;
- case CHECK_DONE:
- scrub_item_clean_state(sri, type);
- return 0;
- default:
- /* CHECK_RETRY should never happen. */
- abort();
- }
+ return error;
}
/* Schedule scrub for all metadata of a given group. */
enum xfrog_scrub_group;
-/* Online scrub and repair. */
-enum check_outcome {
- CHECK_DONE, /* no further processing needed */
- CHECK_REPAIR, /* schedule this for repairs */
- CHECK_ABORT, /* end program */
- CHECK_RETRY, /* repair failed, try again later */
-};
-
/*
* This flag boosts the repair priority of a scrub item when a dependent scrub
* item is scheduled for repair. Use a separate flag to preserve the