aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-11-01 18:04:21 -0400
committerEric Sandeen <sandeen@sandeen.net>2019-11-01 18:04:21 -0400
commit49e05cb05113c8afdbc975dec8f1bd6e94a42395 (patch)
tree84cd1dd545e830b74154e46abc27d2cbd58c7695
parent059215441a51dadb78afd0daed31c896bac22870 (diff)
downloadxfsprogs-dev-49e05cb05113c8afdbc975dec8f1bd6e94a42395.tar.gz
xfs_scrub: create a new category for unfixable errors
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>
-rw-r--r--scrub/common.c8
-rw-r--r--scrub/common.h3
-rw-r--r--scrub/phase4.c5
-rw-r--r--scrub/phase5.c2
-rw-r--r--scrub/phase6.c2
-rw-r--r--scrub/xfs_scrub.c17
-rw-r--r--scrub/xfs_scrub.h1
7 files changed, 30 insertions, 8 deletions
diff --git a/scrub/common.c b/scrub/common.c
index 32ef8cd297..29d08f3ea0 100644
--- a/scrub/common.c
+++ b/scrub/common.c
@@ -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)
diff --git a/scrub/common.h b/scrub/common.h
index b1f2ea2cba..cfd9f186cd 100644
--- a/scrub/common.h
+++ b/scrub/common.h
@@ -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)
diff --git a/scrub/phase4.c b/scrub/phase4.c
index 1cf3f6b7be..a276bc329e 100644
--- a/scrub/phase4.c
+++ b/scrub/phase4.c
@@ -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);
}
diff --git a/scrub/phase5.c b/scrub/phase5.c
index dc0ee5e884..e0c4a3dfaf 100644
--- a/scrub/phase5.c
+++ b/scrub/phase5.c
@@ -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;
diff --git a/scrub/phase6.c b/scrub/phase6.c
index bb159641aa..aae6b7d80f 100644
--- a/scrub/phase6.c
+++ b/scrub/phase6.c
@@ -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;
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index 222daae15f..963d0d7044 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -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)
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index 5abc41fd60..61831c92fa 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -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;