aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2014-04-04 19:54:12 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2014-04-11 18:30:50 -0400
commitd242c1d7d39bb50d2816a2834b84c420c3e7084e (patch)
treed693093cca72b2e40b6b7d7a7861e44b753804fe
parentb295e76900223e4b8e350d02f7b6801fe126d8d2 (diff)
target/tcm_fc: Limit to 1 TPG per wwn
tcm_fc doesn't support multiple TPGs per wwn. For proof, see ft_lport_find_tpg. Enforce this in the code. Replace ft_lport_wwn.tpg_list with a single pointer. We can't fold ft_tpg into ft_lport_wwn because they can have different lifetimes. Signed-off-by: Andy Grover <agrover@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/tcm_fc/tcm_fc.h3
-rw-r--r--drivers/target/tcm_fc/tfc_conf.c20
2 files changed, 12 insertions, 11 deletions
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index aba6861c362b..7290f8fb53f0 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -96,7 +96,6 @@ struct ft_tpg {
96 u32 index; 96 u32 index;
97 struct ft_lport_acl *lport_acl; 97 struct ft_lport_acl *lport_acl;
98 struct ft_tport *tport; /* active tport or NULL */ 98 struct ft_tport *tport; /* active tport or NULL */
99 struct list_head list; /* linkage in ft_lport_acl tpg_list */
100 struct list_head lun_list; /* head of LUNs */ 99 struct list_head lun_list; /* head of LUNs */
101 struct se_portal_group se_tpg; 100 struct se_portal_group se_tpg;
102 struct workqueue_struct *workqueue; 101 struct workqueue_struct *workqueue;
@@ -105,8 +104,8 @@ struct ft_tpg {
105struct ft_lport_acl { 104struct ft_lport_acl {
106 u64 wwpn; 105 u64 wwpn;
107 char name[FT_NAMELEN]; 106 char name[FT_NAMELEN];
107 struct ft_tpg *tpg;
108 struct list_head list; 108 struct list_head list;
109 struct list_head tpg_list;
110 struct se_wwn fc_lport_wwn; 109 struct se_wwn fc_lport_wwn;
111}; 110};
112 111
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 9c2da1ff886a..ccfa328e0367 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -318,6 +318,11 @@ static struct se_portal_group *ft_add_tpg(
318 if (index > UINT_MAX) 318 if (index > UINT_MAX)
319 return NULL; 319 return NULL;
320 320
321 if ((index != 1)) {
322 pr_err("Error, a single TPG=1 is used for HW port mappings\n");
323 return ERR_PTR(-ENOSYS);
324 }
325
321 lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn); 326 lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn);
322 tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); 327 tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
323 if (!tpg) 328 if (!tpg)
@@ -342,7 +347,7 @@ static struct se_portal_group *ft_add_tpg(
342 tpg->workqueue = wq; 347 tpg->workqueue = wq;
343 348
344 mutex_lock(&ft_lport_lock); 349 mutex_lock(&ft_lport_lock);
345 list_add_tail(&tpg->list, &lacl->tpg_list); 350 lacl->tpg = tpg;
346 mutex_unlock(&ft_lport_lock); 351 mutex_unlock(&ft_lport_lock);
347 352
348 return &tpg->se_tpg; 353 return &tpg->se_tpg;
@@ -351,6 +356,7 @@ static struct se_portal_group *ft_add_tpg(
351static void ft_del_tpg(struct se_portal_group *se_tpg) 356static void ft_del_tpg(struct se_portal_group *se_tpg)
352{ 357{
353 struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg); 358 struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg);
359 struct ft_lport_acl *lacl = tpg->lport_acl;
354 360
355 pr_debug("del tpg %s\n", 361 pr_debug("del tpg %s\n",
356 config_item_name(&tpg->se_tpg.tpg_group.cg_item)); 362 config_item_name(&tpg->se_tpg.tpg_group.cg_item));
@@ -361,7 +367,8 @@ static void ft_del_tpg(struct se_portal_group *se_tpg)
361 synchronize_rcu(); 367 synchronize_rcu();
362 368
363 mutex_lock(&ft_lport_lock); 369 mutex_lock(&ft_lport_lock);
364 list_del(&tpg->list); 370 lacl->tpg = NULL;
371
365 if (tpg->tport) { 372 if (tpg->tport) {
366 tpg->tport->tpg = NULL; 373 tpg->tport->tpg = NULL;
367 tpg->tport = NULL; 374 tpg->tport = NULL;
@@ -381,14 +388,10 @@ static void ft_del_tpg(struct se_portal_group *se_tpg)
381struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) 388struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport)
382{ 389{
383 struct ft_lport_acl *lacl; 390 struct ft_lport_acl *lacl;
384 struct ft_tpg *tpg;
385 391
386 list_for_each_entry(lacl, &ft_lport_list, list) { 392 list_for_each_entry(lacl, &ft_lport_list, list) {
387 if (lacl->wwpn == lport->wwpn) { 393 if (lacl->wwpn == lport->wwpn)
388 list_for_each_entry(tpg, &lacl->tpg_list, list) 394 return lacl->tpg;
389 return tpg; /* XXX for now return first entry */
390 return NULL;
391 }
392 } 395 }
393 return NULL; 396 return NULL;
394} 397}
@@ -417,7 +420,6 @@ static struct se_wwn *ft_add_lport(
417 if (!lacl) 420 if (!lacl)
418 return NULL; 421 return NULL;
419 lacl->wwpn = wwpn; 422 lacl->wwpn = wwpn;
420 INIT_LIST_HEAD(&lacl->tpg_list);
421 423
422 mutex_lock(&ft_lport_lock); 424 mutex_lock(&ft_lport_lock);
423 list_for_each_entry(old_lacl, &ft_lport_list, list) { 425 list_for_each_entry(old_lacl, &ft_lport_list, list) {