Date: Mon, 31 Mar 2003 22:48:44 +0100 From: David Malone <dwmalone@maths.tcd.ie> To: arch@freebsd.org Cc: iedowse@freebsd.org Subject: Splitting up sendit Message-ID: <200303312248.aa21293@salmon.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
I wonder if anyone has any comments on this patch. It splits sendit into a part which just does the copyin of arguments and then calls a new function, kern_sendit which does the real work. The point of this is to allow the linux emulation code to avoid using the stackgap for send, sendto and sendmsg. The patch also moves the grabbing of giant into kern_sendit 'cos, as I understand it, neither copyin or the allocation of mbufs requires giant. David. Index: sys/kern/uipc_syscalls.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.145 diff -u -r1.145 uipc_syscalls.c --- sys/kern/uipc_syscalls.c 31 Mar 2003 06:25:42 -0000 1.145 +++ sys/kern/uipc_syscalls.c 31 Mar 2003 20:38:45 -0000 @@ -619,47 +619,18 @@ register struct msghdr *mp; int flags; { - struct uio auio; - register struct iovec *iov; - register int i; struct mbuf *control; - struct sockaddr *to = NULL; - int len, error; - struct socket *so; -#ifdef KTRACE - struct iovec *ktriov = NULL; - struct uio ktruio; - int iovlen; -#endif - - if ((error = fgetsock(td, s, &so, NULL)) != 0) - return (error); - -#ifdef MAC - error = mac_check_socket_send(td->td_ucred, so); - if (error) - goto bad; -#endif + struct sockaddr *to; + int error; - auio.uio_iov = mp->msg_iov; - auio.uio_iovcnt = mp->msg_iovlen; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_rw = UIO_WRITE; - auio.uio_td = td; - auio.uio_offset = 0; /* XXX */ - auio.uio_resid = 0; - iov = mp->msg_iov; - for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if ((auio.uio_resid += iov->iov_len) < 0) { - error = EINVAL; - goto bad; - } - } - if (mp->msg_name) { + if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); if (error) - goto bad; - } + return error; + mp->msg_name = to; + } else + to = NULL; + if (mp->msg_control) { if (mp->msg_controllen < sizeof(struct cmsghdr) #ifdef COMPAT_OLDSOCK @@ -690,7 +661,59 @@ } #endif } else { - control = 0; + control = NULL; + } + + error = kern_sendit(td, s, mp, flags, control); + +bad: + if (to) + FREE(to, M_SONAME); + return (error); +} + +int +kern_sendit(td, s, mp, flags, control) + struct thread *td; + int s; + struct msghdr *mp; + int flags; + struct mbuf *control; +{ + struct uio auio; + struct iovec *iov; + struct socket *so; + int i; + int len, error; +#ifdef KTRACE + struct iovec *ktriov = NULL; + struct uio ktruio; + int iovlen; +#endif + + mtx_lock(&Giant); + if ((error = fgetsock(td, s, &so, NULL)) != 0) + goto bad2; + +#ifdef MAC + error = mac_check_socket_send(td->td_ucred, so); + if (error) + goto bad; +#endif + + auio.uio_iov = mp->msg_iov; + auio.uio_iovcnt = mp->msg_iovlen; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_td = td; + auio.uio_offset = 0; /* XXX */ + auio.uio_resid = 0; + iov = mp->msg_iov; + for (i = 0; i < mp->msg_iovlen; i++, iov++) { + if ((auio.uio_resid += iov->iov_len) < 0) { + error = EINVAL; + goto bad; + } } #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) { @@ -701,8 +724,9 @@ } #endif len = auio.uio_resid; - error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, - flags, td); + error = so->so_proto->pr_usrreqs->pru_sosend(so, mp->msg_name, &auio, + 0, control, flags, td); + if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) @@ -728,8 +752,8 @@ #endif bad: fputsock(so); - if (to) - FREE(to, M_SONAME); +bad2: + mtx_unlock(&Giant); return (error); } @@ -762,9 +786,7 @@ #endif aiov.iov_base = uap->buf; aiov.iov_len = uap->len; - mtx_lock(&Giant); error = sendit(td, uap->s, &msg, uap->flags); - mtx_unlock(&Giant); return (error); } @@ -794,9 +816,7 @@ aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = 0; - mtx_lock(&Giant); error = sendit(td, uap->s, &msg, uap->flags); - mtx_unlock(&Giant); return (error); } @@ -816,7 +836,6 @@ struct iovec aiov[UIO_SMALLIOV], *iov; int error; - mtx_lock(&Giant); error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); if (error) goto done2; @@ -842,7 +861,6 @@ if (iov != aiov) FREE(iov, M_IOV); done2: - mtx_unlock(&Giant); return (error); } #endif @@ -863,7 +881,6 @@ struct iovec aiov[UIO_SMALLIOV], *iov; int error; - mtx_lock(&Giant); error = copyin(uap->msg, &msg, sizeof (msg)); if (error) goto done2; @@ -891,7 +908,6 @@ if (iov != aiov) FREE(iov, M_IOV); done2: - mtx_unlock(&Giant); return (error); } Index: sys/sys/syscallsubr.h =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/sys/syscallsubr.h,v retrieving revision 1.6 diff -u -r1.6 syscallsubr.h --- sys/sys/syscallsubr.h 3 Feb 2003 17:36:52 -0000 1.6 +++ sys/sys/syscallsubr.h 8 Feb 2003 20:47:07 -0000 @@ -32,6 +32,8 @@ #include <sys/uio.h> struct sockaddr; +struct msghdr; +struct mbuf; int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); @@ -70,6 +72,8 @@ int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, fd_set *fd_ex, struct timeval *tvp); +int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, + struct mbuf *control); int kern_sigaction(struct thread *td, int sig, struct sigaction *act, struct sigaction *oact, int flags); int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200303312248.aa21293>