diff options
-rw-r--r-- | drivers/target/target_core_alua.c | 135 | ||||
-rw-r--r-- | drivers/target/target_core_alua.h | 1 | ||||
-rw-r--r-- | drivers/target/target_core_configfs.c | 28 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 12 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 38 | ||||
-rw-r--r-- | include/target/target_core_base.h | 13 |
7 files changed, 65 insertions, 166 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 15c127b780d..b3302a9200a 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -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; diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index 5019157ffe6..a2af8aa15b9 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h @@ -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 */ diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 3d5570da41e..7b473b66da7 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -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; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 4ae1d391382..3c3a3019ce7 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -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; diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 862e4347f68..7ecac453b11 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -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; } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index e996bdf480c..c4c931b525d 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -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, diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 892a93dec19..11b0a68dc76 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -221,16 +221,6 @@ enum tcm_tmrsp_table { }; /* - * 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 */ typedef enum { @@ -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; |