summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sg.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2022-02-24 18:55:47 +0100
committerMartin K. Petersen <martin.petersen@oracle.com>2022-03-01 22:21:49 -0500
commitce70fd9a551af7424a7dace2a1ba05a7de8eae27 (patch)
treec074d0b72237150c6657b632325917f28b1a827a /drivers/scsi/sg.c
parent71bada345b33b9297e7cc9415db6328c99b554f9 (diff)
downloadlinux-ce70fd9a551af7424a7dace2a1ba05a7de8eae27.tar.bz2
scsi: core: Remove the cmd field from struct scsi_request
Now that each scsi_request is backed by a scsi_cmnd, there is no need to indirect the CDB storage. Change all submitters of SCSI passthrough requests to store the CDB information directly in the scsi_cmnd, and while doing so allocate the full 32 bytes that cover all Linux supported SCSI hosts instead of requiring dynamic allocation for > 16 byte CDBs. On 64-bit systems this does not change the size of the scsi_cmnd at all, while on 32-bit systems it slightly increases it for now, but that increase will be made up by the removal of the remaining scsi_request fields. Link: https://lore.kernel.org/r/20220224175552.988286-4-hch@lst.de Reviewed-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: John Garry <john.garry@huawei.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/sg.c')
-rw-r--r--drivers/scsi/sg.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index bbd75026ec93..cc3f11270dc2 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -818,7 +818,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
}
if (atomic_read(&sdp->detaching)) {
if (srp->bio) {
- scsi_req_free_cmd(scsi_req(srp->rq));
blk_mq_free_request(srp->rq);
srp->rq = NULL;
}
@@ -1393,7 +1392,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status)
* blk_rq_unmap_user() can be called from user context.
*/
srp->rq = NULL;
- scsi_req_free_cmd(scsi_req(rq));
blk_mq_free_request(rq);
write_lock_irqsave(&sfp->rq_list_lock, iflags);
@@ -1738,18 +1736,12 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
struct request_queue *q = sfp->parentdp->device->request_queue;
struct rq_map_data *md, map_data;
int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
- unsigned char *long_cmdp = NULL;
+ struct scsi_cmnd *scmd;
SCSI_LOG_TIMEOUT(4, sg_printk(KERN_INFO, sfp->parentdp,
"sg_start_req: dxfer_len=%d\n",
dxfer_len));
- if (hp->cmd_len > BLK_MAX_CDB) {
- long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL);
- if (!long_cmdp)
- return -ENOMEM;
- }
-
/*
* NOTE
*
@@ -1763,16 +1755,18 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
*/
rq = scsi_alloc_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
- if (IS_ERR(rq)) {
- kfree(long_cmdp);
+ if (IS_ERR(rq))
return PTR_ERR(rq);
- }
+ scmd = blk_mq_rq_to_pdu(rq);
req = scsi_req(rq);
- if (hp->cmd_len > BLK_MAX_CDB)
- req->cmd = long_cmdp;
- memcpy(req->cmd, cmd, hp->cmd_len);
- req->cmd_len = hp->cmd_len;
+ if (hp->cmd_len > sizeof(scmd->cmnd)) {
+ blk_mq_free_request(rq);
+ return -EINVAL;
+ }
+
+ memcpy(scmd->cmnd, cmd, hp->cmd_len);
+ scmd->cmd_len = hp->cmd_len;
srp->rq = rq;
rq->end_io_data = srp;
@@ -1865,10 +1859,8 @@ sg_finish_rem_req(Sg_request *srp)
if (srp->bio)
ret = blk_rq_unmap_user(srp->bio);
- if (srp->rq) {
- scsi_req_free_cmd(scsi_req(srp->rq));
+ if (srp->rq)
blk_mq_free_request(srp->rq);
- }
if (srp->res_used)
sg_unlink_reserve(sfp, srp);