Commit 0d8ddeea authored by Amit Engel's avatar Amit Engel Committed by Christoph Hellwig

nvmet-fc: simplify nvmet_fc_alloc_hostport

Once a host is already created, avoid allocate additional hostports that
will be thrown away. add an helper function to handle host search.
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarAmit Engel <amit.engel@dell.com>
Reviewed-by: default avatarChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent bdaf1327
...@@ -1020,61 +1020,76 @@ nvmet_fc_free_hostport(struct nvmet_fc_hostport *hostport) ...@@ -1020,61 +1020,76 @@ nvmet_fc_free_hostport(struct nvmet_fc_hostport *hostport)
nvmet_fc_hostport_put(hostport); nvmet_fc_hostport_put(hostport);
} }
static struct nvmet_fc_hostport *
nvmet_fc_match_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
{
struct nvmet_fc_hostport *host;
lockdep_assert_held(&tgtport->lock);
list_for_each_entry(host, &tgtport->host_list, host_list) {
if (host->hosthandle == hosthandle && !host->invalid) {
if (nvmet_fc_hostport_get(host))
return (host);
}
}
return NULL;
}
static struct nvmet_fc_hostport * static struct nvmet_fc_hostport *
nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
{ {
struct nvmet_fc_hostport *newhost, *host, *match = NULL; struct nvmet_fc_hostport *newhost, *match = NULL;
unsigned long flags; unsigned long flags;
/* if LLDD not implemented, leave as NULL */ /* if LLDD not implemented, leave as NULL */
if (!hosthandle) if (!hosthandle)
return NULL; return NULL;
/* take reference for what will be the newly allocated hostport */ /*
* take reference for what will be the newly allocated hostport if
* we end up using a new allocation
*/
if (!nvmet_fc_tgtport_get(tgtport)) if (!nvmet_fc_tgtport_get(tgtport))
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
spin_lock_irqsave(&tgtport->lock, flags);
match = nvmet_fc_match_hostport(tgtport, hosthandle);
spin_unlock_irqrestore(&tgtport->lock, flags);
if (match) {
/* no new allocation - release reference */
nvmet_fc_tgtport_put(tgtport);
return match;
}
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL); newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
if (!newhost) { if (!newhost) {
spin_lock_irqsave(&tgtport->lock, flags); /* no new allocation - release reference */
list_for_each_entry(host, &tgtport->host_list, host_list) {
if (host->hosthandle == hosthandle && !host->invalid) {
if (nvmet_fc_hostport_get(host)) {
match = host;
break;
}
}
}
spin_unlock_irqrestore(&tgtport->lock, flags);
/* no allocation - release reference */
nvmet_fc_tgtport_put(tgtport); nvmet_fc_tgtport_put(tgtport);
return (match) ? match : ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
newhost->tgtport = tgtport;
newhost->hosthandle = hosthandle;
INIT_LIST_HEAD(&newhost->host_list);
kref_init(&newhost->ref);
spin_lock_irqsave(&tgtport->lock, flags); spin_lock_irqsave(&tgtport->lock, flags);
list_for_each_entry(host, &tgtport->host_list, host_list) { match = nvmet_fc_match_hostport(tgtport, hosthandle);
if (host->hosthandle == hosthandle && !host->invalid) {
if (nvmet_fc_hostport_get(host)) {
match = host;
break;
}
}
}
if (match) { if (match) {
/* new allocation not needed */
kfree(newhost); kfree(newhost);
newhost = NULL; newhost = match;
/* releasing allocation - release reference */ /* no new allocation - release reference */
nvmet_fc_tgtport_put(tgtport); nvmet_fc_tgtport_put(tgtport);
} else } else {
newhost->tgtport = tgtport;
newhost->hosthandle = hosthandle;
INIT_LIST_HEAD(&newhost->host_list);
kref_init(&newhost->ref);
list_add_tail(&newhost->host_list, &tgtport->host_list); list_add_tail(&newhost->host_list, &tgtport->host_list);
}
spin_unlock_irqrestore(&tgtport->lock, flags); spin_unlock_irqrestore(&tgtport->lock, flags);
return (match) ? match : newhost; return newhost;
} }
static void static void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment