forked from Minki/linux
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: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Amit Engel <amit.engel@dell.com> Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
bdaf132791
commit
0d8ddeea11
@ -1020,61 +1020,76 @@ nvmet_fc_free_hostport(struct nvmet_fc_hostport *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 *
|
||||
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;
|
||||
|
||||
/* if LLDD not implemented, leave as NULL */
|
||||
if (!hosthandle)
|
||||
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))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
|
||||
if (!newhost) {
|
||||
spin_lock_irqsave(&tgtport->lock, flags);
|
||||
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);
|
||||
return (match) ? match : 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
kfree(newhost);
|
||||
newhost = NULL;
|
||||
/* releasing allocation - release reference */
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
} else
|
||||
list_add_tail(&newhost->host_list, &tgtport->host_list);
|
||||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||||
spin_unlock_irqrestore(&tgtport->lock, flags);
|
||||
|
||||
return (match) ? match : newhost;
|
||||
if (match) {
|
||||
/* no new allocation - release reference */
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
return match;
|
||||
}
|
||||
|
||||
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL);
|
||||
if (!newhost) {
|
||||
/* no new allocation - release reference */
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&tgtport->lock, flags);
|
||||
match = nvmet_fc_match_hostport(tgtport, hosthandle);
|
||||
if (match) {
|
||||
/* new allocation not needed */
|
||||
kfree(newhost);
|
||||
newhost = match;
|
||||
/* no new allocation - release reference */
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
} 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);
|
||||
}
|
||||
spin_unlock_irqrestore(&tgtport->lock, flags);
|
||||
|
||||
return newhost;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user