From 052605c6caa3e1edf8eee8fe5fe6d53f5721f39a Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Tue, 26 Jul 2011 17:48:43 -0700 Subject: [PATCH] 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 Cc: Andrew Vasquez Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_cdb.c | 11 ++++++++--- drivers/target/target_core_device.c | 4 +++- drivers/target/target_core_tpg.c | 12 ++++++++++-- include/target/target_core_fabric_ops.h | 6 ++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 8ae09a1bdf74..d095408dbd5f 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -67,6 +67,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) { struct se_lun *lun = cmd->se_lun; struct se_device *dev = cmd->se_dev; + struct se_portal_group *tpg = lun->lun_sep->sep_tpg; unsigned char *buf; /* @@ -81,9 +82,13 @@ target_emulate_inquiry_std(struct se_cmd *cmd) buf = transport_kmap_first_data_page(cmd); - buf[0] = dev->transport->get_device_type(dev); - if (buf[0] == TYPE_TAPE) - buf[1] = 0x80; + if (dev == tpg->tpg_virt_lun0.lun_se_dev) { + buf[0] = 0x3f; /* Not connected */ + } else { + buf[0] = dev->transport->get_device_type(dev); + if (buf[0] == TYPE_TAPE) + buf[1] = 0x80; + } buf[2] = dev->transport->get_device_rev(dev); /* diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index b38b6c993e65..ec3fbcda3e3c 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1346,7 +1346,9 @@ struct se_lun *core_dev_add_lun( struct se_node_acl *acl; spin_lock_bh(&tpg->acl_node_lock); 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); core_tpg_add_node_to_devs(acl, tpg); spin_lock_bh(&tpg->acl_node_lock); diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 4f1ba4c5ef11..718ccd1348b1 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -298,8 +298,16 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( tpg->se_tpg_tfo->tpg_release_fabric_acl(tpg, acl); return NULL; } - - core_tpg_add_node_to_devs(acl, tpg); + /* + * 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); spin_lock_bh(&tpg->acl_node_lock); list_add_tail(&acl->acl_list, &tpg->acl_node_list); diff --git a/include/target/target_core_fabric_ops.h b/include/target/target_core_fabric_ops.h index 2de8fe907596..126c675f4f14 100644 --- a/include/target/target_core_fabric_ops.h +++ b/include/target/target_core_fabric_ops.h @@ -27,6 +27,12 @@ struct target_core_fabric_ops { int (*tpg_check_demo_mode_cache)(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 *); + /* + * 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_portal_group *); void (*tpg_release_fabric_acl)(struct se_portal_group *, -- 2.30.2