mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 12:52:29 -04:00
s390/dasd: Snapshot intrc before freeing the request block
__dasd_cleanup_cqr() maps the completion result to a block status by reading cqr->intrc, but only after discipline->free_cp() has returned the request block to its memory pool (dasd_eckd_free_cp() ends in dasd_sfree_request()). On SMP another CPU can reallocate that block and overwrite cqr->intrc before it is read, completing the request with the wrong error. proc_bytes is already snapshotted before free_cp() for the same reason; do the same for intrc. 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-5-sth@linux.ibm.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
2a1780f9fc
commit
dc3e3f7306
@@ -2687,17 +2687,23 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
|
||||
struct request *req;
|
||||
blk_status_t error = BLK_STS_OK;
|
||||
unsigned int proc_bytes;
|
||||
int status;
|
||||
int status, intrc;
|
||||
|
||||
req = (struct request *) cqr->callback_data;
|
||||
dasd_profile_end(cqr->block, cqr, req);
|
||||
|
||||
/*
|
||||
* free_cp() returns the request block to its memory pool, so snapshot
|
||||
* everything still needed from cqr before calling it - another CPU can
|
||||
* reallocate and overwrite the block right after.
|
||||
*/
|
||||
proc_bytes = cqr->proc_bytes;
|
||||
intrc = cqr->intrc;
|
||||
status = cqr->block->base->discipline->free_cp(cqr, req);
|
||||
if (status < 0)
|
||||
error = errno_to_blk_status(status);
|
||||
else if (status == 0) {
|
||||
switch (cqr->intrc) {
|
||||
switch (intrc) {
|
||||
case -EPERM:
|
||||
/*
|
||||
* DASD doesn't implement SCSI/NVMe reservations, but it
|
||||
|
||||
Reference in New Issue
Block a user