]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: fix handling of read-verify pool runtime errors
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 17 Oct 2019 02:35:25 +0000 (22:35 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 17 Oct 2019 02:35:25 +0000 (22:35 -0400)
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>
scrub/read_verify.c

index b890c92f2f0016cd4f56386913f501d4fc3c13f7..d020ce2f2f0d08047b662048bf1c547871639ac0 100644 (file)
@@ -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;