| From fcf29481fb8e106daad6688f2e898226ee928992 Mon Sep 17 00:00:00 2001 |
| From: Nicholas Bellinger <nab@linux-iscsi.org> |
| Date: Mon, 18 Feb 2013 18:00:33 -0800 |
| Subject: target: Fix lookup of dynamic NodeACLs during cached demo-mode operation |
| |
| From: Nicholas Bellinger <nab@linux-iscsi.org> |
| |
| commit fcf29481fb8e106daad6688f2e898226ee928992 upstream. |
| |
| This patch fixes a bug in core_tpg_check_initiator_node_acl() -> |
| core_tpg_get_initiator_node_acl() where a dynamically created |
| se_node_acl generated during session login would be skipped during |
| subsequent lookup due to the '!acl->dynamic_node_acl' check, causing |
| a new se_node_acl to be created with a duplicate ->initiatorname. |
| |
| This would occur when a fabric endpoint was configured with |
| TFO->tpg_check_demo_mode()=1 + TPF->tpg_check_demo_mode_cache()=1 |
| preventing the release of an existing se_node_acl during se_session |
| shutdown. |
| |
| Also, drop the unnecessary usage of core_tpg_get_initiator_node_acl() |
| within core_dev_init_initiator_node_lun_acl() that originally |
| required the extra '!acl->dynamic_node_acl' check, and just pass |
| the configfs provided se_node_acl pointer instead. |
| |
| Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/target/target_core_device.c | 13 ++++--------- |
| drivers/target/target_core_fabric_configfs.c | 4 ++-- |
| drivers/target/target_core_internal.h | 2 +- |
| drivers/target/target_core_tpg.c | 10 ++-------- |
| 4 files changed, 9 insertions(+), 20 deletions(-) |
| |
| --- a/drivers/target/target_core_device.c |
| +++ b/drivers/target/target_core_device.c |
| @@ -1483,24 +1483,18 @@ static struct se_lun *core_dev_get_lun(s |
| |
| struct se_lun_acl *core_dev_init_initiator_node_lun_acl( |
| struct se_portal_group *tpg, |
| + struct se_node_acl *nacl, |
| u32 mapped_lun, |
| - char *initiatorname, |
| int *ret) |
| { |
| struct se_lun_acl *lacl; |
| - struct se_node_acl *nacl; |
| |
| - if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) { |
| + if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { |
| pr_err("%s InitiatorName exceeds maximum size.\n", |
| tpg->se_tpg_tfo->get_fabric_name()); |
| *ret = -EOVERFLOW; |
| return NULL; |
| } |
| - nacl = core_tpg_get_initiator_node_acl(tpg, initiatorname); |
| - if (!nacl) { |
| - *ret = -EINVAL; |
| - return NULL; |
| - } |
| lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); |
| if (!lacl) { |
| pr_err("Unable to allocate memory for struct se_lun_acl.\n"); |
| @@ -1511,7 +1505,8 @@ struct se_lun_acl *core_dev_init_initiat |
| INIT_LIST_HEAD(&lacl->lacl_list); |
| lacl->mapped_lun = mapped_lun; |
| lacl->se_lun_nacl = nacl; |
| - snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); |
| + snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", |
| + nacl->initiatorname); |
| |
| return lacl; |
| } |
| --- a/drivers/target/target_core_fabric_configfs.c |
| +++ b/drivers/target/target_core_fabric_configfs.c |
| @@ -357,8 +357,8 @@ static struct config_group *target_fabri |
| goto out; |
| } |
| |
| - lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, |
| - config_item_name(acl_ci), &ret); |
| + lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl, |
| + mapped_lun, &ret); |
| if (!lacl) { |
| ret = -EINVAL; |
| goto out; |
| --- a/drivers/target/target_core_internal.h |
| +++ b/drivers/target/target_core_internal.h |
| @@ -61,7 +61,7 @@ struct se_lun *core_dev_add_lun(struct s |
| int core_dev_del_lun(struct se_portal_group *, u32); |
| struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); |
| struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, |
| - u32, char *, int *); |
| + struct se_node_acl *, u32, int *); |
| int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, |
| struct se_lun_acl *, u32, u32); |
| int core_dev_del_initiator_node_lun_acl(struct se_portal_group *, |
| --- a/drivers/target/target_core_tpg.c |
| +++ b/drivers/target/target_core_tpg.c |
| @@ -114,16 +114,10 @@ struct se_node_acl *core_tpg_get_initiat |
| struct se_node_acl *acl; |
| |
| spin_lock_irq(&tpg->acl_node_lock); |
| - list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { |
| - if (!strcmp(acl->initiatorname, initiatorname) && |
| - !acl->dynamic_node_acl) { |
| - spin_unlock_irq(&tpg->acl_node_lock); |
| - return acl; |
| - } |
| - } |
| + acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname); |
| spin_unlock_irq(&tpg->acl_node_lock); |
| |
| - return NULL; |
| + return acl; |
| } |
| |
| /* core_tpg_add_node_to_devs(): |