mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 15:12:13 +02:00
nvmet-fc: take tgtport refs for portentry
Ensure that the tgtport is not going away as long portentry has a pointer on it. Signed-off-by: Daniel Wagner <wagi@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
bbccbf791e
commit
596cba55ad
|
|
@ -1257,6 +1257,7 @@ nvmet_fc_portentry_bind(struct nvmet_fc_tgtport *tgtport,
|
|||
{
|
||||
lockdep_assert_held(&nvmet_fc_tgtlock);
|
||||
|
||||
nvmet_fc_tgtport_get(tgtport);
|
||||
pe->tgtport = tgtport;
|
||||
tgtport->pe = pe;
|
||||
|
||||
|
|
@ -1276,8 +1277,10 @@ nvmet_fc_portentry_unbind(struct nvmet_fc_port_entry *pe)
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
|
||||
if (pe->tgtport)
|
||||
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);
|
||||
}
|
||||
|
|
@ -1295,8 +1298,10 @@ nvmet_fc_portentry_unbind_tgt(struct nvmet_fc_tgtport *tgtport)
|
|||
|
||||
spin_lock_irqsave(&nvmet_fc_tgtlock, flags);
|
||||
pe = tgtport->pe;
|
||||
if (pe)
|
||||
if (pe) {
|
||||
nvmet_fc_tgtport_put(pe->tgtport);
|
||||
pe->tgtport = NULL;
|
||||
}
|
||||
tgtport->pe = NULL;
|
||||
spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
|
||||
}
|
||||
|
|
@ -1319,6 +1324,9 @@ nvmet_fc_portentry_rebind_tgt(struct nvmet_fc_tgtport *tgtport)
|
|||
list_for_each_entry(pe, &nvmet_fc_portentry_list, pe_list) {
|
||||
if (tgtport->fc_target_port.node_name == pe->node_name &&
|
||||
tgtport->fc_target_port.port_name == pe->port_name) {
|
||||
if (!nvmet_fc_tgtport_get(tgtport))
|
||||
continue;
|
||||
|
||||
WARN_ON(pe->tgtport);
|
||||
tgtport->pe = pe;
|
||||
pe->tgtport = tgtport;
|
||||
|
|
@ -2888,12 +2896,17 @@ nvmet_fc_add_port(struct nvmet_port *port)
|
|||
list_for_each_entry(tgtport, &nvmet_fc_target_list, tgt_list) {
|
||||
if ((tgtport->fc_target_port.node_name == traddr.nn) &&
|
||||
(tgtport->fc_target_port.port_name == traddr.pn)) {
|
||||
if (!nvmet_fc_tgtport_get(tgtport))
|
||||
continue;
|
||||
|
||||
/* a FC port can only be 1 nvmet port id */
|
||||
if (!tgtport->pe) {
|
||||
nvmet_fc_portentry_bind(tgtport, pe, port);
|
||||
ret = 0;
|
||||
} else
|
||||
ret = -EALREADY;
|
||||
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -2909,11 +2922,21 @@ static void
|
|||
nvmet_fc_remove_port(struct nvmet_port *port)
|
||||
{
|
||||
struct nvmet_fc_port_entry *pe = port->priv;
|
||||
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;
|
||||
spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
|
||||
|
||||
nvmet_fc_portentry_unbind(pe);
|
||||
|
||||
/* terminate any outstanding associations */
|
||||
__nvmet_fc_free_assocs(pe->tgtport);
|
||||
if (tgtport) {
|
||||
/* terminate any outstanding associations */
|
||||
__nvmet_fc_free_assocs(tgtport);
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
}
|
||||
|
||||
kfree(pe);
|
||||
}
|
||||
|
|
@ -2922,10 +2945,21 @@ static void
|
|||
nvmet_fc_discovery_chg(struct nvmet_port *port)
|
||||
{
|
||||
struct nvmet_fc_port_entry *pe = port->priv;
|
||||
struct nvmet_fc_tgtport *tgtport = pe->tgtport;
|
||||
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;
|
||||
spin_unlock_irqrestore(&nvmet_fc_tgtlock, flags);
|
||||
|
||||
if (!tgtport)
|
||||
return;
|
||||
|
||||
if (tgtport && tgtport->ops->discovery_event)
|
||||
tgtport->ops->discovery_event(&tgtport->fc_target_port);
|
||||
|
||||
nvmet_fc_tgtport_put(tgtport);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user