diff options
author | Michael Brown <mcb30@ipxe.org> | 2010-11-05 23:13:22 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2010-11-08 03:35:36 +0000 |
commit | 41231fda9c6989c2e1fcc41abef307531926a804 (patch) | |
tree | 032a3ac48ca092e8dce106435599013d5b0a6940 /src/net/fc.c | |
parent | 0cd185e7341a62e1a166d277ef96f255827b8032 (diff) | |
download | ipxe-41231fda9c6989c2e1fcc41abef307531926a804.zip ipxe-41231fda9c6989c2e1fcc41abef307531926a804.tar.gz ipxe-41231fda9c6989c2e1fcc41abef307531926a804.tar.bz2 |
[fc] Hold ULP's peer reference while ULP exists
Allow fc_ulp_decrement() to guarantee to fc_peer_decrement() that the
peer reference remains valid for the duration of the call, by ensuring
that ulp->peer remains valid while ulp is valid.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/fc.c')
-rw-r--r-- | src/net/fc.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/net/fc.c b/src/net/fc.c index fb930f1..d321c1f 100644 --- a/src/net/fc.c +++ b/src/net/fc.c @@ -1477,6 +1477,18 @@ struct fc_peer * fc_peer_get_port_id ( struct fc_port *port, */ /** + * Free Fibre Channel upper-layer protocol + * + * @v refcnt Reference count + */ +static void fc_ulp_free ( struct refcnt *refcnt ) { + struct fc_ulp *ulp = container_of ( refcnt, struct fc_ulp, refcnt ); + + fc_peer_put ( ulp->peer ); + free ( ulp ); +} + +/** * Close Fibre Channel upper-layer protocol * * @v ulp Fibre Channel upper-layer protocol @@ -1499,10 +1511,6 @@ static void fc_ulp_close ( struct fc_ulp *ulp, int rc ) { /* Remove from list of ULPs */ list_del ( &ulp->list ); INIT_LIST_HEAD ( &ulp->list ); - - /* Drop peer reference */ - fc_peer_put ( ulp->peer ); - ulp->peer = NULL; } /** @@ -1525,7 +1533,6 @@ void fc_ulp_increment ( struct fc_ulp *ulp ) { * @v ulp Fibre Channel ulp */ void fc_ulp_decrement ( struct fc_ulp *ulp ) { - struct fc_peer *peer = ulp->peer; /* Sanity check */ assert ( ulp->usage > 0 ); @@ -1535,7 +1542,7 @@ void fc_ulp_decrement ( struct fc_ulp *ulp ) { fc_ulp_logout ( ulp, 0 ); /* Decrement our peer's usage count */ - fc_peer_decrement ( peer ); + fc_peer_decrement ( ulp->peer ); } /** @@ -1702,7 +1709,7 @@ static struct fc_ulp * fc_ulp_create ( struct fc_peer *peer, ulp = zalloc ( sizeof ( *ulp ) ); if ( ! ulp ) return NULL; - ref_init ( &ulp->refcnt, NULL ); + ref_init ( &ulp->refcnt, fc_ulp_free ); fc_link_init ( &ulp->link, fc_ulp_examine, &ulp->refcnt ); intf_init ( &ulp->prli, &fc_ulp_prli_desc, &ulp->refcnt ); ulp->peer = fc_peer_get ( peer ); |