diff options
author | Andy Grover <agrover@redhat.com> | 2014-04-04 23:54:12 (GMT) |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-11 22:30:50 (GMT) |
commit | d242c1d7d39bb50d2816a2834b84c420c3e7084e (patch) | |
tree | d693093cca72b2e40b6b7d7a7861e44b753804fe | |
parent | b295e76900223e4b8e350d02f7b6801fe126d8d2 (diff) | |
download | linux-d242c1d7d39bb50d2816a2834b84c420c3e7084e.tar.xz |
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.h | 3 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_conf.c | 20 |
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 aba6861..7290f8f 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -96,7 +96,6 @@ struct ft_tpg { u32 index; struct ft_lport_acl *lport_acl; struct ft_tport *tport; /* active tport or NULL */ - struct list_head list; /* linkage in ft_lport_acl tpg_list */ struct list_head lun_list; /* head of LUNs */ struct se_portal_group se_tpg; struct workqueue_struct *workqueue; @@ -105,8 +104,8 @@ struct ft_tpg { struct ft_lport_acl { u64 wwpn; char name[FT_NAMELEN]; + struct ft_tpg *tpg; struct list_head list; - struct list_head tpg_list; struct se_wwn fc_lport_wwn; }; diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 9c2da1f..ccfa328 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( if (index > UINT_MAX) return NULL; + if ((index != 1)) { + pr_err("Error, a single TPG=1 is used for HW port mappings\n"); + return ERR_PTR(-ENOSYS); + } + lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn); tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); if (!tpg) @@ -342,7 +347,7 @@ static struct se_portal_group *ft_add_tpg( tpg->workqueue = wq; mutex_lock(&ft_lport_lock); - list_add_tail(&tpg->list, &lacl->tpg_list); + lacl->tpg = tpg; mutex_unlock(&ft_lport_lock); return &tpg->se_tpg; @@ -351,6 +356,7 @@ static struct se_portal_group *ft_add_tpg( static void ft_del_tpg(struct se_portal_group *se_tpg) { struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg); + struct ft_lport_acl *lacl = tpg->lport_acl; pr_debug("del tpg %s\n", 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) synchronize_rcu(); mutex_lock(&ft_lport_lock); - list_del(&tpg->list); + lacl->tpg = NULL; + if (tpg->tport) { tpg->tport->tpg = NULL; tpg->tport = NULL; @@ -381,14 +388,10 @@ static void ft_del_tpg(struct se_portal_group *se_tpg) struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) { struct ft_lport_acl *lacl; - struct ft_tpg *tpg; list_for_each_entry(lacl, &ft_lport_list, list) { - if (lacl->wwpn == lport->wwpn) { - list_for_each_entry(tpg, &lacl->tpg_list, list) - return tpg; /* XXX for now return first entry */ - return NULL; - } + if (lacl->wwpn == lport->wwpn) + return lacl->tpg; } return NULL; } @@ -417,7 +420,6 @@ static struct se_wwn *ft_add_lport( if (!lacl) return NULL; lacl->wwpn = wwpn; - INIT_LIST_HEAD(&lacl->tpg_list); mutex_lock(&ft_lport_lock); list_for_each_entry(old_lacl, &ft_lport_list, list) { |