From 131e6abc674edb9f9a59090bb35bf6650569b7e7 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sat, 22 Mar 2014 14:55:56 -0700 Subject: target: Add TFO->abort_task for aborted task resources release Now that TASK_ABORTED status is not generated for all cases by TMR ABORT_TASK + LUN_RESET, a new TFO->abort_task() caller is necessary in order to give fabric drivers a chance to unmap hardware / software resources before the se_cmd descriptor is released via the normal TFO->release_cmd() codepath. This patch adds TFO->aborted_task() in core_tmr_abort_task() in place of the original transport_send_task_abort(), and also updates all fabric drivers to implement this caller. The fabric drivers that include changes to perform cleanup via ->aborted_task() are: - iscsi-target - iser-target - srpt - tcm_qla2xxx The fabric drivers that currently set ->aborted_task() to NOPs are: - loopback - tcm_fc - usb-gadget - sbp-target - vhost-scsi For the latter five, there appears to be no additional cleanup required before invoking TFO->release_cmd() to release the se_cmd descriptor. v2 changes: - Move ->aborted_task() call into transport_cmd_finish_abort (Alex) Cc: Alex Leung Cc: Mark Rustad Cc: Roland Dreier Cc: Vu Pham Cc: Chris Boot Cc: Sebastian Andrzej Siewior Cc: Michael S. Tsirkin Cc: Giridhar Malavali Cc: Saurav Kashyap Cc: Quinn Tran Cc: Sagi Grimberg Cc: Or Gerlitz Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_conf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/target/tcm_fc/tfc_conf.c') diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index e879da81ad93..b8b5a719a784 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -536,6 +536,7 @@ static struct target_core_fabric_ops ft_fabric_ops = { .queue_data_in = ft_queue_data_in, .queue_status = ft_queue_status, .queue_tm_rsp = ft_queue_tm_resp, + .aborted_task = ft_aborted_task, /* * Setup function pointers for generic logic in * target_core_fabric_configfs.c -- cgit v1.2.3 From b295e76900223e4b8e350d02f7b6801fe126d8d2 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 4 Apr 2014 16:54:11 -0700 Subject: target/tcm_fc: Don't export ft_lport_list Nobody outside tfc_conf.c uses it. Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tcm_fc.h | 1 - drivers/target/tcm_fc/tfc_conf.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/target/tcm_fc/tfc_conf.c') diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index 4f4b97161228..aba6861c362b 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -128,7 +128,6 @@ struct ft_cmd { u32 sg_cnt; /* No. of item in scatterlist */ }; -extern struct list_head ft_lport_list; extern struct mutex ft_lport_lock; extern struct fc4_prov ft_prov; extern struct target_fabric_configfs *ft_configfs; diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index b8b5a719a784..9c2da1ff886a 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -50,7 +50,7 @@ struct target_fabric_configfs *ft_configfs; -LIST_HEAD(ft_lport_list); +static LIST_HEAD(ft_lport_list); DEFINE_MUTEX(ft_lport_lock); unsigned int ft_debug_logging; -- cgit v1.2.3 From d242c1d7d39bb50d2816a2834b84c420c3e7084e Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 4 Apr 2014 16:54:12 -0700 Subject: 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 Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tcm_fc.h | 3 +-- drivers/target/tcm_fc/tfc_conf.c | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/target/tcm_fc/tfc_conf.c') 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 { 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 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( 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) { -- cgit v1.2.3 From 705665da222b810fced1273169d63f31635df6f0 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 4 Apr 2014 16:54:13 -0700 Subject: target/tcm_fc: Rename structs and list members for clarity Rename struct ft_lport_acl to ft_lport_wwn. "acl" is associated with something different in LIO terms. Really, ft_lport_wwn is the fabric-specific wrapper for the struct se_wwn. Rename "lacl" local variables to "ft_wwn" as well. Rename list_heads used as list members to make it clear they're nodes, not heads. Rename lport_node to ft_wwn_node. Rename ft_lport_list to ft_wwn_list Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tcm_fc.h | 8 +++--- drivers/target/tcm_fc/tfc_conf.c | 57 ++++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 33 deletions(-) (limited to 'drivers/target/tcm_fc/tfc_conf.c') diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index 7290f8fb53f0..a0bcfd3e7e7d 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -94,19 +94,19 @@ struct ft_lun { */ struct ft_tpg { u32 index; - struct ft_lport_acl *lport_acl; + struct ft_lport_wwn *lport_wwn; struct ft_tport *tport; /* active tport or NULL */ struct list_head lun_list; /* head of LUNs */ struct se_portal_group se_tpg; struct workqueue_struct *workqueue; }; -struct ft_lport_acl { +struct ft_lport_wwn { u64 wwpn; char name[FT_NAMELEN]; + struct list_head ft_wwn_node; struct ft_tpg *tpg; - struct list_head list; - struct se_wwn fc_lport_wwn; + struct se_wwn se_wwn; }; /* diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index ccfa328e0367..bd7d544d5478 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -50,7 +50,7 @@ struct target_fabric_configfs *ft_configfs; -static LIST_HEAD(ft_lport_list); +static LIST_HEAD(ft_wwn_list); DEFINE_MUTEX(ft_lport_lock); unsigned int ft_debug_logging; @@ -298,7 +298,7 @@ static struct se_portal_group *ft_add_tpg( struct config_group *group, const char *name) { - struct ft_lport_acl *lacl; + struct ft_lport_wwn *ft_wwn; struct ft_tpg *tpg; struct workqueue_struct *wq; unsigned long index; @@ -323,12 +323,12 @@ static struct se_portal_group *ft_add_tpg( return ERR_PTR(-ENOSYS); } - lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn); + ft_wwn = container_of(wwn, struct ft_lport_wwn, se_wwn); tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); if (!tpg) return NULL; tpg->index = index; - tpg->lport_acl = lacl; + tpg->lport_wwn = ft_wwn; INIT_LIST_HEAD(&tpg->lun_list); wq = alloc_workqueue("tcm_fc", 0, 1); @@ -347,7 +347,7 @@ static struct se_portal_group *ft_add_tpg( tpg->workqueue = wq; mutex_lock(&ft_lport_lock); - lacl->tpg = tpg; + ft_wwn->tpg = tpg; mutex_unlock(&ft_lport_lock); return &tpg->se_tpg; @@ -356,7 +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; + struct ft_lport_wwn *ft_wwn = tpg->lport_wwn; pr_debug("del tpg %s\n", config_item_name(&tpg->se_tpg.tpg_group.cg_item)); @@ -367,8 +367,7 @@ static void ft_del_tpg(struct se_portal_group *se_tpg) synchronize_rcu(); mutex_lock(&ft_lport_lock); - lacl->tpg = NULL; - + ft_wwn->tpg = NULL; if (tpg->tport) { tpg->tport->tpg = NULL; tpg->tport = NULL; @@ -387,11 +386,11 @@ 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_lport_wwn *ft_wwn; - list_for_each_entry(lacl, &ft_lport_list, list) { - if (lacl->wwpn == lport->wwpn) - return lacl->tpg; + list_for_each_entry(ft_wwn, &ft_wwn_list, ft_wwn_node) { + if (ft_wwn->wwpn == lport->wwpn) + return ft_wwn->tpg; } return NULL; } @@ -409,44 +408,44 @@ static struct se_wwn *ft_add_lport( struct config_group *group, const char *name) { - struct ft_lport_acl *lacl; - struct ft_lport_acl *old_lacl; + struct ft_lport_wwn *ft_wwn; + struct ft_lport_wwn *old_ft_wwn; u64 wwpn; pr_debug("add lport %s\n", name); if (ft_parse_wwn(name, &wwpn, 1) < 0) return NULL; - lacl = kzalloc(sizeof(*lacl), GFP_KERNEL); - if (!lacl) + ft_wwn = kzalloc(sizeof(*ft_wwn), GFP_KERNEL); + if (!ft_wwn) return NULL; - lacl->wwpn = wwpn; + ft_wwn->wwpn = wwpn; mutex_lock(&ft_lport_lock); - list_for_each_entry(old_lacl, &ft_lport_list, list) { - if (old_lacl->wwpn == wwpn) { + list_for_each_entry(old_ft_wwn, &ft_wwn_list, ft_wwn_node) { + if (old_ft_wwn->wwpn == wwpn) { mutex_unlock(&ft_lport_lock); - kfree(lacl); + kfree(ft_wwn); return NULL; } } - list_add_tail(&lacl->list, &ft_lport_list); - ft_format_wwn(lacl->name, sizeof(lacl->name), wwpn); + list_add_tail(&ft_wwn->ft_wwn_node, &ft_wwn_list); + ft_format_wwn(ft_wwn->name, sizeof(ft_wwn->name), wwpn); mutex_unlock(&ft_lport_lock); - return &lacl->fc_lport_wwn; + return &ft_wwn->se_wwn; } static void ft_del_lport(struct se_wwn *wwn) { - struct ft_lport_acl *lacl = container_of(wwn, - struct ft_lport_acl, fc_lport_wwn); + struct ft_lport_wwn *ft_wwn = container_of(wwn, + struct ft_lport_wwn, se_wwn); - pr_debug("del lport %s\n", lacl->name); + pr_debug("del lport %s\n", ft_wwn->name); mutex_lock(&ft_lport_lock); - list_del(&lacl->list); + list_del(&ft_wwn->ft_wwn_node); mutex_unlock(&ft_lport_lock); - kfree(lacl); + kfree(ft_wwn); } static ssize_t ft_wwn_show_attr_version( @@ -473,7 +472,7 @@ static char *ft_get_fabric_wwn(struct se_portal_group *se_tpg) { struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr; - return tpg->lport_acl->name; + return tpg->lport_wwn->name; } static u16 ft_get_tag(struct se_portal_group *se_tpg) -- cgit v1.2.3 From 0d7cb932b7ccde61654f5f01754d335872dd15ab Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Fri, 4 Apr 2014 16:54:14 -0700 Subject: target/tcm_fc: Rename ft_{add,del}_lport to {add,del}_wwn These functions are not adding or deleting an lport. They are adding a wwn that may match with an lport that is present on the system. Renaming ft_del_lport also means we won't have functions named both ft_del_lport and ft_lport_del any more. Signed-off-by: Andy Grover Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_conf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/target/tcm_fc/tfc_conf.c') diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index bd7d544d5478..efdcb9663a1a 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -403,7 +403,7 @@ struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport) * Add lport to allowed config. * The name is the WWPN in lower-case ASCII, colon-separated bytes. */ -static struct se_wwn *ft_add_lport( +static struct se_wwn *ft_add_wwn( struct target_fabric_configfs *tf, struct config_group *group, const char *name) @@ -412,7 +412,7 @@ static struct se_wwn *ft_add_lport( struct ft_lport_wwn *old_ft_wwn; u64 wwpn; - pr_debug("add lport %s\n", name); + pr_debug("add wwn %s\n", name); if (ft_parse_wwn(name, &wwpn, 1) < 0) return NULL; ft_wwn = kzalloc(sizeof(*ft_wwn), GFP_KERNEL); @@ -435,12 +435,12 @@ static struct se_wwn *ft_add_lport( return &ft_wwn->se_wwn; } -static void ft_del_lport(struct se_wwn *wwn) +static void ft_del_wwn(struct se_wwn *wwn) { struct ft_lport_wwn *ft_wwn = container_of(wwn, struct ft_lport_wwn, se_wwn); - pr_debug("del lport %s\n", ft_wwn->name); + pr_debug("del wwn %s\n", ft_wwn->name); mutex_lock(&ft_lport_lock); list_del(&ft_wwn->ft_wwn_node); mutex_unlock(&ft_lport_lock); @@ -542,8 +542,8 @@ static struct target_core_fabric_ops ft_fabric_ops = { * Setup function pointers for generic logic in * target_core_fabric_configfs.c */ - .fabric_make_wwn = &ft_add_lport, - .fabric_drop_wwn = &ft_del_lport, + .fabric_make_wwn = &ft_add_wwn, + .fabric_drop_wwn = &ft_del_wwn, .fabric_make_tpg = &ft_add_tpg, .fabric_drop_tpg = &ft_del_tpg, .fabric_post_link = NULL, -- cgit v1.2.3