We always support ALUA for virtual backends, and never for physical ones.  Simplify
the code to just deal with these two cases and remove the superflous abstractions.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
Christoph Hellwig 2012-10-10 17:37:16 -04:00 коммит произвёл Nicholas Bellinger
Родитель d977f4377f
Коммит c87fbd5656
7 изменённых файлов: 65 добавлений и 166 удалений

Просмотреть файл

@ -522,40 +522,26 @@ static inline int core_alua_state_transition(
}
/*
* Used for alua_type SPC_ALUA_PASSTHROUGH and SPC2_ALUA_DISABLED
* in transport_cmd_sequencer(). This function is assigned to
* struct t10_alua *->state_check() in core_setup_alua()
*/
static int core_alua_state_check_nop(
struct se_cmd *cmd,
unsigned char *cdb,
u8 *alua_ascq)
{
return 0;
}
/*
* Used for alua_type SPC3_ALUA_EMULATED in transport_cmd_sequencer().
* This function is assigned to struct t10_alua *->state_check() in
* core_setup_alua()
*
* Also, this function can return three different return codes to
* signal transport_generic_cmd_sequencer()
*
* return 1: Is used to signal LUN not accecsable, and check condition/not ready
* return 0: Used to signal success
* reutrn -1: Used to signal failure, and invalid cdb field
*/
static int core_alua_state_check(
struct se_cmd *cmd,
unsigned char *cdb,
u8 *alua_ascq)
int target_alua_state_check(struct se_cmd *cmd)
{
struct se_device *dev = cmd->se_dev;
unsigned char *cdb = cmd->t_task_cdb;
struct se_lun *lun = cmd->se_lun;
struct se_port *port = lun->lun_sep;
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;
if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV)
return 0;
if (!port)
return 0;
@ -564,11 +550,11 @@ static int core_alua_state_check(
* access state: OFFLINE
*/
if (atomic_read(&port->sep_tg_pt_secondary_offline)) {
*alua_ascq = ASCQ_04H_ALUA_OFFLINE;
pr_debug("ALUA: Got secondary offline status for local"
" target port\n");
*alua_ascq = ASCQ_04H_ALUA_OFFLINE;
return 1;
alua_ascq = ASCQ_04H_ALUA_OFFLINE;
ret = 1;
goto out;
}
/*
* Second, obtain the struct t10_alua_tg_pt_gp_member pointer to the
@ -593,14 +579,18 @@ static int core_alua_state_check(
switch (out_alua_state) {
case ALUA_ACCESS_STATE_ACTIVE_NON_OPTIMIZED:
return core_alua_state_nonoptimized(cmd, cdb,
nonop_delay_msecs, alua_ascq);
ret = core_alua_state_nonoptimized(cmd, cdb,
nonop_delay_msecs, &alua_ascq);
break;
case ALUA_ACCESS_STATE_STANDBY:
return core_alua_state_standby(cmd, cdb, alua_ascq);
ret = core_alua_state_standby(cmd, cdb, &alua_ascq);
break;
case ALUA_ACCESS_STATE_UNAVAILABLE:
return core_alua_state_unavailable(cmd, cdb, alua_ascq);
ret = core_alua_state_unavailable(cmd, cdb, &alua_ascq);
break;
case ALUA_ACCESS_STATE_TRANSITION:
return core_alua_state_transition(cmd, cdb, alua_ascq);
ret = core_alua_state_transition(cmd, cdb, &alua_ascq);
break;
/*
* OFFLINE is a secondary ALUA target port group access state, that is
* handled above with struct se_port->sep_tg_pt_secondary_offline=1
@ -609,10 +599,27 @@ static int core_alua_state_check(
default:
pr_err("Unknown ALUA access state: 0x%02x\n",
out_alua_state);
return -EINVAL;
ret = -EINVAL;
break;
}
return 0;
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 ret;
}
/*
@ -1264,13 +1271,9 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp)
void core_alua_free_lu_gp_mem(struct se_device *dev)
{
struct t10_alua *alua = &dev->t10_alua;
struct t10_alua_lu_gp *lu_gp;
struct t10_alua_lu_gp_member *lu_gp_mem;
if (alua->alua_type != SPC3_ALUA_EMULATED)
return;
lu_gp_mem = dev->dev_alua_lu_gp_mem;
if (!lu_gp_mem)
return;
@ -1538,13 +1541,9 @@ void core_alua_free_tg_pt_gp(
void core_alua_free_tg_pt_gp_mem(struct se_port *port)
{
struct t10_alua *alua = &port->sep_lun->lun_se_dev->t10_alua;
struct t10_alua_tg_pt_gp *tg_pt_gp;
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
if (alua->alua_type != SPC3_ALUA_EMULATED)
return;
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (!tg_pt_gp_mem)
return;
@ -1636,14 +1635,10 @@ static void __core_alua_drop_tg_pt_gp_mem(
ssize_t core_alua_show_tg_pt_gp_info(struct se_port *port, char *page)
{
struct config_item *tg_pt_ci;
struct t10_alua *alua = &port->sep_lun->lun_se_dev->t10_alua;
struct t10_alua_tg_pt_gp *tg_pt_gp;
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
ssize_t len = 0;
if (alua->alua_type != SPC3_ALUA_EMULATED)
return len;
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (!tg_pt_gp_mem)
return len;
@ -1686,13 +1681,9 @@ ssize_t core_alua_store_tg_pt_gp_info(
tpg = port->sep_tpg;
lun = port->sep_lun;
if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
pr_warn("SPC3_ALUA_EMULATED not enabled for"
" %s/tpgt_%hu/%s\n", tpg->se_tpg_tfo->tpg_get_wwn(tpg),
tpg->se_tpg_tfo->tpg_get_tag(tpg),
config_item_name(&lun->lun_group.cg_item));
return -EINVAL;
}
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (!tg_pt_gp_mem)
return 0;
if (count > TG_PT_GROUP_NAME_BUF) {
pr_err("ALUA Target Port Group alias too large!\n");
@ -1715,13 +1706,6 @@ ssize_t core_alua_store_tg_pt_gp_info(
if (!tg_pt_gp_new)
return -ENODEV;
}
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (!tg_pt_gp_mem) {
if (tg_pt_gp_new)
core_alua_put_tg_pt_gp_from_name(tg_pt_gp_new);
pr_err("NULL struct se_port->sep_alua_tg_pt_gp_mem pointer\n");
return -EINVAL;
}
spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
@ -2050,26 +2034,9 @@ ssize_t core_alua_store_secondary_write_metadata(
int core_setup_alua(struct se_device *dev)
{
struct t10_alua *alua = &dev->t10_alua;
struct t10_alua_lu_gp_member *lu_gp_mem;
/*
* If this device is from Target_Core_Mod/pSCSI, use the ALUA logic
* of the Underlying SCSI hardware. In Linux/SCSI terms, this can
* cause a problem because libata and some SATA RAID HBAs appear
* under Linux/SCSI, but emulate SCSI logic themselves.
*/
if ((dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) ||
(dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV &&
!dev->dev_attrib.emulate_alua)) {
pr_debug("%s: Using SPC_ALUA_PASSTHROUGH, no ALUA"
" emulation\n", dev->transport->name);
alua->alua_type = SPC_ALUA_PASSTHROUGH;
alua->alua_state_check = &core_alua_state_check_nop;
} else if (dev->transport->get_device_rev(dev) >= SCSI_3) {
pr_debug("%s: Enabling ALUA Emulation for SPC-3"
" device\n", dev->transport->name);
if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV &&
!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) {
struct t10_alua_lu_gp_member *lu_gp_mem;
/*
* Associate this struct se_device with the default ALUA
@ -2079,8 +2046,6 @@ int core_setup_alua(struct se_device *dev)
if (IS_ERR(lu_gp_mem))
return PTR_ERR(lu_gp_mem);
alua->alua_type = SPC3_ALUA_EMULATED;
alua->alua_state_check = &core_alua_state_check;
spin_lock(&lu_gp_mem->lu_gp_mem_lock);
__core_alua_attach_lu_gp_mem(lu_gp_mem,
default_lu_gp);
@ -2089,12 +2054,6 @@ int core_setup_alua(struct se_device *dev)
pr_debug("%s: Adding to default ALUA LU Group:"
" core/alua/lu_gps/default_lu_gp\n",
dev->transport->name);
} else {
pr_debug("%s: Disabling ALUA Emulation for SPC-2"
" device\n", dev->transport->name);
alua->alua_type = SPC2_ALUA_DISABLED;
alua->alua_state_check = &core_alua_state_check_nop;
}
return 0;

Просмотреть файл

@ -132,5 +132,6 @@ extern ssize_t core_alua_show_secondary_write_metadata(struct se_lun *,
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 int target_alua_state_check(struct se_cmd *cmd);
#endif /* TARGET_CORE_ALUA_H */

Просмотреть файл

@ -1615,15 +1615,9 @@ static ssize_t target_core_show_alua_lu_gp(void *p, char *page)
struct t10_alua_lu_gp_member *lu_gp_mem;
ssize_t len = 0;
if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
return len;
lu_gp_mem = dev->dev_alua_lu_gp_mem;
if (!lu_gp_mem) {
pr_err("NULL struct se_device->dev_alua_lu_gp_mem"
" pointer\n");
return -EINVAL;
}
if (!lu_gp_mem)
return 0;
spin_lock(&lu_gp_mem->lu_gp_mem_lock);
lu_gp = lu_gp_mem->lu_gp;
@ -1649,12 +1643,10 @@ static ssize_t target_core_store_alua_lu_gp(
unsigned char buf[LU_GROUP_NAME_BUF];
int move = 0;
if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) {
pr_warn("SPC3_ALUA_EMULATED not enabled for %s/%s\n",
config_item_name(&hba->hba_group.cg_item),
config_item_name(&dev->dev_group.cg_item));
return -EINVAL;
}
lu_gp_mem = dev->dev_alua_lu_gp_mem;
if (!lu_gp_mem)
return 0;
if (count > LU_GROUP_NAME_BUF) {
pr_err("ALUA LU Group Alias too large!\n");
return -EINVAL;
@ -1675,14 +1667,6 @@ static ssize_t target_core_store_alua_lu_gp(
if (!lu_gp_new)
return -ENODEV;
}
lu_gp_mem = dev->dev_alua_lu_gp_mem;
if (!lu_gp_mem) {
if (lu_gp_new)
core_alua_put_lu_gp_from_name(lu_gp_new);
pr_err("NULL struct se_device->dev_alua_lu_gp_mem"
" pointer\n");
return -EINVAL;
}
spin_lock(&lu_gp_mem->lu_gp_mem_lock);
lu_gp = lu_gp_mem->lu_gp;

Просмотреть файл

@ -556,7 +556,8 @@ static void core_export_port(
list_add_tail(&port->sep_list, &dev->dev_sep_list);
spin_unlock(&dev->se_port_lock);
if (dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
if (dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV &&
!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) {
tg_pt_gp_mem = core_alua_allocate_tg_pt_gp_mem(port);
if (IS_ERR(tg_pt_gp_mem) || !tg_pt_gp_mem) {
pr_err("Unable to allocate t10_alua_tg_pt"
@ -1398,7 +1399,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
dev->dev_attrib.emulate_tas = DA_EMULATE_TAS;
dev->dev_attrib.emulate_tpu = DA_EMULATE_TPU;
dev->dev_attrib.emulate_tpws = DA_EMULATE_TPWS;
dev->dev_attrib.emulate_alua = DA_EMULATE_ALUA;
dev->dev_attrib.enforce_pr_isids = DA_ENFORCE_PR_ISIDS;
dev->dev_attrib.is_nonrot = DA_IS_NONROT;
dev->dev_attrib.emulate_rest_reord = DA_EMULATE_REST_REORD;

Просмотреть файл

@ -95,8 +95,7 @@ static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf)
/*
* Enable SCCS and TPGS fields for Emulated ALUA
*/
if (dev->t10_alua.alua_type == SPC3_ALUA_EMULATED)
spc_fill_alua_data(lun->lun_sep, buf);
spc_fill_alua_data(lun->lun_sep, buf);
buf[7] = 0x2; /* CmdQue=1 */
@ -294,9 +293,6 @@ check_t10_vend_desc:
* Get the PROTOCOL IDENTIFIER as defined by spc4r17
* section 7.5.1 Table 362
*/
if (dev->t10_alua.alua_type != SPC3_ALUA_EMULATED)
goto check_scsi_name;
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (!tg_pt_gp_mem)
goto check_lu_gp;
@ -1083,8 +1079,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
* MAINTENANCE_IN from SCC-2
* Check for emulated MI_REPORT_TARGET_PGS
*/
if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS &&
dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS) {
cmd->execute_cmd =
target_emulate_report_target_port_groups;
}
@ -1102,8 +1097,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
* MAINTENANCE_OUT from SCC-2
* Check for emulated MO_SET_TARGET_PGS.
*/
if (cdb[1] == MO_SET_TARGET_PGS &&
dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) {
if (cdb[1] == MO_SET_TARGET_PGS) {
cmd->execute_cmd =
target_emulate_set_target_port_groups;
}

Просмотреть файл

@ -70,7 +70,6 @@ static void transport_handle_queue_full(struct se_cmd *cmd,
static int transport_generic_get_mem(struct se_cmd *cmd);
static int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
static void transport_put_cmd(struct se_cmd *cmd);
static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq);
static void target_complete_ok_work(struct work_struct *work);
int init_se_kmem_caches(void)
@ -1103,7 +1102,6 @@ int target_setup_cmd_from_cdb(
unsigned char *cdb)
{
struct se_device *dev = cmd->se_dev;
u8 alua_ascq = 0;
unsigned long flags;
int ret;
@ -1153,26 +1151,13 @@ int target_setup_cmd_from_cdb(
return -EINVAL;
}
ret = dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq);
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..
*/
if (ret > 0) {
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);
transport_set_sense_codes(cmd, 0x04, alua_ascq);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY;
return -EINVAL;
}
ret = target_alua_state_check(cmd);
if (ret) {
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
if (ret > 0)
cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY;
else
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
}
@ -2640,17 +2625,6 @@ static int transport_get_sense_codes(
return 0;
}
static int transport_set_sense_codes(
struct se_cmd *cmd,
u8 asc,
u8 ascq)
{
cmd->scsi_asc = asc;
cmd->scsi_ascq = ascq;
return 0;
}
int transport_send_check_condition_and_sense(
struct se_cmd *cmd,
u8 reason,

Просмотреть файл

@ -220,16 +220,6 @@ enum tcm_tmrsp_table {
TMR_FUNCTION_REJECTED = 255,
};
/*
* Used by TCM Core internally to signal if ALUA emulation is enabled or
* disabled, or running in with TCM/pSCSI passthrough mode
*/
typedef enum {
SPC_ALUA_PASSTHROUGH,
SPC2_ALUA_DISABLED,
SPC3_ALUA_EMULATED
} t10_alua_index_t;
/*
* Used for target SCSI statistics
*/
@ -243,7 +233,6 @@ typedef enum {
struct se_cmd;
struct t10_alua {
t10_alua_index_t alua_type;
/* ALUA Target Port Group ID */
u16 alua_tg_pt_gps_counter;
u32 alua_tg_pt_gps_count;
@ -253,7 +242,6 @@ struct t10_alua {
struct t10_alua_tg_pt_gp *default_tg_pt_gp;
/* Used for default ALUA Target Port Group ConfigFS group */
struct config_group alua_tg_pt_gps_group;
int (*alua_state_check)(struct se_cmd *, unsigned char *, u8 *);
struct list_head tg_pt_gps_list;
};
@ -605,7 +593,6 @@ struct se_dev_attrib {
int emulate_tas;
int emulate_tpu;
int emulate_tpws;
int emulate_alua;
int enforce_pr_isids;
int is_nonrot;
int emulate_rest_reord;