[2/2] target: set ALUA_TG_PT_STANDBY if a backing store is in standby mode

Submitted by Andrei Vagin on Feb. 27, 2018, 2:10 a.m.

Details

Message ID 1519697410-26352-2-git-send-email-avagin@openvz.org
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrei Vagin Feb. 27, 2018, 2:10 a.m.
[This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing at http://aka.ms/LearnAboutSpoofing]

HA can decide to switch the current target into standby mode and switch
another target into active mode. In this case, an image lease will be
granted to the new target, and the current target has to complete all
commands and set the ASCQ_04H_ALUA_TG_PT_STANDBY bit in there status.

https://pmc.acronis.com/browse/VSTOR-7879

Signed-off-by: Andrei Vagin <avagin@openvz.org>
---
 drivers/target/target_core_alua.c      |  5 +++++
 drivers/target/target_core_alua.h      |  1 +
 drivers/target/target_core_iblock.c    | 10 ++++++++--
 drivers/target/target_core_transport.c |  8 ++++++--
 include/target/target_core_base.h      |  1 +
 5 files changed, 21 insertions(+), 4 deletions(-)

--
1.8.3.1

Patch hide | download patch | download mbox

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index f1c1733..827de6f 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -473,6 +473,11 @@  static inline void set_ascq(struct se_cmd *cmd, u8 alua_ascq)
        cmd->scsi_ascq = alua_ascq;
 }

+void core_alua_set_ascq(struct se_cmd *cmd, u8 alua_ascq)
+{
+       set_ascq(cmd, alua_ascq);
+}
+
 static inline void core_alua_state_nonoptimized(
        struct se_cmd *cmd,
        unsigned char *cdb,
diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h
index df1cf49..5f79d4b 100644
--- a/drivers/target/target_core_alua.h
+++ b/drivers/target/target_core_alua.h
@@ -161,5 +161,6 @@  extern ssize_t core_alua_store_secondary_write_metadata(struct se_lun *,
                                        const char *, size_t);
 extern int core_setup_alua(struct se_device *);
 extern sense_reason_t target_alua_state_check(struct se_cmd *cmd);
+extern void core_alua_set_ascq(struct se_cmd *cmd, u8 alua_ascq);

 #endif /* TARGET_CORE_ALUA_H */
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index b451916..c68e255 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -297,9 +297,15 @@  static void iblock_complete_cmd(struct se_cmd *cmd)
        if (!atomic_dec_and_test(&ibr->pending))
                return;

-       if (atomic_read(&ibr->ib_bio_err_cnt))
+       if (atomic_read(&ibr->ib_bio_err_cnt)) {
+               struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev);
+               struct request_queue *q = bdev_get_queue(ib_dev->ibd_bd);
+
+               if (blk_queue_standby(q))
+                       cmd->transport_state |= CMD_T_STANDBY;
+
                status = SAM_STAT_CHECK_CONDITION;
-       else
+       } else
                status = SAM_STAT_GOOD;

        target_complete_cmd(cmd, status);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1682d60..5d2487b 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -629,6 +629,7 @@  void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 static void target_complete_failure_work(struct work_struct *work)
 {
        struct se_cmd *cmd = container_of(work, struct se_cmd, work);
+       sense_reason_t sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

        switch (cmd->data_direction) {
        case DMA_FROM_DEVICE:
@@ -643,8 +644,11 @@  static void target_complete_failure_work(struct work_struct *work)
                break;
        }

-       transport_generic_request_failure(cmd,
-                       TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE);
+       if (cmd->transport_state & CMD_T_STANDBY) {
+               core_alua_set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY);
+               sense_reason = TCM_CHECK_CONDITION_NOT_READY;
+       }
+       transport_generic_request_failure(cmd, sense_reason);
 }

 /*
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 196d4df..2889350 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -538,6 +538,7 @@  struct se_cmd {
 #define CMD_T_DEV_ACTIVE       (1 << 7)
 #define CMD_T_REQUEST_STOP     (1 << 8)
 #define CMD_T_BUSY             (1 << 9)
+#define CMD_T_STANDBY          (1 << 31)
        spinlock_t              t_state_lock;
        struct completion       t_transport_stop_comp;