diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-03-25 15:03:29 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-03-25 15:03:29 +0000 |
commit | f594b5f37bad3af3a3ecddfae898048e07a57bc1 (patch) | |
tree | 11842e9420815dabd22cfaa6cdb3c5d9c18bdff4 /sys/netipx | |
parent | bb7f7422a3416143c19361a3ec36ba3b2ff33457 (diff) | |
download | FreeBSD-src-f594b5f37bad3af3a3ecddfae898048e07a57bc1.zip FreeBSD-src-f594b5f37bad3af3a3ecddfae898048e07a57bc1.tar.gz |
Restructure spx_attach() to properly free memory in the event that one
of its allocations fails. Allocate the ipxp last so as to avoid having
to free it if another allocation goes wrong.
Normalize retrieval of ipxp and cb from socket in spx_sp_attach(), and
add assertions.
MFC after: 1 month
Diffstat (limited to 'sys/netipx')
-rw-r--r-- | sys/netipx/spx_usrreq.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index d2ad220..e562270 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -1344,29 +1344,31 @@ spx_attach(struct socket *so, int proto, struct thread *td) ipxp = sotoipxpcb(so); KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL")); - IPX_LIST_LOCK(); - error = ipx_pcballoc(so, &ipxpcb_list, td); - if (error) - goto spx_attach_end; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { error = soreserve(so, (u_long) 3072, (u_long) 3072); if (error) - goto spx_attach_end; + return (error); } - ipxp = sotoipxpcb(so); MALLOC(cb, struct spxpcb *, sizeof *cb, M_PCB, M_NOWAIT | M_ZERO); - if (cb == NULL) { - error = ENOBUFS; - goto spx_attach_end; - } - + if (cb == NULL) + return (ENOBUFS); mm = m_getclr(M_DONTWAIT, MT_DATA); if (mm == NULL) { FREE(cb, M_PCB); - error = ENOBUFS; - goto spx_attach_end; + return (ENOBUFS); + } + + IPX_LIST_LOCK(); + error = ipx_pcballoc(so, &ipxpcb_list, td); + if (error) { + IPX_LIST_UNLOCK(); + m_free(mm); + FREE(cb, M_PCB); + return (error); } + ipxp = sotoipxpcb(so); + cb->s_ipx = mtod(mm, struct ipx *); cb->s_state = TCPS_LISTEN; cb->s_smax = -1; @@ -1388,7 +1390,6 @@ spx_attach(struct socket *so, int proto, struct thread *td) ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1, SPXTV_MIN, SPXTV_REXMTMAX); ipxp->ipxp_pcb = (caddr_t)cb; -spx_attach_end: IPX_LIST_UNLOCK(); return (error); } @@ -1649,16 +1650,26 @@ spx_shutdown(struct socket *so) static int spx_sp_attach(struct socket *so, int proto, struct thread *td) { - int error; struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL")); error = spx_attach(so, proto, td); - if (error == 0) { - ipxp = sotoipxpcb(so); - ((struct spxpcb *)ipxp->ipxp_pcb)->s_flags |= - (SF_HI | SF_HO | SF_PI); - } - return (error); + if (error) + return (error); + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL")); + + IPX_LOCK(ipxp); + cb->s_flags |= (SF_HI | SF_HO | SF_PI); + IPX_UNLOCK(ipxp); + return (0); } /* |