From edb4607dc58949da9eb5788ff3696a6ba8d0a7c6 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 17 Feb 2016 03:08:01 +0000 Subject: [PATCH] [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 --- scst/include/scst.h | 1 + scst/src/dev_handlers/scst_vdisk.c | 11 +++++-- scst/src/scst_tg.c | 50 ++++++++++++++++++++++++------ 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/scst/include/scst.h b/scst/include/scst.h index 2ed26ee79..728db0f19 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -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); diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index a36a3136d..963f08664 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -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) { diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 783696316..fae553190 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -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.