]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: create a new category for unfixable errors
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 1 Nov 2019 22:04:21 +0000 (18:04 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 1 Nov 2019 22:04:21 +0000 (18:04 -0400)
There's nothing that xfs_scrub (or XFS) can do about media errors for
data file blocks -- the data are gone.  Create a new category for these
unfixable errors so that we don't advise the user to take further action
that won't fix the problem.

[sandeen: this error counter is only used for media errors today, but
there are tests in the code to accommodate potential future new types
of unfixable errors.]

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
scrub/common.c
scrub/common.h
scrub/phase4.c
scrub/phase5.c
scrub/phase6.c
scrub/xfs_scrub.c
scrub/xfs_scrub.h

index 32ef8cd29718fdee11fca15ad52ea4727e3aa233..29d08f3ea020f3f28cf6808034363fb0927f233e 100644 (file)
@@ -43,7 +43,7 @@ xfs_scrub_excessive_errors(
                return false;
 
        pthread_mutex_lock(&ctx->lock);
-       errors_seen = ctx->corruptions_found;
+       errors_seen = ctx->corruptions_found + ctx->unfixable_errors;
        pthread_mutex_unlock(&ctx->lock);
 
        return errors_seen >= ctx->max_errors;
@@ -61,6 +61,10 @@ static struct {
                .string = "Corruption",
                .loglevel = LOG_ERR,
        },
+       [S_UNFIXABLE] = {
+               .string = "Unfixable Error",
+               .loglevel = LOG_ERR,
+       },
        [S_WARN]   = {
                .string = "Warning",
                .loglevel = LOG_WARNING,
@@ -136,6 +140,8 @@ out_record:
                ctx->runtime_errors++;
        else if (level == S_CORRUPT)
                ctx->corruptions_found++;
+       else if (level == S_UNFIXABLE)
+               ctx->unfixable_errors++;
        else if (level == S_WARN)
                ctx->warnings_found++;
        else if (level == S_REPAIR)
index b1f2ea2cba2ebe415bb75765dff00d0c75e99279..cfd9f186cd67b51f54ac4999fcb334c34da9ecf4 100644 (file)
@@ -18,6 +18,7 @@ bool xfs_scrub_excessive_errors(struct scrub_ctx *ctx);
 enum error_level {
        S_ERROR = 0,
        S_CORRUPT,
+       S_UNFIXABLE,
        S_WARN,
        S_INFO,
        S_REPAIR,
@@ -43,6 +44,8 @@ void __str_out(struct scrub_ctx *ctx, const char *descr, enum error_level level,
        __str_out(ctx, str, S_REPAIR,   0,      __FILE__, __LINE__, __VA_ARGS__)
 #define record_preen(ctx, str, ...) \
        __str_out(ctx, str, S_PREEN,    0,      __FILE__, __LINE__, __VA_ARGS__)
+#define str_unfixable_error(ctx, str, ...) \
+       __str_out(ctx, str, S_UNFIXABLE, 0,     __FILE__, __LINE__, __VA_ARGS__)
 
 #define dbg_printf(fmt, ...) \
        do {if (debug > 1) {printf(fmt, __VA_ARGS__);}} while (0)
index 1cf3f6b7be45dffcb83eff37340672a358868197..a276bc329e433f924ac2d105d54adeb42287e944 100644 (file)
@@ -99,7 +99,10 @@ xfs_process_action_items(
        workqueue_destroy(&wq);
 
        pthread_mutex_lock(&ctx->lock);
-       if (moveon && ctx->corruptions_found == 0 && want_fstrim) {
+       if (moveon &&
+           ctx->corruptions_found == 0 &&
+           ctx->unfixable_errors == 0 &&
+           want_fstrim) {
                fstrim(ctx);
                progress_add(1);
        }
index dc0ee5e88440b9530638e781c1ed36809128048c..e0c4a3dfafad4cc0defcb7500a35914ff6f89a17 100644 (file)
@@ -336,7 +336,7 @@ xfs_scan_connections(
        bool                    moveon = true;
        bool                    ret;
 
-       if (ctx->corruptions_found) {
+       if (ctx->corruptions_found || ctx->unfixable_errors) {
                str_info(ctx, ctx->mntpoint,
 _("Filesystem has errors, skipping connectivity checks."));
                return true;
index bb159641aab8aea3b0fa7c51e6571406cd094f98..aae6b7d80fbddb86056403c6f412bee9262638e1 100644 (file)
@@ -161,7 +161,7 @@ report_badfile(
        bad_length = min(start + length,
                         br->bmap->bm_physical + br->bmap->bm_length) - start;
 
-       str_error(br->ctx, br->descr,
+       str_unfixable_error(br->ctx, br->descr,
 _("media error at data offset %llu length %llu."),
                        br->bmap->bm_offset + bad_offset, bad_length);
        return 0;
index 222daae15f3b170ef8fa45e7b1eb725873e28efa..963d0d7044b734b0ac9cc0609af5b6c52ba157a2 100644 (file)
@@ -511,15 +511,24 @@ static void
 report_outcome(
        struct scrub_ctx        *ctx)
 {
-       unsigned long long      total_errors;
+       unsigned long long      actionable_errors;
 
-       total_errors = ctx->corruptions_found + ctx->runtime_errors;
+       actionable_errors = ctx->corruptions_found + ctx->runtime_errors;
 
-       if (total_errors == 0 && ctx->warnings_found == 0) {
+       if (actionable_errors == 0 &&
+           ctx->unfixable_errors == 0 &&
+           ctx->warnings_found == 0) {
                log_info(ctx, _("No problems found."));
                return;
        }
 
+       if (ctx->unfixable_errors) {
+               fprintf(stderr, _("%s: unfixable errors found: %llu\n"),
+                               ctx->mntpoint, ctx->unfixable_errors);
+               log_err(ctx, _("unfixable errors found: %llu"),
+                               ctx->unfixable_errors);
+       }
+
        if (ctx->corruptions_found > 0) {
                fprintf(stderr, _("%s: corruptions found: %llu\n"),
                                ctx->mntpoint, ctx->corruptions_found);
@@ -545,7 +554,7 @@ report_outcome(
         * setting up the scrub and we actually saw corruptions.  Warnings
         * are not corruptions.
         */
-       if (ctx->scrub_setup_succeeded && total_errors > 0) {
+       if (ctx->scrub_setup_succeeded && actionable_errors > 0) {
                char            *msg;
 
                if (ctx->mode == SCRUB_MODE_DRY_RUN)
index 5abc41fd60ed67cee7061b9b3689579a5568df2d..61831c92fad0825906f6c6be4d735b6b3b355d6f 100644 (file)
@@ -74,6 +74,7 @@ struct scrub_ctx {
        unsigned long long      max_errors;
        unsigned long long      runtime_errors;
        unsigned long long      corruptions_found;
+       unsigned long long      unfixable_errors;
        unsigned long long      warnings_found;
        unsigned long long      inodes_checked;
        unsigned long long      bytes_checked;