[PATCH 06/13] scsi: alua: Add scsi_alua_rtpg_run()

John Garry posted 13 patches 2 weeks, 6 days ago
[PATCH 06/13] scsi: alua: Add scsi_alua_rtpg_run()
Posted by John Garry 2 weeks, 6 days ago
Add a function to run rtpg and handle error codes - it does equivalent
handling as in alua_rtpg_work() from scsi_dh_alua.c

Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 drivers/scsi/scsi_alua.c | 33 +++++++++++++++++++++++++++++++--
 include/scsi/scsi_alua.h |  6 ++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_alua.c b/drivers/scsi/scsi_alua.c
index d8825ad7a1672..e4cb43ba645fa 100644
--- a/drivers/scsi/scsi_alua.c
+++ b/drivers/scsi/scsi_alua.c
@@ -48,7 +48,6 @@ static struct workqueue_struct *kalua_wq;
  * Returns SCSI_DH_RETRY if the sense code is NOT READY/ALUA TRANSITIONING,
  * SCSI_DH_OK if no error occurred, and SCSI_DH_IO otherwise.
  */
-__maybe_unused
 static int scsi_alua_tur(struct scsi_device *sdev)
 {
 	struct scsi_sense_hdr sense_hdr;
@@ -159,7 +158,6 @@ static char print_alua_state(unsigned char state)
  * Returns -ENODEV if the path is
  * found to be unusable.
  */
-__maybe_unused
 static int scsi_alua_rtpg(struct scsi_device *sdev)
 {
 	struct alua_data *alua = sdev->alua;
@@ -390,6 +388,37 @@ static int scsi_alua_rtpg(struct scsi_device *sdev)
 	return err;
 }
 
+int scsi_alua_rtpg_run(struct scsi_device *sdev)
+{
+	struct alua_data *alua = sdev->alua;
+	unsigned long flags;
+	int state, err;
+
+	spin_lock_irqsave(&alua->lock, flags);
+	state = alua->state;
+	spin_unlock_irqrestore(&alua->lock, flags);
+
+	if (state == SCSI_ACCESS_STATE_TRANSITIONING) {
+		if (scsi_alua_tur(sdev) == -EAGAIN) {
+			spin_lock_irqsave(&alua->lock, flags);
+			alua->interval = ALUA_RTPG_RETRY_DELAY;
+			spin_unlock_irqrestore(&alua->lock, flags);
+			return -EAGAIN;
+		}
+		/* Send RTPG on failure or if TUR indicates SUCCESS */
+	}
+
+	err = scsi_alua_rtpg(sdev);
+	spin_lock_irqsave(&alua->lock, flags);
+	if (err == -EAGAIN) {
+		alua->interval = ALUA_RTPG_RETRY_DELAY;
+		spin_unlock_irqrestore(&alua->lock, flags);
+		return -EAGAIN;
+	}
+	spin_unlock_irqrestore(&alua->lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(scsi_alua_rtpg_run);
 
 /*
  * scsi_alua_stpg - Issue a SET TARGET PORT GROUP command
diff --git a/include/scsi/scsi_alua.h b/include/scsi/scsi_alua.h
index 068277261ed9d..1eb5481f40bd4 100644
--- a/include/scsi/scsi_alua.h
+++ b/include/scsi/scsi_alua.h
@@ -30,10 +30,16 @@ struct alua_data {
 int scsi_alua_sdev_init(struct scsi_device *sdev);
 void scsi_alua_sdev_exit(struct scsi_device *sdev);
 
+int scsi_alua_rtpg_run(struct scsi_device *sdev);
+
 int scsi_alua_init(void);
 void scsi_exit_alua(void);
 #else //CONFIG_SCSI_ALUA
 
+static inline int scsi_alua_rtpg_run(struct scsi_device *sdev)
+{
+	return 0;
+}
 static inline int scsi_alua_sdev_init(struct scsi_device *sdev)
 {
 	return 0;
-- 
2.43.5