@@ -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.
@@ -103,6 +103,7 @@ enum scsi_disposition {
TIMEOUT_ERROR = 0x2007,
SCSI_RETURN_NOT_HANDLED = 0x2008,
FAST_IO_FAIL = 0x2009,
+ FAILOVER = 0x2010,
};
/*