diff mbox series

[2/4] scsi: Add new SUBMITTED types for passthrough

Message ID 20220810034155.20744-3-michael.christie@oracle.com
State New
Headers show
Series scsi: passthrough fixes/improvements | expand

Commit Message

Mike Christie Aug. 10, 2022, 3:41 a.m. UTC
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(-)

Comments

Christoph Hellwig Aug. 11, 2022, 12:21 p.m. UTC | #1
On Tue, Aug 09, 2022 at 10:41:53PM -0500, Mike Christie wrote:
> 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.

But do we really want to handle errors differently based on the
submitter, or based on what the submitter asks us to do?  I.e. why
should this be based on the callchain vs the intention?
diff mbox series

Patch

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 4cea3b08087e..0bc69c56f36b 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -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);
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 96ee35256a16..2d4ae1383892 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -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;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 448748e3fba5..ac4471e33a9c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -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);
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 729e309e6034..d8bb638f835d 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -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;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 3ef85c8b689d..c689c28d6181 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -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);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8f79fa6318fe..550df58f228a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -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);
 
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 340b050ad28d..3f10cedf6f03 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -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);
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index a278b739d0c5..8b9f44079aa6 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -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);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 850172a2b8f1..b981a186e195 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -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);
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index e6a967ddc08c..a5886ddcf075 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -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;
 
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index bac55decf900..1ade0d454874 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -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 */