target: Make standard INQUIRY return 'not connected' for tpg_virt_lun0
This patch changes target_emulate_inquiry_std() to set the 'not connected' (0x35) bit in standard INQUIRY response data when we are processing a request to a virtual LUN=0 mapping from struct se_device *g_lun0_dev that have been setup for us in transport_lookup_cmd_lun(). This addresses an issue where qla2xxx FC clients need to be able to create demo-mode I_T FC Nexuses by default, but should not be exposing the default set of TPG LUNs to all FC clients. This includes adding an new optional target_core_fabric_ops->tpg_check_demo_mode_login_only() caller to allow demo_mode nexuses to skip the old default of bulding a demo-mode MappedLUNs list via core_tpg_add_node_to_devs(). (roland: Add missing tpg_check_demo_mode_login_only check in core_dev_add_lun) Reported-by: Roland Dreier <roland@purestorage.com> Cc: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: Nicholas Bellinger <nab@risingtidesystems.com>
This commit is contained in:
Родитель
eb39d34004
Коммит
052605c6ca
|
@ -67,6 +67,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
struct se_lun *lun = cmd->se_lun;
|
struct se_lun *lun = cmd->se_lun;
|
||||||
struct se_device *dev = cmd->se_dev;
|
struct se_device *dev = cmd->se_dev;
|
||||||
|
struct se_portal_group *tpg = lun->lun_sep->sep_tpg;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,9 +82,13 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
|
||||||
|
|
||||||
buf = transport_kmap_first_data_page(cmd);
|
buf = transport_kmap_first_data_page(cmd);
|
||||||
|
|
||||||
|
if (dev == tpg->tpg_virt_lun0.lun_se_dev) {
|
||||||
|
buf[0] = 0x3f; /* Not connected */
|
||||||
|
} else {
|
||||||
buf[0] = dev->transport->get_device_type(dev);
|
buf[0] = dev->transport->get_device_type(dev);
|
||||||
if (buf[0] == TYPE_TAPE)
|
if (buf[0] == TYPE_TAPE)
|
||||||
buf[1] = 0x80;
|
buf[1] = 0x80;
|
||||||
|
}
|
||||||
buf[2] = dev->transport->get_device_rev(dev);
|
buf[2] = dev->transport->get_device_rev(dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1346,7 +1346,9 @@ struct se_lun *core_dev_add_lun(
|
||||||
struct se_node_acl *acl;
|
struct se_node_acl *acl;
|
||||||
spin_lock_bh(&tpg->acl_node_lock);
|
spin_lock_bh(&tpg->acl_node_lock);
|
||||||
list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
|
list_for_each_entry(acl, &tpg->acl_node_list, acl_list) {
|
||||||
if (acl->dynamic_node_acl) {
|
if (acl->dynamic_node_acl &&
|
||||||
|
(!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only ||
|
||||||
|
!tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg))) {
|
||||||
spin_unlock_bh(&tpg->acl_node_lock);
|
spin_unlock_bh(&tpg->acl_node_lock);
|
||||||
core_tpg_add_node_to_devs(acl, tpg);
|
core_tpg_add_node_to_devs(acl, tpg);
|
||||||
spin_lock_bh(&tpg->acl_node_lock);
|
spin_lock_bh(&tpg->acl_node_lock);
|
||||||
|
|
|
@ -298,7 +298,15 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
|
||||||
tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
|
tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Here we only create demo-mode MappedLUNs from the active
|
||||||
|
* TPG LUNs if the fabric is not explictly asking for
|
||||||
|
* tpg_check_demo_mode_login_only() == 1.
|
||||||
|
*/
|
||||||
|
if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only != NULL) &&
|
||||||
|
(tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg) == 1))
|
||||||
|
do { ; } while (0);
|
||||||
|
else
|
||||||
core_tpg_add_node_to_devs(acl, tpg);
|
core_tpg_add_node_to_devs(acl, tpg);
|
||||||
|
|
||||||
spin_lock_bh(&tpg->acl_node_lock);
|
spin_lock_bh(&tpg->acl_node_lock);
|
||||||
|
|
|
@ -27,6 +27,12 @@ struct target_core_fabric_ops {
|
||||||
int (*tpg_check_demo_mode_cache)(struct se_portal_group *);
|
int (*tpg_check_demo_mode_cache)(struct se_portal_group *);
|
||||||
int (*tpg_check_demo_mode_write_protect)(struct se_portal_group *);
|
int (*tpg_check_demo_mode_write_protect)(struct se_portal_group *);
|
||||||
int (*tpg_check_prod_mode_write_protect)(struct se_portal_group *);
|
int (*tpg_check_prod_mode_write_protect)(struct se_portal_group *);
|
||||||
|
/*
|
||||||
|
* Optionally used by fabrics to allow demo-mode login, but not
|
||||||
|
* expose any TPG LUNs, and return 'not connected' in standard
|
||||||
|
* inquiry response
|
||||||
|
*/
|
||||||
|
int (*tpg_check_demo_mode_login_only)(struct se_portal_group *);
|
||||||
struct se_node_acl *(*tpg_alloc_fabric_acl)(
|
struct se_node_acl *(*tpg_alloc_fabric_acl)(
|
||||||
struct se_portal_group *);
|
struct se_portal_group *);
|
||||||
void (*tpg_release_fabric_acl)(struct se_portal_group *,
|
void (*tpg_release_fabric_acl)(struct se_portal_group *,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче