Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.97.2.2 retrieving revision 1.98 diff -u -p -r1.97.2.2 -r1.98 --- src/sys/kern/uipc_socket.c 2005/10/31 13:37:33 1.97.2.2 +++ src/sys/kern/uipc_socket.c 2004/04/17 15:15:29 1.98 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.97.2.2 2005/10/31 13:37:33 tron Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.98 2004/04/17 15:15:29 christos Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.97.2.2 2005/10/31 13:37:33 tron Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.98 2004/04/17 15:15:29 christos Exp $"); #include "opt_sock_counters.h" #include "opt_sosend_loan.h" @@ -162,13 +162,14 @@ int sokvawaiters; static size_t sodopendfree(struct socket *); static size_t sodopendfreel(struct socket *); -static __inline void sokvareserve(struct socket *, vsize_t); +static __inline vsize_t sokvareserve(struct socket *, vsize_t); static __inline void sokvaunreserve(vsize_t); -static __inline void +static __inline vsize_t sokvareserve(struct socket *so, vsize_t len) { int s; + int error; s = splvm(); simple_lock(&so_pendfree_slock); @@ -190,12 +191,18 @@ sokvareserve(struct socket *so, vsize_t SOSEND_COUNTER_INCR(&sosend_kvalimit); sokvawaiters++; - (void) ltsleep(&socurkva, PVM, "sokva", 0, &so_pendfree_slock); + error = ltsleep(&socurkva, PVM | PCATCH, "sokva", 0, + &so_pendfree_slock); sokvawaiters--; + if (error) { + len = 0; + break; + } } socurkva += len; simple_unlock(&so_pendfree_slock); splx(s); + return len; } static __inline void @@ -225,7 +232,8 @@ sokvaalloc(vsize_t len, struct socket *s * reserve kva. */ - sokvareserve(so, len); + if (sokvareserve(so, len) == 0) + return 0; /* * allocate kva. @@ -479,6 +487,8 @@ socreate(int dom, struct socket **aso, i #endif if (p != 0) so->so_uid = p->p_ucred->cr_uid; + else + so->so_uid = UID_MAX; error = (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0, (struct mbuf *)(long)proto, (struct mbuf *)0, p); if (error) { @@ -540,7 +550,13 @@ sofree(struct socket *so) if (!soqremque(so, 0)) return; } - sbrelease(&so->so_snd); + if (so->so_rcv.sb_hiwat) + (void)chgsbsize(so->so_uid, &so->so_rcv.sb_hiwat, 0, + RLIM_INFINITY); + if (so->so_snd.sb_hiwat) + (void)chgsbsize(so->so_uid, &so->so_snd.sb_hiwat, 0, + RLIM_INFINITY); + sbrelease(&so->so_snd, so); sorflush(so); pool_put(&socket_pool, so); } @@ -1367,7 +1383,7 @@ sorflush(struct socket *so) splx(s); if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) (*pr->pr_domain->dom_dispose)(asb.sb_mb); - sbrelease(&asb); + sbrelease(&asb, so); } int @@ -1391,11 +1407,6 @@ sosetopt(struct socket *so, int level, i error = EINVAL; goto bad; } - if (mtod(m, struct linger *)->l_linger < 0 || - mtod(m, struct linger *)->l_linger > (INT_MAX / hz)) { - error = EDOM; - goto bad; - } so->so_linger = mtod(m, struct linger *)->l_linger; /* fall thru... */ @@ -1446,7 +1457,7 @@ sosetopt(struct socket *so, int level, i case SO_RCVBUF: if (sbreserve(optname == SO_SNDBUF ? &so->so_snd : &so->so_rcv, - (u_long) optval) == 0) { + (u_long) optval, so) == 0) { error = ENOBUFS; goto bad; } @@ -1769,9 +1780,7 @@ SYSCTL_SETUP(sysctl_kern_somaxkva_setup, sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, - CTLTYPE_INT, "somaxkva", - SYSCTL_DESCR("Maximum amount of kernel memory to be " - "used for socket buffers"), + CTLTYPE_INT, "somaxkva", NULL, sysctl_kern_somaxkva, 0, NULL, 0, CTL_KERN, KERN_SOMAXKVA, CTL_EOL); }