From c09f87e3b7b1838cff9c822a33655f016099b0b2 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 4 Nov 2010 03:28:29 +0000 Subject: [PATCH] [fc] Hold reference to peers and ULPs while calling fc_link_examine() Allow link examination methods to safely assume that their self-reference remains valid for the duration of the method call. Signed-off-by: Michael Brown --- src/net/fc.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/net/fc.c b/src/net/fc.c index c15fa724c..46bc66589 100644 --- a/src/net/fc.c +++ b/src/net/fc.c @@ -982,8 +982,11 @@ int fc_port_login ( struct fc_port *port, struct fc_port_id *port_id, fc_link_up ( &port->link ); /* Notify peers of link state change */ - list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) + list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) { + fc_peer_get ( peer ); fc_link_examine ( &peer->link ); + fc_peer_put ( peer ); + } return 0; } @@ -1008,8 +1011,11 @@ void fc_port_logout ( struct fc_port *port, int rc ) { fc_link_err ( &port->link, rc ); /* Notify peers of link state change */ - list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) + list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) { + fc_peer_get ( peer ); fc_link_examine ( &peer->link ); + fc_peer_put ( peer ); + } } /** @@ -1274,8 +1280,11 @@ int fc_peer_login ( struct fc_peer *peer, struct fc_port *port, fc_link_up ( &peer->link ); /* Notify ULPs of link state change */ - list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) + list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) { + fc_ulp_get ( ulp ); fc_link_examine ( &ulp->link ); + fc_ulp_put ( ulp ); + } return 0; } @@ -1305,8 +1314,11 @@ void fc_peer_logout ( struct fc_peer *peer, int rc ) { fc_link_err ( &peer->link, rc ); /* Notify ULPs of link state change */ - list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) + list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) { + fc_ulp_get ( ulp ); fc_link_examine ( &ulp->link ); + fc_ulp_put ( ulp ); + } /* Close peer if there are no active users */ if ( peer->usage == 0 )