diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-02-18 21:00:33 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-02-18 21:47:20 -0500 |
commit | fcf29481fb8e106daad6688f2e898226ee928992 (patch) | |
tree | dabde5fb8908c786e8f22019d552c62961f7d007 | |
parent | 71f41fe1fafae2e407ef19d8174207f7ff80b387 (diff) |
target: Fix lookup of dynamic NodeACLs during cached demo-mode operation
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.
Cc: <stable@vger.kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/target/target_core_device.c | 13 | ||||
-rw-r--r-- | drivers/target/target_core_fabric_configfs.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_internal.h | 2 | ||||
-rw-r--r-- | drivers/target/target_core_tpg.c | 10 |
4 files changed, 9 insertions, 20 deletions
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 6fb82f1abe5c..2e4d655471bc 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1226,24 +1226,18 @@ static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked | |||
1226 | 1226 | ||
1227 | struct se_lun_acl *core_dev_init_initiator_node_lun_acl( | 1227 | struct se_lun_acl *core_dev_init_initiator_node_lun_acl( |
1228 | struct se_portal_group *tpg, | 1228 | struct se_portal_group *tpg, |
1229 | struct se_node_acl *nacl, | ||
1229 | u32 mapped_lun, | 1230 | u32 mapped_lun, |
1230 | char *initiatorname, | ||
1231 | int *ret) | 1231 | int *ret) |
1232 | { | 1232 | { |
1233 | struct se_lun_acl *lacl; | 1233 | struct se_lun_acl *lacl; |
1234 | struct se_node_acl *nacl; | ||
1235 | 1234 | ||
1236 | if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) { | 1235 | if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { |
1237 | pr_err("%s InitiatorName exceeds maximum size.\n", | 1236 | pr_err("%s InitiatorName exceeds maximum size.\n", |
1238 | tpg->se_tpg_tfo->get_fabric_name()); | 1237 | tpg->se_tpg_tfo->get_fabric_name()); |
1239 | *ret = -EOVERFLOW; | 1238 | *ret = -EOVERFLOW; |
1240 | return NULL; | 1239 | return NULL; |
1241 | } | 1240 | } |
1242 | nacl = core_tpg_get_initiator_node_acl(tpg, initiatorname); | ||
1243 | if (!nacl) { | ||
1244 | *ret = -EINVAL; | ||
1245 | return NULL; | ||
1246 | } | ||
1247 | lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); | 1241 | lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); |
1248 | if (!lacl) { | 1242 | if (!lacl) { |
1249 | pr_err("Unable to allocate memory for struct se_lun_acl.\n"); | 1243 | pr_err("Unable to allocate memory for struct se_lun_acl.\n"); |
@@ -1254,7 +1248,8 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( | |||
1254 | INIT_LIST_HEAD(&lacl->lacl_list); | 1248 | INIT_LIST_HEAD(&lacl->lacl_list); |
1255 | lacl->mapped_lun = mapped_lun; | 1249 | lacl->mapped_lun = mapped_lun; |
1256 | lacl->se_lun_nacl = nacl; | 1250 | lacl->se_lun_nacl = nacl; |
1257 | snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); | 1251 | snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", |
1252 | nacl->initiatorname); | ||
1258 | 1253 | ||
1259 | return lacl; | 1254 | return lacl; |
1260 | } | 1255 | } |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index c57bbbc7a7d1..b932653358dd 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -355,8 +355,8 @@ static struct config_group *target_fabric_make_mappedlun( | |||
355 | goto out; | 355 | goto out; |
356 | } | 356 | } |
357 | 357 | ||
358 | lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, | 358 | lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl, |
359 | config_item_name(acl_ci), &ret); | 359 | mapped_lun, &ret); |
360 | if (!lacl) { | 360 | if (!lacl) { |
361 | ret = -EINVAL; | 361 | ret = -EINVAL; |
362 | goto out; | 362 | goto out; |
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index fdc51f8301a1..853bab60e362 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h | |||
@@ -46,7 +46,7 @@ struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u3 | |||
46 | int core_dev_del_lun(struct se_portal_group *, u32); | 46 | int core_dev_del_lun(struct se_portal_group *, u32); |
47 | struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); | 47 | struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); |
48 | struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, | 48 | struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, |
49 | u32, char *, int *); | 49 | struct se_node_acl *, u32, int *); |
50 | int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, | 50 | int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, |
51 | struct se_lun_acl *, u32, u32); | 51 | struct se_lun_acl *, u32, u32); |
52 | int core_dev_del_initiator_node_lun_acl(struct se_portal_group *, | 52 | int core_dev_del_initiator_node_lun_acl(struct se_portal_group *, |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 5192ac0337f7..9169d6a5d7e4 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -111,16 +111,10 @@ struct se_node_acl *core_tpg_get_initiator_node_acl( | |||
111 | struct se_node_acl *acl; | 111 | struct se_node_acl *acl; |
112 | 112 | ||
113 | spin_lock_irq(&tpg->acl_node_lock); | 113 | spin_lock_irq(&tpg->acl_node_lock); |
114 | list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { | 114 | acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname); |
115 | if (!strcmp(acl->initiatorname, initiatorname) && | ||
116 | !acl->dynamic_node_acl) { | ||
117 | spin_unlock_irq(&tpg->acl_node_lock); | ||
118 | return acl; | ||
119 | } | ||
120 | } | ||
121 | spin_unlock_irq(&tpg->acl_node_lock); | 115 | spin_unlock_irq(&tpg->acl_node_lock); |
122 | 116 | ||
123 | return NULL; | 117 | return acl; |
124 | } | 118 | } |
125 | 119 | ||
126 | /* core_tpg_add_node_to_devs(): | 120 | /* core_tpg_add_node_to_devs(): |