Skip to content

Commit

Permalink
target: simplify alua support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Nov 7, 2012
1 parent d977f43 commit c87fbd5
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 166 deletions.
135 changes: 47 additions & 88 deletions drivers/target/target_core_alua.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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;
}

/*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/target/target_core_alua.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
28 changes: 6 additions & 22 deletions drivers/target/target_core_configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/target/target_core_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 3 additions & 9 deletions drivers/target/target_core_spc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down Expand Up @@ -294,9 +293,6 @@ static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
* 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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit c87fbd5

Please sign in to comment.