[ALUA][EXPERIMENTAL]: review and cleanup according to SPC-4 allowed and not allowed commands in various ALUA states

Also changes in INQUIRY the peripheral qualifier to 001b for UNAVAILABLE and OFFLINE states as required by SPC-4



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6802 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2016-02-17 03:08:01 +00:00
parent ab193f3835
commit edb4607dc5
3 changed files with 49 additions and 13 deletions
+1
View File
@@ -3825,6 +3825,7 @@ static inline void scst_sess_set_tgt_priv(struct scst_session *sess,
}
uint16_t scst_lookup_tg_id(struct scst_device *dev, struct scst_tgt *tgt);
enum scst_tg_state scst_get_alua_state(struct scst_device *dev, struct scst_tgt *tgt);
bool scst_alua_configured(struct scst_device *dev);
int scst_tg_get_group_info(void **buf, uint32_t *response_length,
struct scst_device *dev, uint8_t data_format);
+8 -3
View File
@@ -3547,7 +3547,6 @@ static bool vdisk_no_fd_allowed_commands(const struct scst_cmd *cmd)
switch (cmd->cdb[0]) {
case TEST_UNIT_READY:
case GET_EVENT_STATUS_NOTIFICATION:
case INQUIRY:
case MODE_SENSE:
case MODE_SENSE_10:
@@ -4369,6 +4368,7 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
uint8_t *buf;
struct scst_device *dev = cmd->dev;
struct scst_vdisk_dev *virt_dev = dev->dh_priv;
enum scst_tg_state alua_state;
TRACE_ENTRY();
@@ -4390,8 +4390,13 @@ static enum compl_status_e vdisk_exec_inquiry(struct vdisk_cmd_params *p)
goto out_put;
}
buf[0] = virt_dev->dummy ? SCSI_INQ_PQ_NOT_CON << 5 | 0x1f :
SCSI_INQ_PQ_CON << 5 | dev->type;
alua_state = scst_get_alua_state(cmd->dev, cmd->tgt);
if ((alua_state == SCST_TG_STATE_UNAVAILABLE) ||
(alua_state == SCST_TG_STATE_OFFLINE))
buf[0] = SCSI_INQ_PQ_NOT_CON << 5 | dev->type;
else
buf[0] = virt_dev->dummy ? SCSI_INQ_PQ_NOT_CON << 5 | 0x1f :
SCSI_INQ_PQ_CON << 5 | dev->type;
/* Vital Product */
if (cmd->cdb[1] & EVPD) {
if (cmd->cdb[2] == 0) {
+40 -10
View File
@@ -283,8 +283,6 @@ static int scst_tg_accept_standby(struct scst_cmd *cmd)
TRACE_ENTRY();
switch (cmd->cdb[0]) {
case TEST_UNIT_READY:
case GET_EVENT_STATUS_NOTIFICATION:
case INQUIRY:
case MODE_SENSE:
case MODE_SENSE_10:
@@ -348,18 +346,10 @@ static int scst_tg_accept_unav(struct scst_cmd *cmd)
TRACE_ENTRY();
switch (cmd->cdb[0]) {
case TEST_UNIT_READY:
case GET_EVENT_STATUS_NOTIFICATION:
case INQUIRY:
case MODE_SENSE:
case MODE_SENSE_10:
case READ_CAPACITY:
case REPORT_LUNS:
case REQUEST_SENSE:
case RELEASE:
case RELEASE_10:
case RESERVE:
case RESERVE_10:
case READ_BUFFER:
case WRITE_BUFFER:
res = SCST_ALUA_CHECK_OK;
@@ -458,6 +448,13 @@ static int scst_tg_accept_transitioning(struct scst_cmd *cmd)
goto out;
}
break;
case MAINTENANCE_IN:
switch (cmd->cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
res = SCST_ALUA_CHECK_OK;
goto out;
}
break;
}
if (cmd->already_transitioning)
@@ -1443,6 +1440,39 @@ out_unlock:
}
EXPORT_SYMBOL_GPL(scst_lookup_tg_id);
/**
* scst_get_alua_state() - returns ALUA state the target port group.
* @dev: SCST device.
* @tgt: SCST target.
*
* Returns a valid ALUA state (SCST_TG_STATE_OPTIMIZED is no ALUA configured)
*/
enum scst_tg_state scst_get_alua_state(struct scst_device *dev, struct scst_tgt *tgt)
{
struct scst_dev_group *dg;
struct scst_target_group *tg;
struct scst_tg_tgt *tg_tgt;
enum scst_tg_state res = SCST_TG_STATE_OPTIMIZED;
TRACE_ENTRY();
mutex_lock(&scst_dg_mutex);
dg = __lookup_dg_by_dev(dev);
if (!dg)
goto out_unlock;
tg_tgt = __lookup_dg_tgt(dg, tgt->tgt_name);
if (!tg_tgt)
goto out_unlock;
tg = tg_tgt->tg;
BUG_ON(!tg);
res = tg->state;
out_unlock:
mutex_unlock(&scst_dg_mutex);
TRACE_EXIT_RES(res);
return res;
}
EXPORT_SYMBOL_GPL(scst_get_alua_state);
/**
* scst_alua_configured() - Whether implicit ALUA has been configured.
* @dev: Pointer to the SCST device to verify.