diff options
author | rrs <rrs@FreeBSD.org> | 2007-09-08 11:35:11 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-09-08 11:35:11 +0000 |
commit | 4dd82bd675126ae3087b47d4425b57c8c44aa790 (patch) | |
tree | 33156f38f2aa559546f6d475b9777be0710945b3 /sys/netinet/sctp_peeloff.c | |
parent | 8c4e364ee08a6259e006283ec6d3d38f50f37d5f (diff) | |
download | FreeBSD-src-4dd82bd675126ae3087b47d4425b57c8c44aa790.zip FreeBSD-src-4dd82bd675126ae3087b47d4425b57c8c44aa790.tar.gz |
- Locking compatiability changes. This involves adding
additional flags to many function calls. The flags only
get used in BSD when we compile with lock testing. These
flags allow apple to escape the "giant" lock it holds on
the socket and have more fine-grained locking in the NKE.
It also allows us to test (with witness) the locking used
by apple via a compile switch (manually applied).
Approved by: re@freebsd.org(B Mah)
Diffstat (limited to 'sys/netinet/sctp_peeloff.c')
-rw-r--r-- | sys/netinet/sctp_peeloff.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/sys/netinet/sctp_peeloff.c b/sys/netinet/sctp_peeloff.c index b286c96..424de2c 100644 --- a/sys/netinet/sctp_peeloff.c +++ b/sys/netinet/sctp_peeloff.c @@ -60,8 +60,8 @@ sctp_can_peel_off(struct socket *head, sctp_assoc_t assoc_id) } stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); if (stcb == NULL) { - SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOTCONN); - return (ENOTCONN); + SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOENT); + return (ENOENT); } state = SCTP_GET_STATE((&stcb->asoc)); if ((state == SCTP_STATE_EMPTY) || @@ -161,26 +161,27 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error) *error = ENOTCONN; return (NULL); } + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); newso = sonewconn(head, SS_ISCONNECTED ); if (newso == NULL) { SCTPDBG(SCTP_DEBUG_PEEL1, "sctp_peeloff:sonewconn failed\n"); SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_PEELOFF, ENOMEM); *error = ENOMEM; - SCTP_TCB_UNLOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); return (NULL); } + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); n_inp = (struct sctp_inpcb *)newso->so_pcb; SOCK_LOCK(head); - SCTP_INP_WLOCK(inp); - SCTP_INP_WLOCK(n_inp); n_inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE | SCTP_PCB_FLAGS_CONNECTED | SCTP_PCB_FLAGS_IN_TCPPOOL | /* Turn on Blocking IO */ (SCTP_PCB_COPY_FLAGS & inp->sctp_flags)); n_inp->sctp_features = inp->sctp_features; - n_inp->sctp_mobility_features = inp->sctp_mobility_features; n_inp->sctp_frag_point = inp->sctp_frag_point; n_inp->partial_delivery_point = inp->partial_delivery_point; n_inp->sctp_context = inp->sctp_context; @@ -222,8 +223,6 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error) * Now we must move it from one hash table to another and get the * stcb in the right place. */ - SCTP_INP_WUNLOCK(n_inp); - SCTP_INP_WUNLOCK(inp); sctp_move_pcb_and_assoc(inp, n_inp, stcb); atomic_add_int(&stcb->asoc.refcnt, 1); SCTP_TCB_UNLOCK(stcb); @@ -233,6 +232,5 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error) */ sctp_pull_off_control_to_new_inp(inp, n_inp, stcb, M_WAITOK); atomic_subtract_int(&stcb->asoc.refcnt, 1); - return (newso); } |