From 68ec3b819a5d600a4ede8b596761dccac9f39ebc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 21 Oct 2021 08:06:05 +0200 Subject: [PATCH] scsi: add a scsi_alloc_request helper Add a new helper that calls blk_get_request and initializes the scsi_request to avoid the indirect call through ->.initialize_rq_fn. Note that this makes the pktcdvd driver depend on the SCSI core, but given that only SCSI devices support SCSI passthrough requests that is not a functional change. Signed-off-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Link: https://lore.kernel.org/r/20211021060607.264371-6-hch@lst.de Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 2 +- drivers/block/pktcdvd.c | 2 +- drivers/scsi/scsi_bsg.c | 4 ++-- drivers/scsi/scsi_error.c | 2 +- drivers/scsi/scsi_ioctl.c | 4 ++-- drivers/scsi/scsi_lib.c | 19 +++++++++++++------ drivers/scsi/sg.c | 4 ++-- drivers/scsi/sr.c | 2 +- drivers/scsi/st.c | 2 +- drivers/target/target_core_pscsi.c | 3 +-- include/scsi/scsi_cmnd.h | 3 +++ 11 files changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ab3e37aa1830..9151e8ffba1c 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -304,8 +304,8 @@ config BLK_DEV_RAM_SIZE config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media (DEPRECATED)" depends on !UML + depends on SCSI select CDROM - select SCSI_COMMON help Note: This driver is deprecated and will be removed from the kernel in the near future! diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index cb52cce6fb03..ea2262ec76d2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -703,7 +703,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * struct request *rq; int ret = 0; - rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? + rq = scsi_alloc_request(q, (cgc->data_direction == CGC_DATA_WRITE) ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index 81c3853a2a80..551727a6f694 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -25,8 +25,8 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, return -EOPNOTSUPP; } - rq = blk_get_request(q, hdr->dout_xfer_len ? - REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + rq = scsi_alloc_request(q, hdr->dout_xfer_len ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); rq->timeout = timeout; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index b6c86cce57bf..71d027b94be4 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1998,7 +1998,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) struct request *req; struct scsi_request *rq; - req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, 0); + req = scsi_alloc_request(sdev->request_queue, REQ_OP_DRV_IN, 0); if (IS_ERR(req)) return; rq = scsi_req(req); diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 6ff2207bd45a..0078975e3c07 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -438,7 +438,7 @@ static int sg_io(struct scsi_device *sdev, struct gendisk *disk, at_head = 1; ret = -ENOMEM; - rq = blk_get_request(sdev->request_queue, writing ? + rq = scsi_alloc_request(sdev->request_queue, writing ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); @@ -561,7 +561,7 @@ static int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, } - rq = blk_get_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + rq = scsi_alloc_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) { err = PTR_ERR(rq); goto error_free_buffer; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 30f7d0b4eb73..a0f801fc8943 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -216,7 +216,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, struct scsi_request *rq; int ret; - req = blk_get_request(sdev->request_queue, + req = scsi_alloc_request(sdev->request_queue, data_direction == DMA_TO_DEVICE ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); @@ -1079,9 +1079,6 @@ EXPORT_SYMBOL(scsi_alloc_sgtables); * This function initializes the members of struct scsi_cmnd that must be * initialized before request processing starts and that won't be * reinitialized if a SCSI command is requeued. - * - * Called from inside blk_get_request() for pass-through requests and from - * inside scsi_init_command() for filesystem requests. */ static void scsi_initialize_rq(struct request *rq) { @@ -1098,6 +1095,18 @@ static void scsi_initialize_rq(struct request *rq) cmd->retries = 0; } +struct request *scsi_alloc_request(struct request_queue *q, + unsigned int op, blk_mq_req_flags_t flags) +{ + struct request *rq; + + rq = blk_get_request(q, op, flags); + if (!IS_ERR(rq)) + scsi_initialize_rq(rq); + return rq; +} +EXPORT_SYMBOL_GPL(scsi_alloc_request); + /* * Only called when the request isn't completed by SCSI, and not freed by * SCSI @@ -1864,7 +1873,6 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { #endif .init_request = scsi_mq_init_request, .exit_request = scsi_mq_exit_request, - .initialize_rq_fn = scsi_initialize_rq, .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, @@ -1894,7 +1902,6 @@ static const struct blk_mq_ops scsi_mq_ops = { #endif .init_request = scsi_mq_init_request, .exit_request = scsi_mq_exit_request, - .initialize_rq_fn = scsi_initialize_rq, .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 3c98f08dc25d..85f57ac0b844 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1718,13 +1718,13 @@ sg_start_req(Sg_request *srp, unsigned char *cmd) * * With scsi-mq enabled, there are a fixed number of preallocated * requests equal in number to shost->can_queue. If all of the - * preallocated requests are already in use, then blk_get_request() + * preallocated requests are already in use, then scsi_alloc_request() * will sleep until an active command completes, freeing up a request. * Although waiting in an asynchronous interface is less than ideal, we * do not want to use BLK_MQ_REQ_NOWAIT here because userspace might * not expect an EWOULDBLOCK from this condition. */ - rq = blk_get_request(q, hp->dxfer_direction == SG_DXFER_TO_DEV ? + 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); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 115f7ef7a5de..7c4d9a964799 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -967,7 +967,7 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf, struct bio *bio; int ret; - rq = blk_get_request(disk->queue, REQ_OP_DRV_IN, 0); + rq = scsi_alloc_request(disk->queue, REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); req = scsi_req(rq); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9933722acfd9..1275299f6159 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -543,7 +543,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd, int err = 0; struct scsi_tape *STp = SRpnt->stp; - req = blk_get_request(SRpnt->stp->device->request_queue, + req = scsi_alloc_request(SRpnt->stp->device->request_queue, data_direction == DMA_TO_DEVICE ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(req)) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 75ef52f008ff..b5705a2bd761 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -980,11 +980,10 @@ pscsi_execute_cmd(struct se_cmd *cmd) memcpy(pt->pscsi_cdb, cmd->t_task_cdb, scsi_command_size(cmd->t_task_cdb)); - req = blk_get_request(pdv->pdv_sd->request_queue, + req = scsi_alloc_request(pdv->pdv_sd->request_queue, cmd->data_direction == DMA_TO_DEVICE ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(req)) { - pr_err("PSCSI: blk_get_request() failed\n"); ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; goto fail; } diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index eaf04c9a1dfc..31078063afac 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -396,4 +396,7 @@ static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq); +struct request *scsi_alloc_request(struct request_queue *q, + unsigned int op, blk_mq_req_flags_t flags); + #endif /* _SCSI_SCSI_CMND_H */ -- 2.11.0