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;
};
/*
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) {
}
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. */
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;