[RHEL7,COMMIT] target: set ALUA_TG_PT_STANDBY if a backing store is in standby mode

Submitted by Konstantin Khorenko on March 1, 2018, 8:07 a.m.

Details

Message ID 201803010807.w2187ZP4007482@finist_ce7.work
State New
Series "target: set ALUA_TG_PT_STANDBY if a backing store is in standby mode"
Headers show

Commit Message

Konstantin Khorenko March 1, 2018, 8:07 a.m.
The commit is pushed to "branch-rh7-3.10.0-693.17.1.vz7.45.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.17.1.vz7.45.6
------>
commit d96dbda7b4a166e3ce8034b8f168304d32b47565
Author: Andrei Vagin <avagin@openvz.org>
Date:   Thu Mar 1 11:07:34 2018 +0300

    target: set ALUA_TG_PT_STANDBY if a backing store is in standby mode
    
    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(-)

Patch hide | download patch | download mbox

diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index f1c17335ac95..827de6f2cd17 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 df1cf4927080..5f79d4b3ef3e 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 b451916b4b0e..c68e2555edf4 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 b27c17bda01d..870d0472145e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -630,6 +630,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:
@@ -644,8 +645,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 7b6699c0c095..3b847b78bac8 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -539,6 +539,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;