|
|
@@ -455,11 +455,26 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-static inline int core_alua_state_nonoptimized(
|
|
|
+static inline void set_ascq(struct se_cmd *cmd, u8 alua_ascq)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
|
|
|
+ * The ALUA additional sense code qualifier (ASCQ) is determined
|
|
|
+ * by the ALUA primary or secondary access state..
|
|
|
+ */
|
|
|
+ pr_debug("[%s]: ALUA TG Port not available, "
|
|
|
+ "SenseKey: NOT_READY, ASC/ASCQ: "
|
|
|
+ "0x04/0x%02x\n",
|
|
|
+ cmd->se_tfo->get_fabric_name(), alua_ascq);
|
|
|
+
|
|
|
+ cmd->scsi_asc = 0x04;
|
|
|
+ cmd->scsi_ascq = alua_ascq;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void core_alua_state_nonoptimized(
|
|
|
struct se_cmd *cmd,
|
|
|
unsigned char *cdb,
|
|
|
- int nonop_delay_msecs,
|
|
|
- u8 *alua_ascq)
|
|
|
+ int nonop_delay_msecs)
|
|
|
{
|
|
|
/*
|
|
|
* Set SCF_ALUA_NON_OPTIMIZED here, this value will be checked
|
|
|
@@ -468,13 +483,11 @@ static inline int core_alua_state_nonoptimized(
|
|
|
*/
|
|
|
cmd->se_cmd_flags |= SCF_ALUA_NON_OPTIMIZED;
|
|
|
cmd->alua_nonop_delay = nonop_delay_msecs;
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
static inline int core_alua_state_lba_dependent(
|
|
|
struct se_cmd *cmd,
|
|
|
- struct t10_alua_tg_pt_gp *tg_pt_gp,
|
|
|
- u8 *alua_ascq)
|
|
|
+ struct t10_alua_tg_pt_gp *tg_pt_gp)
|
|
|
{
|
|
|
struct se_device *dev = cmd->se_dev;
|
|
|
u64 segment_size, segment_mult, sectors, lba;
|
|
|
@@ -520,7 +533,7 @@ static inline int core_alua_state_lba_dependent(
|
|
|
}
|
|
|
if (!cur_map) {
|
|
|
spin_unlock(&dev->t10_alua.lba_map_lock);
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE);
|
|
|
return 1;
|
|
|
}
|
|
|
list_for_each_entry(map_mem, &cur_map->lba_map_mem_list,
|
|
|
@@ -531,11 +544,11 @@ static inline int core_alua_state_lba_dependent(
|
|
|
switch(map_mem->lba_map_mem_alua_state) {
|
|
|
case ALUA_ACCESS_STATE_STANDBY:
|
|
|
spin_unlock(&dev->t10_alua.lba_map_lock);
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY);
|
|
|
return 1;
|
|
|
case ALUA_ACCESS_STATE_UNAVAILABLE:
|
|
|
spin_unlock(&dev->t10_alua.lba_map_lock);
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE);
|
|
|
return 1;
|
|
|
default:
|
|
|
break;
|
|
|
@@ -548,8 +561,7 @@ static inline int core_alua_state_lba_dependent(
|
|
|
|
|
|
static inline int core_alua_state_standby(
|
|
|
struct se_cmd *cmd,
|
|
|
- unsigned char *cdb,
|
|
|
- u8 *alua_ascq)
|
|
|
+ unsigned char *cdb)
|
|
|
{
|
|
|
/*
|
|
|
* Allowed CDBs for ALUA_ACCESS_STATE_STANDBY as defined by
|
|
|
@@ -570,7 +582,7 @@ static inline int core_alua_state_standby(
|
|
|
case MI_REPORT_TARGET_PGS:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY);
|
|
|
return 1;
|
|
|
}
|
|
|
case MAINTENANCE_OUT:
|
|
|
@@ -578,7 +590,7 @@ static inline int core_alua_state_standby(
|
|
|
case MO_SET_TARGET_PGS:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY);
|
|
|
return 1;
|
|
|
}
|
|
|
case REQUEST_SENSE:
|
|
|
@@ -588,7 +600,7 @@ static inline int core_alua_state_standby(
|
|
|
case WRITE_BUFFER:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_STANDBY;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
@@ -597,8 +609,7 @@ static inline int core_alua_state_standby(
|
|
|
|
|
|
static inline int core_alua_state_unavailable(
|
|
|
struct se_cmd *cmd,
|
|
|
- unsigned char *cdb,
|
|
|
- u8 *alua_ascq)
|
|
|
+ unsigned char *cdb)
|
|
|
{
|
|
|
/*
|
|
|
* Allowed CDBs for ALUA_ACCESS_STATE_UNAVAILABLE as defined by
|
|
|
@@ -613,7 +624,7 @@ static inline int core_alua_state_unavailable(
|
|
|
case MI_REPORT_TARGET_PGS:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE);
|
|
|
return 1;
|
|
|
}
|
|
|
case MAINTENANCE_OUT:
|
|
|
@@ -621,7 +632,7 @@ static inline int core_alua_state_unavailable(
|
|
|
case MO_SET_TARGET_PGS:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE);
|
|
|
return 1;
|
|
|
}
|
|
|
case REQUEST_SENSE:
|
|
|
@@ -629,7 +640,7 @@ static inline int core_alua_state_unavailable(
|
|
|
case WRITE_BUFFER:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
@@ -638,8 +649,7 @@ static inline int core_alua_state_unavailable(
|
|
|
|
|
|
static inline int core_alua_state_transition(
|
|
|
struct se_cmd *cmd,
|
|
|
- unsigned char *cdb,
|
|
|
- u8 *alua_ascq)
|
|
|
+ unsigned char *cdb)
|
|
|
{
|
|
|
/*
|
|
|
* Allowed CDBs for ALUA_ACCESS_STATE_TRANSITION as defined by
|
|
|
@@ -654,7 +664,7 @@ static inline int core_alua_state_transition(
|
|
|
case MI_REPORT_TARGET_PGS:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_STATE_TRANSITION;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_STATE_TRANSITION);
|
|
|
return 1;
|
|
|
}
|
|
|
case REQUEST_SENSE:
|
|
|
@@ -662,7 +672,7 @@ static inline int core_alua_state_transition(
|
|
|
case WRITE_BUFFER:
|
|
|
return 0;
|
|
|
default:
|
|
|
- *alua_ascq = ASCQ_04H_ALUA_STATE_TRANSITION;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_STATE_TRANSITION);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
@@ -684,8 +694,6 @@ target_alua_state_check(struct se_cmd *cmd)
|
|
|
struct t10_alua_tg_pt_gp *tg_pt_gp;
|
|
|
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
|
|
|
int out_alua_state, nonop_delay_msecs;
|
|
|
- u8 alua_ascq;
|
|
|
- int ret;
|
|
|
|
|
|
if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)
|
|
|
return 0;
|
|
|
@@ -701,9 +709,8 @@ target_alua_state_check(struct se_cmd *cmd)
|
|
|
if (atomic_read(&port->sep_tg_pt_secondary_offline)) {
|
|
|
pr_debug("ALUA: Got secondary offline status for local"
|
|
|
" target port\n");
|
|
|
- alua_ascq = ASCQ_04H_ALUA_OFFLINE;
|
|
|
- ret = 1;
|
|
|
- goto out;
|
|
|
+ set_ascq(cmd, ASCQ_04H_ALUA_OFFLINE);
|
|
|
+ return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
}
|
|
|
/*
|
|
|
* Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the
|
|
|
@@ -731,20 +738,23 @@ target_alua_state_check(struct se_cmd *cmd)
|
|
|
|
|
|
switch (out_alua_state) {
|
|
|
case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
|
|
|
- ret = core_alua_state_nonoptimized(cmd, cdb,
|
|
|
- nonop_delay_msecs, &alua_ascq);
|
|
|
+ core_alua_state_nonoptimized(cmd, cdb, nonop_delay_msecs);
|
|
|
break;
|
|
|
case ALUA_ACCESS_STATE_STANDBY:
|
|
|
- ret = core_alua_state_standby(cmd, cdb, &alua_ascq);
|
|
|
+ if (core_alua_state_standby(cmd, cdb))
|
|
|
+ return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
break;
|
|
|
case ALUA_ACCESS_STATE_UNAVAILABLE:
|
|
|
- ret = core_alua_state_unavailable(cmd, cdb, &alua_ascq);
|
|
|
+ if (core_alua_state_unavailable(cmd, cdb))
|
|
|
+ return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
break;
|
|
|
case ALUA_ACCESS_STATE_TRANSITION:
|
|
|
- ret = core_alua_state_transition(cmd, cdb, &alua_ascq);
|
|
|
+ if (core_alua_state_transition(cmd, cdb))
|
|
|
+ return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
break;
|
|
|
case ALUA_ACCESS_STATE_LBA_DEPENDENT:
|
|
|
- ret = core_alua_state_lba_dependent(cmd, tg_pt_gp, &alua_ascq);
|
|
|
+ if (core_alua_state_lba_dependent(cmd, tg_pt_gp))
|
|
|
+ return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
break;
|
|
|
/*
|
|
|
* OFFLINE is a secondary ALUA target port group access state, that is
|
|
|
@@ -757,23 +767,6 @@ target_alua_state_check(struct se_cmd *cmd)
|
|
|
return TCM_INVALID_CDB_FIELD;
|
|
|
}
|
|
|
|
|
|
-out:
|
|
|
- if (ret > 0) {
|
|
|
- /*
|
|
|
- * Set SCSI additional sense code (ASC) to 'LUN Not Accessible';
|
|
|
- * The ALUA additional sense code qualifier (ASCQ) is determined
|
|
|
- * by the ALUA primary or secondary access state..
|
|
|
- */
|
|
|
- pr_debug("[%s]: ALUA TG Port not available, "
|
|
|
- "SenseKey: NOT_READY, ASC/ASCQ: "
|
|
|
- "0x04/0x%02x\n",
|
|
|
- cmd->se_tfo->get_fabric_name(), alua_ascq);
|
|
|
-
|
|
|
- cmd->scsi_asc = 0x04;
|
|
|
- cmd->scsi_ascq = alua_ascq;
|
|
|
- return TCM_CHECK_CONDITION_NOT_READY;
|
|
|
- }
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|