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 <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Link: https://lore.kernel.org/r/20211021060607.264371-6-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Christoph Hellwig 2021-10-21 08:06:05 +02:00 коммит произвёл Jens Axboe
Родитель 237ea1602f
Коммит 68ec3b819a
11 изменённых файлов: 28 добавлений и 19 удалений

Просмотреть файл

@ -304,8 +304,8 @@ config BLK_DEV_RAM_SIZE
config CDROM_PKTCDVD config CDROM_PKTCDVD
tristate "Packet writing on CD/DVD media (DEPRECATED)" tristate "Packet writing on CD/DVD media (DEPRECATED)"
depends on !UML depends on !UML
depends on SCSI
select CDROM select CDROM
select SCSI_COMMON
help help
Note: This driver is deprecated and will be removed from the Note: This driver is deprecated and will be removed from the
kernel in the near future! kernel in the near future!

Просмотреть файл

@ -703,7 +703,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
struct request *rq; struct request *rq;
int ret = 0; 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); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);

Просмотреть файл

@ -25,8 +25,8 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
rq = blk_get_request(q, hdr->dout_xfer_len ? rq = scsi_alloc_request(q, hdr->dout_xfer_len ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
rq->timeout = timeout; rq->timeout = timeout;

Просмотреть файл

@ -1998,7 +1998,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
struct request *req; struct request *req;
struct scsi_request *rq; 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)) if (IS_ERR(req))
return; return;
rq = scsi_req(req); rq = scsi_req(req);

Просмотреть файл

@ -438,7 +438,7 @@ static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
at_head = 1; at_head = 1;
ret = -ENOMEM; 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); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_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)) { if (IS_ERR(rq)) {
err = PTR_ERR(rq); err = PTR_ERR(rq);
goto error_free_buffer; goto error_free_buffer;

Просмотреть файл

@ -216,7 +216,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
struct scsi_request *rq; struct scsi_request *rq;
int ret; int ret;
req = blk_get_request(sdev->request_queue, req = scsi_alloc_request(sdev->request_queue,
data_direction == DMA_TO_DEVICE ? data_direction == DMA_TO_DEVICE ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); 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 * This function initializes the members of struct scsi_cmnd that must be
* initialized before request processing starts and that won't be * initialized before request processing starts and that won't be
* reinitialized if a SCSI command is requeued. * 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) static void scsi_initialize_rq(struct request *rq)
{ {
@ -1098,6 +1095,18 @@ static void scsi_initialize_rq(struct request *rq)
cmd->retries = 0; 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 * Only called when the request isn't completed by SCSI, and not freed by
* SCSI * SCSI
@ -1864,7 +1873,6 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = {
#endif #endif
.init_request = scsi_mq_init_request, .init_request = scsi_mq_init_request,
.exit_request = scsi_mq_exit_request, .exit_request = scsi_mq_exit_request,
.initialize_rq_fn = scsi_initialize_rq,
.cleanup_rq = scsi_cleanup_rq, .cleanup_rq = scsi_cleanup_rq,
.busy = scsi_mq_lld_busy, .busy = scsi_mq_lld_busy,
.map_queues = scsi_map_queues, .map_queues = scsi_map_queues,
@ -1894,7 +1902,6 @@ static const struct blk_mq_ops scsi_mq_ops = {
#endif #endif
.init_request = scsi_mq_init_request, .init_request = scsi_mq_init_request,
.exit_request = scsi_mq_exit_request, .exit_request = scsi_mq_exit_request,
.initialize_rq_fn = scsi_initialize_rq,
.cleanup_rq = scsi_cleanup_rq, .cleanup_rq = scsi_cleanup_rq,
.busy = scsi_mq_lld_busy, .busy = scsi_mq_lld_busy,
.map_queues = scsi_map_queues, .map_queues = scsi_map_queues,

Просмотреть файл

@ -1718,13 +1718,13 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
* *
* With scsi-mq enabled, there are a fixed number of preallocated * With scsi-mq enabled, there are a fixed number of preallocated
* requests equal in number to shost->can_queue. If all of the * 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. * will sleep until an active command completes, freeing up a request.
* Although waiting in an asynchronous interface is less than ideal, we * Although waiting in an asynchronous interface is less than ideal, we
* do not want to use BLK_MQ_REQ_NOWAIT here because userspace might * do not want to use BLK_MQ_REQ_NOWAIT here because userspace might
* not expect an EWOULDBLOCK from this condition. * 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); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) { if (IS_ERR(rq)) {
kfree(long_cmdp); kfree(long_cmdp);

Просмотреть файл

@ -967,7 +967,7 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
struct bio *bio; struct bio *bio;
int ret; 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)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
req = scsi_req(rq); req = scsi_req(rq);

Просмотреть файл

@ -543,7 +543,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
int err = 0; int err = 0;
struct scsi_tape *STp = SRpnt->stp; 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 ? data_direction == DMA_TO_DEVICE ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(req)) if (IS_ERR(req))

Просмотреть файл

@ -980,11 +980,10 @@ pscsi_execute_cmd(struct se_cmd *cmd)
memcpy(pt->pscsi_cdb, cmd->t_task_cdb, memcpy(pt->pscsi_cdb, cmd->t_task_cdb,
scsi_command_size(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 ? cmd->data_direction == DMA_TO_DEVICE ?
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(req)) { if (IS_ERR(req)) {
pr_err("PSCSI: blk_get_request() failed\n");
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto fail; goto fail;
} }

Просмотреть файл

@ -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, extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc,
u8 key, u8 asc, u8 ascq); 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 */ #endif /* _SCSI_SCSI_CMND_H */