s390/dasd: Propagate partial completion length across ERP recovery

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: 5e6bdd37c5 ("s390/dasd: fix data corruption for thin provisioned devices")
Cc: stable@vger.kernel.org
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Link: https://patch.msgid.link/20260805111612.1285190-3-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Stefan Haberland 2026-08-05 13:15:55 +02:00 committed by Jens Axboe
parent cddb447c62
commit 6fb5ba2e7e

View File

@ -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 {