From 6fb5ba2e7e43173a3761e46f091070a8185efa14 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Wed, 5 Aug 2026 13:15:55 +0200 Subject: [PATCH] s390/dasd: Propagate partial completion length across ERP recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dasd_default_erp_postaction() copies the timing and device state from the finished ERP request back to the original request but drops proc_bytes. A request that was partially completed, an ESE read of a not-yet-allocated track returns fewer bytes than requested, and then recovered through the ERP chain loses its partial-completion length. __dasd_cleanup_cqr() then sees proc_bytes == 0 and completes the whole request instead of requeueing the remainder, silently returning zeroed data for the part that was never read. Carry proc_bytes over to the original request like the other per-request state. Fixes: 5e6bdd37c552 ("s390/dasd: fix data corruption for thin provisioned devices") Cc: stable@vger.kernel.org Reviewed-by: Jan Höppner Signed-off-by: Stefan Haberland Link: https://patch.msgid.link/20260805111612.1285190-3-sth@linux.ibm.com Signed-off-by: Jens Axboe --- drivers/s390/block/dasd_erp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index 89d7516b9ec8..468f0b2cc342 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -123,6 +123,7 @@ struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr) int success; unsigned long startclk, stopclk; struct dasd_device *startdev; + unsigned int proc_bytes; BUG_ON(cqr->refers == NULL || cqr->function == NULL); @@ -130,6 +131,7 @@ struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr) startclk = cqr->startclk; stopclk = cqr->stopclk; startdev = cqr->startdev; + proc_bytes = cqr->proc_bytes; /* free all ERPs - but NOT the original cqr */ while (cqr->refers != NULL) { @@ -147,6 +149,7 @@ struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr) cqr->startclk = startclk; cqr->stopclk = stopclk; cqr->startdev = startdev; + cqr->proc_bytes = proc_bytes; if (success) cqr->status = DASD_CQR_DONE; else {