--- x/drivers/nvme/target/fc.c +++ y/drivers/nvme/target/fc.c @@ -1268,20 +1268,6 @@ nvmet_fc_portentry_bind(struct nvmet_fc_ list_add_tail(&pe->pe_list, &nvmet_fc_portentry_list); } -static void -nvmet_fc_portentry_unbind(struct nvmet_fc_port_entry *pe) -{ - unsigned long flags; - - spin_lock_irqsave(&nvmet_fc_tgtlock, flags); - if (pe->tgtport) { - nvmet_fc_tgtport_put(pe->tgtport); - pe->tgtport->pe = NULL; - } - list_del(&pe->pe_list); - spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags); -} - /* * called when a targetport deregisters. Breaks the relationship * with the nvmet port, but leaves the port_entry in place so that @@ -2915,24 +2901,31 @@ nvmet_fc_add_port(struct nvmet_port *por static void nvmet_fc_remove_port(struct nvmet_port *port) { - struct nvmet_fc_port_entry *pe = port->priv; + struct nvmet_fc_port_entry *pe, *entry, *an = NULL; struct nvmet_fc_tgtport *tgtport = NULL; unsigned long flags; spin_lock_irqsave(&nvmet_fc_tgtlock, flags); - if (pe->tgtport && nvmet_fc_tgtport_get(pe->tgtport)) - tgtport = pe->tgtport; + pe = port->priv; + list_for_each_entry(entry, &nvmet_fc_portentry_list, pe_list) { + if (!pe) + break; + if (entry != pe) + continue; + list_del(&pe->pe_list); + if (pe->tgtport) { + pe->tgtport->pe = NULL; + tgtport = pe->tgtport; + } + an = pe; + break; + } spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags); - nvmet_fc_portentry_unbind(pe); - + kfree(an); if (tgtport) { - /* terminate any outstanding associations */ - __nvmet_fc_free_assocs(tgtport); nvmet_fc_tgtport_put(tgtport); } - - kfree(pe); } static void