summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-07-11 01:34:34 +0000
committerrwatson <rwatson@FreeBSD.org>2004-07-11 01:34:34 +0000
commit7d0a074b000ec2ba28f19904b5d4377aee2a816d (patch)
tree4ffbc6659cbae0b40860268843fb00acbe2dfc33 /sys
parent2c40b499bc610c50be579ec89b7e9fcf21fc4738 (diff)
downloadFreeBSD-src-7d0a074b000ec2ba28f19904b5d4377aee2a816d.zip
FreeBSD-src-7d0a074b000ec2ba28f19904b5d4377aee2a816d.tar.gz
Break out non-inline out-of-band data receive code from soreceive()
and put it in its own helper function soreceive_rcvoob().
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/uipc_socket.c101
1 files changed, 63 insertions, 38 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 8d3e523..cb6ba3a 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -63,6 +63,9 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
+static int soreceive_rcvoob(struct socket *so, struct uio *uio,
+ int flags);
+
#ifdef INET
static int do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
#endif
@@ -831,6 +834,64 @@ out:
}
/*
+ * The part of soreceive() that implements reading non-inline out-of-band
+ * data from a socket. For more complete comments, see soreceive(), from
+ * which this code originated.
+ *
+ * XXXRW: Note that soreceive_rcvoob(), unlike the remainder of soreceve(),
+ * is unable to return an mbuf chain to the caller.
+ */
+static int
+soreceive_rcvoob(so, uio, flags)
+ struct socket *so;
+ struct uio *uio;
+ int flags;
+{
+ struct protosw *pr = so->so_proto;
+ struct mbuf *m;
+ int error;
+
+ KASSERT(flags & MSG_OOB, ("soreceive_rcvoob: (flags & MSG_OOB) == 0"));
+
+ m = m_get(M_TRYWAIT, MT_DATA);
+ if (m == NULL)
+ return (ENOBUFS);
+ error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
+ if (error)
+ goto bad;
+ do {
+#ifdef ZERO_COPY_SOCKETS
+ if (so_zero_copy_receive) {
+ vm_page_t pg;
+ int disposable;
+
+ if ((m->m_flags & M_EXT)
+ && (m->m_ext.ext_type == EXT_DISPOSABLE))
+ disposable = 1;
+ else
+ disposable = 0;
+
+ pg = PHYS_TO_VM_PAGE(vtophys(mtod(m, caddr_t)));
+ if (uio->uio_offset == -1)
+ uio->uio_offset =IDX_TO_OFF(pg->pindex);
+
+ error = uiomoveco(mtod(m, void *),
+ min(uio->uio_resid, m->m_len),
+ uio, pg->object,
+ disposable);
+ } else
+#endif /* ZERO_COPY_SOCKETS */
+ error = uiomove(mtod(m, void *),
+ (int) min(uio->uio_resid, m->m_len), uio);
+ m = m_free(m);
+ } while (uio->uio_resid && error == 0 && m);
+bad:
+ if (m != NULL)
+ m_freem(m);
+ return (error);
+}
+
+/*
* Implement receive operations on a socket.
* We depend on the way that records are added to the sockbuf
* by sbappend*. In particular, each record (mbufs linked through m_next)
@@ -871,44 +932,8 @@ soreceive(so, psa, uio, mp0, controlp, flagsp)
flags = *flagsp &~ MSG_EOR;
else
flags = 0;
- if (flags & MSG_OOB) {
- m = m_get(M_TRYWAIT, MT_DATA);
- if (m == NULL)
- return (ENOBUFS);
- error = (*pr->pr_usrreqs->pru_rcvoob)(so, m, flags & MSG_PEEK);
- if (error)
- goto bad;
- do {
-#ifdef ZERO_COPY_SOCKETS
- if (so_zero_copy_receive) {
- vm_page_t pg;
- int disposable;
-
- if ((m->m_flags & M_EXT)
- && (m->m_ext.ext_type == EXT_DISPOSABLE))
- disposable = 1;
- else
- disposable = 0;
-
- pg = PHYS_TO_VM_PAGE(vtophys(mtod(m, caddr_t)));
- if (uio->uio_offset == -1)
- uio->uio_offset =IDX_TO_OFF(pg->pindex);
-
- error = uiomoveco(mtod(m, void *),
- min(uio->uio_resid, m->m_len),
- uio, pg->object,
- disposable);
- } else
-#endif /* ZERO_COPY_SOCKETS */
- error = uiomove(mtod(m, void *),
- (int) min(uio->uio_resid, m->m_len), uio);
- m = m_free(m);
- } while (uio->uio_resid && error == 0 && m);
-bad:
- if (m != NULL)
- m_freem(m);
- return (error);
- }
+ if (flags & MSG_OOB)
+ return (soreceive_rcvoob(so, uio, flags));
if (mp != NULL)
*mp = NULL;
if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
OpenPOWER on IntegriCloud