These do the same as nvme_mpath_{start,end}_request()
Signed-off-by: John Garry <[email protected]>
---
drivers/scsi/sd.c | 55 +++++++++++++++++++++++++++++++++++
include/scsi/scsi_cmnd.h | 5 ++++
include/scsi/scsi_multipath.h | 1 +
3 files changed, 61 insertions(+)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 222e28ed44e9b..845d392456549 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1546,6 +1546,57 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
mempool_free(rq->special_vec.bv_page, sd_page_pool);
}
+#ifdef CONFIG_SCSI_MULTIPATH
+static void sd_mpath_start_command(struct scsi_cmnd *scmd)
+{
+ struct request *req = scsi_cmd_to_rq(scmd);
+ struct scsi_disk *sdkp = scsi_disk(req->q->disk);
+ struct sd_mpath_disk *sd_mpath_disk = sdkp->sd_mpath_disk;
+ struct mpath_disk *mpath_disk = sd_mpath_disk->mpath_disk;
+ struct scsi_device *sdev = scmd->device;
+ struct mpath_head *mpath_head = mpath_disk->mpath_head;
+ struct scsi_mpath_head *scsi_mpath_head = mpath_head->drvdata;
+ struct gendisk *disk = mpath_disk->disk;
+
+ if (mpath_qd_iopolicy(&scsi_mpath_head->iopolicy) &&
+ !(scmd->flags & SCMD_MPATH_CNT_ACTIVE)) {
+ struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev;
+
+ atomic_inc(&scsi_mpath_dev->nr_active);
+ scmd->flags |= SCMD_MPATH_CNT_ACTIVE;
+ }
+
+ if (!blk_queue_io_stat(disk->queue) || blk_rq_is_passthrough(req) ||
+ (scmd->flags & SCMD_MPATH_IO_STATS))
+ return;
+
+ scmd->flags |= SCMD_MPATH_IO_STATS;
+ scmd->start_time = bdev_start_io_acct(disk->part0, req_op(req),
+ jiffies);
+}
+
+static void sd_mpath_end_command(struct scsi_cmnd *scmd)
+{
+ struct request *req = scsi_cmd_to_rq(scmd);
+ struct scsi_disk *sdkp = scsi_disk(req->q->disk);
+ struct sd_mpath_disk *sd_mpath_disk = sdkp->sd_mpath_disk;
+ struct mpath_disk *mpath_disk = sd_mpath_disk->mpath_disk;
+ struct scsi_device *sdev = scmd->device;
+
+ if (scmd->flags & SCMD_MPATH_CNT_ACTIVE) {
+ struct scsi_mpath_device *scsi_mpath_dev = sdev->scsi_mpath_dev;
+
+ atomic_dec_if_positive(&scsi_mpath_dev->nr_active);
+ }
+
+ if (!(scmd->flags & SCMD_MPATH_IO_STATS))
+ return;
+ bdev_end_io_acct(mpath_disk->disk->part0, req_op(req),
+ blk_rq_bytes(req) >> SECTOR_SHIFT,
+ scmd->start_time);
+}
+#endif
+
static bool sd_need_revalidate(struct gendisk *disk, struct scsi_disk *sdkp)
{
if (sdkp->device->removable || sdkp->write_prot) {
@@ -4468,6 +4519,10 @@ static struct scsi_driver sd_template = {
.resume = sd_resume,
.init_command = sd_init_command,
.uninit_command = sd_uninit_command,
+ #ifdef CONFIG_SCSI_MULTIPATH
+ .mpath_start_cmd = sd_mpath_start_command,
+ .mpath_end_cmd = sd_mpath_end_command,
+ #endif
.done = sd_done,
.eh_action = sd_eh_action,
.eh_reset = sd_eh_reset,
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 8ecfb94049db5..c6571a36e577b 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -60,6 +60,8 @@ struct scsi_pointer {
#define SCMD_FAIL_IF_RECOVERING (1 << 4)
/* flags preserved across unprep / reprep */
#define SCMD_PRESERVED_FLAGS (SCMD_INITIALIZED | SCMD_FAIL_IF_RECOVERING)
+#define SCMD_MPATH_IO_STATS (1 << 5)
+#define SCMD_MPATH_CNT_ACTIVE (1 << 6)
/* for scmd->state */
#define SCMD_STATE_COMPLETE 0
@@ -139,6 +141,9 @@ struct scsi_cmnd {
* to release this memory. (The memory
* obtained by scsi_malloc is guaranteed
* to be at an address < 16Mb). */
+ #ifdef CONFIG_SCSI_MULTIPATH
+ unsigned long start_time;
+ #endif
int result; /* Status code from lower level driver */
};
diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h
index cb63c6536b854..2011447f482d6 100644
--- a/include/scsi/scsi_multipath.h
+++ b/include/scsi/scsi_multipath.h
@@ -36,6 +36,7 @@ struct scsi_mpath_device {
struct mpath_device mpath_device;
struct scsi_device *sdev;
int index;
+ atomic_t nr_active;
struct scsi_mpath_head *scsi_mpath_head;
char device_id_str[SCSI_MPATH_DEVICE_ID_LEN];
--
2.43.5