@@ -689,7 +689,8 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
int ret = 0;
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,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq))
return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
@@ -26,7 +26,8 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
}
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,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq))
return PTR_ERR(rq);
rq->timeout = timeout;
@@ -2025,7 +2025,8 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
struct scsi_cmnd *scmd;
struct request *req;
- req = scsi_alloc_request(sdev->request_queue, REQ_OP_DRV_IN, 0);
+ req = scsi_alloc_request(sdev->request_queue, REQ_OP_DRV_IN, 0,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(req))
return;
scmd = blk_mq_rq_to_pdu(req);
@@ -435,7 +435,8 @@ static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
at_head = 1;
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,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq))
return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
@@ -546,7 +547,8 @@ static int sg_scsi_ioctl(struct request_queue *q, fmode_t mode,
}
- rq = scsi_alloc_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,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto error_free_buffer;
@@ -210,9 +210,10 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
int ret;
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);
+ data_direction == DMA_TO_DEVICE ?
+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN,
+ rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0,
+ SUBMITTED_BY_SCSI_EXEC);
if (IS_ERR(req))
return PTR_ERR(req);
@@ -226,6 +227,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
scmd->cmd_len = COMMAND_SIZE(cmd[0]);
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
scmd->allowed = retries;
+ scmd->submitter = SUBMITTED_BY_SCSI_EXEC;
req->timeout = timeout;
req->cmd_flags |= flags;
req->rq_flags |= rq_flags | RQF_QUIET;
@@ -1119,13 +1121,18 @@ static void scsi_initialize_rq(struct request *rq)
}
struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf,
- blk_mq_req_flags_t flags)
+ blk_mq_req_flags_t flags,
+ enum scsi_cmnd_submitter submitter)
{
+ struct scsi_cmnd *cmd;
struct request *rq;
rq = blk_mq_alloc_request(q, opf, flags);
if (!IS_ERR(rq))
scsi_initialize_rq(rq);
+
+ cmd = blk_mq_rq_to_pdu(rq);
+ cmd->submitter = submitter;
return rq;
}
EXPORT_SYMBOL_GPL(scsi_alloc_request);
@@ -1541,13 +1548,14 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
scsi_init_command(sdev, cmd);
- if (!blk_rq_is_passthrough(req))
+ if (!blk_rq_is_passthrough(req)) {
cmd->allowed = 0;
+ cmd->submitter = SUBMITTED_BY_BLOCK_LAYER;
+ }
cmd->eh_eflags = 0;
cmd->prot_type = 0;
cmd->prot_flags = 0;
- cmd->submitter = 0;
memset(&cmd->sdb, 0, sizeof(cmd->sdb));
cmd->underflow = 0;
cmd->transfersize = 0;
@@ -1605,6 +1613,8 @@ static void scsi_done_internal(struct scsi_cmnd *cmd, bool complete_directly)
switch (cmd->submitter) {
case SUBMITTED_BY_BLOCK_LAYER:
+ case SUBMITTED_BY_SCSI_EXEC:
+ case SUBMITTED_BY_BLOCK_PT:
break;
case SUBMITTED_BY_SCSI_ERROR_HANDLER:
return scsi_eh_done(cmd);
@@ -1741,7 +1751,6 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
scsi_set_resid(cmd, 0);
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
- cmd->submitter = SUBMITTED_BY_BLOCK_LAYER;
blk_mq_start_request(req);
reason = scsi_dispatch_cmd(cmd);
@@ -3637,7 +3637,8 @@ static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len)
struct request *req;
struct scsi_cmnd *scmd;
- req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM);
+ req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(req))
return PTR_ERR(req);
@@ -1744,7 +1744,8 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
* not expect an EWOULDBLOCK from this condition.
*/
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,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq))
return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
@@ -933,7 +933,8 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
struct bio *bio;
int ret;
- rq = scsi_alloc_request(disk->queue, REQ_OP_DRV_IN, 0);
+ rq = scsi_alloc_request(disk->queue, REQ_OP_DRV_IN, 0,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(rq))
return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
@@ -545,8 +545,9 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
struct scsi_cmnd *scmd;
req = scsi_alloc_request(SRpnt->stp->device->request_queue,
- data_direction == DMA_TO_DEVICE ?
- REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
+ data_direction == DMA_TO_DEVICE ?
+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(req))
return PTR_ERR(req);
scmd = blk_mq_rq_to_pdu(req);
@@ -941,8 +941,9 @@ pscsi_execute_cmd(struct se_cmd *cmd)
sense_reason_t ret;
req = scsi_alloc_request(pdv->pdv_sd->request_queue,
- cmd->data_direction == DMA_TO_DEVICE ?
- REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
+ cmd->data_direction == DMA_TO_DEVICE ?
+ REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0,
+ SUBMITTED_BY_BLOCK_PT);
if (IS_ERR(req))
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -63,6 +63,8 @@ enum scsi_cmnd_submitter {
SUBMITTED_BY_BLOCK_LAYER = 0,
SUBMITTED_BY_SCSI_ERROR_HANDLER = 1,
SUBMITTED_BY_SCSI_RESET_IOCTL = 2,
+ SUBMITTED_BY_SCSI_EXEC = 3,
+ SUBMITTED_BY_BLOCK_PT = 4,
} __packed;
struct scsi_cmnd {
@@ -387,6 +389,7 @@ 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, blk_opf_t opf,
- blk_mq_req_flags_t flags);
+ blk_mq_req_flags_t flags,
+ enum scsi_cmnd_submitter submitter);
#endif /* _SCSI_SCSI_CMND_H */
This adds 2 new SUBMITTED types so we know if a command was queued because of a scsi_execute user vs SG IO/tape/cd. In the next patch we can then handle errors differently based on what submitted the cmd. For scsi_execute we can let the scsi error handler retry like normal if the user has requested retries. And for other users we can fail fast for device errors like is expected by users like SG IO. Signed-off-by: Mike Christie <michael.christie@oracle.com> --- drivers/block/pktcdvd.c | 3 ++- drivers/scsi/scsi_bsg.c | 3 ++- drivers/scsi/scsi_error.c | 3 ++- drivers/scsi/scsi_ioctl.c | 6 ++++-- drivers/scsi/scsi_lib.c | 23 ++++++++++++++++------- drivers/scsi/sd.c | 3 ++- drivers/scsi/sg.c | 3 ++- drivers/scsi/sr.c | 3 ++- drivers/scsi/st.c | 5 +++-- drivers/target/target_core_pscsi.c | 5 +++-- include/scsi/scsi_cmnd.h | 5 ++++- 11 files changed, 42 insertions(+), 20 deletions(-)