aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-10-16 22:35:25 -0400
committerEric Sandeen <sandeen@sandeen.net>2019-10-16 22:35:25 -0400
commit5c657f1e5a9329edda1da00864375b2d5591a1bd (patch)
tree3ed38aaba419fbc366aa1f707021b1fc01534a20
parent499c104f5747eb8a859023b9779afe07dded6522 (diff)
downloadxfsprogs-dev-5c657f1e5a9329edda1da00864375b2d5591a1bd.tar.gz
xfs_scrub: fix handling of read-verify pool runtime errors
Fix some bogosity with how we handle runtime errors in the read verify pool functions. First of all, memory allocation failures shouldn't be recorded as disk IO errors, they should just complain and abort the phase. Second, we need to collect any other runtime errors in the IO thread and abort the phase instead of silently ignoring them. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
-rw-r--r--scrub/read_verify.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/scrub/read_verify.c b/scrub/read_verify.c
index b890c92f2f..d020ce2f2f 100644
--- a/scrub/read_verify.c
+++ b/scrub/read_verify.c
@@ -53,6 +53,12 @@ struct read_verify_pool {
struct disk *disk; /* which disk? */
read_verify_ioerr_fn_t ioerr_fn; /* io error callback */
size_t miniosz; /* minimum io size, bytes */
+
+ /*
+ * Store a runtime error code here so that we can stop the pool and
+ * return it to the caller.
+ */
+ int runtime_error;
};
/*
@@ -149,6 +155,7 @@ read_verify(
unsigned long long verified = 0;
ssize_t sz;
ssize_t len;
+ int ret;
rvp = (struct read_verify_pool *)wq->wq_ctx;
while (rv->io_length > 0) {
@@ -173,7 +180,12 @@ read_verify(
}
free(rv);
- ptcounter_add(rvp->verified_bytes, verified);
+ ret = ptcounter_add(rvp->verified_bytes, verified);
+ if (ret) {
+ str_liberror(rvp->ctx, ret,
+ _("updating bytes verified counter"));
+ rvp->runtime_error = ret;
+ }
}
/* Queue a read verify request. */
@@ -188,18 +200,25 @@ read_verify_queue(
dbg_printf("verify fd %d start %"PRIu64" len %"PRIu64"\n",
rvp->disk->d_fd, rv->io_start, rv->io_length);
+ /* Worker thread saw a runtime error, don't queue more. */
+ if (rvp->runtime_error)
+ return false;
+
+ /* Otherwise clone the request and queue the copy. */
tmp = malloc(sizeof(struct read_verify));
if (!tmp) {
- rvp->ioerr_fn(rvp->ctx, rvp->disk, rv->io_start,
- rv->io_length, errno, rv->io_end_arg);
- return true;
+ rvp->runtime_error = errno;
+ str_errno(rvp->ctx, _("allocating read-verify request"));
+ return false;
}
+
memcpy(tmp, rv, sizeof(*tmp));
ret = workqueue_add(&rvp->wq, read_verify, 0, tmp);
if (ret) {
str_liberror(rvp->ctx, ret, _("queueing read-verify work"));
free(tmp);
+ rvp->runtime_error = ret;
return false;
}
rv->io_length = 0;