diff mbox series

[RFC,v1,4/8] scsi: Complete multipath request

Message ID 20241109044529.992935-5-himanshu.madhani@oracle.com (mailing list archive)
State Changes Requested
Headers show
Series scsi: Multipath support for scsi disk devices. | expand

Commit Message

Himanshu Madhani Nov. 9, 2024, 4:45 a.m. UTC
From: Himanshu Madhani <himanshu.madhani@oracle.com>

Add check for multipath reqeust when scsi_complete is called.
For error handling case, call scsi_mpath_failover_req() to
complete the multipath IO.

Signed-off-by: Himanshu Madhani <himanshu.madhani@oracle.com>
---
 drivers/scsi/scsi_lib.c | 25 +++++++++++++++++++++++++
 include/scsi/scsi.h     |  1 +
 2 files changed, 26 insertions(+)
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 0561b318dade..1c8113abc154 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -33,6 +33,7 @@ 
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport.h> /* scsi_init_limits() */
+#include <scsi/scsi_multipath.h>
 #include <scsi/scsi_dh.h>
 
 #include <trace/events/scsi.h>
@@ -620,6 +621,14 @@  static void scsi_run_queue_async(struct scsi_device *sdev)
 	}
 }
 
+static inline void __scsi_mpath_end_request(struct request *req,
+    blk_status_t status)
+{
+	if (req->cmd_flags & REQ_SCSI_MPATH)
+		scsi_mpath_end_request(req);
+	blk_mq_end_request(req, status);
+}
+
 /* Returns false when no more bytes to process, true if there are more */
 static bool scsi_end_request(struct request *req, blk_status_t error,
 		unsigned int bytes)
@@ -661,6 +670,9 @@  static bool scsi_end_request(struct request *req, blk_status_t error,
 	 */
 	percpu_ref_get(&q->q_usage_counter);
 
+	if (req->cmd_flags & REQ_SCSI_MPATH)
+		scsi_mpath_end_request(req);
+
 	__blk_mq_end_request(req, error);
 
 	scsi_run_queue_async(sdev);
@@ -1528,6 +1540,9 @@  static void scsi_complete(struct request *rq)
 	case ADD_TO_MLQUEUE:
 		scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
 		break;
+	case FAILOVER:
+		scsi_mpath_failover_req(rq);
+		break;
 	default:
 		scsi_eh_scmd_add(cmd);
 		break;
@@ -1840,6 +1855,9 @@  static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
 	memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 	cmd->submitter = SUBMITTED_BY_BLOCK_LAYER;
 
+	if (req->cmd_flags & REQ_SCSI_MPATH)
+		scsi_mpath_start_request(req);
+
 	blk_mq_start_request(req);
 	reason = scsi_dispatch_cmd(cmd);
 	if (reason) {
@@ -2811,6 +2829,9 @@  EXPORT_SYMBOL(scsi_target_resume);
 
 static int __scsi_internal_device_block_nowait(struct scsi_device *sdev)
 {
+	if (scsi_mpath_enabled(sdev))
+		scsi_mpath_clear_current_path(sdev);
+
 	if (scsi_device_set_state(sdev, SDEV_BLOCK))
 		return scsi_device_set_state(sdev, SDEV_CREATED_BLOCK);
 
@@ -2927,6 +2948,10 @@  int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
 		return -EINVAL;
 	}
 
+	/* For multipath device set the path live */
+	if (scsi_mpath_enabled(sdev))
+		scsi_mpath_set_live(sdev);
+
 	/*
 	 * Try to transition the scsi device to SDEV_RUNNING or one of the
 	 * offlined states and goose the device queue if successful.
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 96b350366670..544153a01b3f 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -103,6 +103,7 @@  enum scsi_disposition {
 	TIMEOUT_ERROR		= 0x2007,
 	SCSI_RETURN_NOT_HANDLED	= 0x2008,
 	FAST_IO_FAIL		= 0x2009,
+	FAILOVER		= 0x2010,
 };
 
 /*