sctp_syscalls.c (62378) | sctp_syscalls.c (64837) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * sendfile(2) and related extensions: 6 * Copyright (c) 1998, David Greenman. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 20 unchanged lines hidden (view full) --- 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 |
37 * $FreeBSD: head/sys/kern/uipc_syscalls.c 62378 2000-07-02 08:08:09Z green $ | 37 * $FreeBSD: head/sys/kern/uipc_syscalls.c 64837 2000-08-19 08:32:59Z dwmalone $ |
38 */ 39 40#include "opt_compat.h" 41#include "opt_ktrace.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> --- 21 unchanged lines hidden (view full) --- 67#include <vm/vm_page.h> 68#include <vm/vm_pageout.h> 69#include <vm/vm_kern.h> 70#include <vm/vm_extern.h> 71 72static void sf_buf_init(void *arg); 73SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) 74static struct sf_buf *sf_buf_alloc(void); | 38 */ 39 40#include "opt_compat.h" 41#include "opt_ktrace.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> --- 21 unchanged lines hidden (view full) --- 67#include <vm/vm_page.h> 68#include <vm/vm_pageout.h> 69#include <vm/vm_kern.h> 70#include <vm/vm_extern.h> 71 72static void sf_buf_init(void *arg); 73SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) 74static struct sf_buf *sf_buf_alloc(void); |
75static void sf_buf_ref(caddr_t addr, u_int size); 76static void sf_buf_free(caddr_t addr, u_int size); | 75static void sf_buf_free(caddr_t addr, void *args); |
77 78static int sendit __P((struct proc *p, int s, struct msghdr *mp, int flags)); 79static int recvit __P((struct proc *p, int s, struct msghdr *mp, 80 caddr_t namelenp)); 81 82static int accept1 __P((struct proc *p, struct accept_args *uap, int compat)); 83static int getsockname1 __P((struct proc *p, struct getsockname_args *uap, 84 int compat)); --- 1264 unchanged lines hidden (view full) --- 1349 1350 s = splimp(); 1351 while ((sf = SLIST_FIRST(&sf_freelist)) == NULL) { 1352 sf_buf_alloc_want = 1; 1353 tsleep(&sf_freelist, PVM, "sfbufa", 0); 1354 } 1355 SLIST_REMOVE_HEAD(&sf_freelist, free_list); 1356 splx(s); | 76 77static int sendit __P((struct proc *p, int s, struct msghdr *mp, int flags)); 78static int recvit __P((struct proc *p, int s, struct msghdr *mp, 79 caddr_t namelenp)); 80 81static int accept1 __P((struct proc *p, struct accept_args *uap, int compat)); 82static int getsockname1 __P((struct proc *p, struct getsockname_args *uap, 83 int compat)); --- 1264 unchanged lines hidden (view full) --- 1348 1349 s = splimp(); 1350 while ((sf = SLIST_FIRST(&sf_freelist)) == NULL) { 1351 sf_buf_alloc_want = 1; 1352 tsleep(&sf_freelist, PVM, "sfbufa", 0); 1353 } 1354 SLIST_REMOVE_HEAD(&sf_freelist, free_list); 1355 splx(s); |
1357 sf->refcnt = 1; | |
1358 return (sf); 1359} 1360 1361#define dtosf(x) (&sf_bufs[((uintptr_t)(x) - (uintptr_t)sf_base) >> PAGE_SHIFT]) | 1356 return (sf); 1357} 1358 1359#define dtosf(x) (&sf_bufs[((uintptr_t)(x) - (uintptr_t)sf_base) >> PAGE_SHIFT]) |
1362static void 1363sf_buf_ref(caddr_t addr, u_int size) 1364{ 1365 struct sf_buf *sf; | |
1366 | 1360 |
1367 sf = dtosf(addr); 1368 if (sf->refcnt == 0) 1369 panic("sf_buf_ref: referencing a free sf_buf"); 1370 sf->refcnt++; 1371} 1372 | |
1373/* | 1361/* |
1374 * Lose a reference to an sf_buf. When none left, detach mapped page 1375 * and release resources back to the system. | |
1376 * | 1362 * |
1363 * Detatch mapped page and release resources back to the system. 1364 * |
|
1377 * Must be called at splimp. 1378 */ 1379static void | 1365 * Must be called at splimp. 1366 */ 1367static void |
1380sf_buf_free(caddr_t addr, u_int size) | 1368sf_buf_free(caddr_t addr, void *args) |
1381{ 1382 struct sf_buf *sf; 1383 struct vm_page *m; 1384 int s; 1385 1386 sf = dtosf(addr); | 1369{ 1370 struct sf_buf *sf; 1371 struct vm_page *m; 1372 int s; 1373 1374 sf = dtosf(addr); |
1387 if (sf->refcnt == 0) 1388 panic("sf_buf_free: freeing free sf_buf"); 1389 sf->refcnt--; 1390 if (sf->refcnt == 0) { 1391 pmap_qremove((vm_offset_t)addr, 1); 1392 m = sf->m; 1393 s = splvm(); 1394 vm_page_unwire(m, 0); 1395 /* 1396 * Check for the object going away on us. This can 1397 * happen since we don't hold a reference to it. 1398 * If so, we're responsible for freeing the page. 1399 */ 1400 if (m->wire_count == 0 && m->object == NULL) 1401 vm_page_free(m); 1402 splx(s); 1403 sf->m = NULL; 1404 SLIST_INSERT_HEAD(&sf_freelist, sf, free_list); 1405 if (sf_buf_alloc_want) { 1406 sf_buf_alloc_want = 0; 1407 wakeup(&sf_freelist); 1408 } | 1375 pmap_qremove((vm_offset_t)addr, 1); 1376 m = sf->m; 1377 s = splvm(); 1378 vm_page_unwire(m, 0); 1379 /* 1380 * Check for the object going away on us. This can 1381 * happen since we don't hold a reference to it. 1382 * If so, we're responsible for freeing the page. 1383 */ 1384 if (m->wire_count == 0 && m->object == NULL) 1385 vm_page_free(m); 1386 splx(s); 1387 sf->m = NULL; 1388 SLIST_INSERT_HEAD(&sf_freelist, sf, free_list); 1389 if (sf_buf_alloc_want) { 1390 sf_buf_alloc_want = 0; 1391 wakeup(&sf_freelist); |
1409 } 1410} 1411 1412/* 1413 * sendfile(2). 1414 * int sendfile(int fd, int s, off_t offset, size_t nbytes, 1415 * struct sf_hdtr *hdtr, off_t *sbytes, int flags) 1416 * --- 208 unchanged lines hidden (view full) --- 1625 /* 1626 * Get an mbuf header and set it up as having external storage. 1627 */ 1628 MGETHDR(m, M_WAIT, MT_DATA); 1629 if (m == NULL) { 1630 error = ENOBUFS; 1631 goto done; 1632 } | 1392 } 1393} 1394 1395/* 1396 * sendfile(2). 1397 * int sendfile(int fd, int s, off_t offset, size_t nbytes, 1398 * struct sf_hdtr *hdtr, off_t *sbytes, int flags) 1399 * --- 208 unchanged lines hidden (view full) --- 1608 /* 1609 * Get an mbuf header and set it up as having external storage. 1610 */ 1611 MGETHDR(m, M_WAIT, MT_DATA); 1612 if (m == NULL) { 1613 error = ENOBUFS; 1614 goto done; 1615 } |
1633 m->m_ext.ext_free = sf_buf_free; 1634 m->m_ext.ext_ref = sf_buf_ref; 1635 m->m_ext.ext_buf = (void *)sf->kva; 1636 m->m_ext.ext_size = PAGE_SIZE; | 1616 /* 1617 * Setup external storage for mbuf. 1618 */ 1619 MEXTADD(m, sf->kva, PAGE_SIZE, sf_buf_free, NULL); |
1637 m->m_data = (char *) sf->kva + pgoff; | 1620 m->m_data = (char *) sf->kva + pgoff; |
1638 m->m_flags |= M_EXT; | |
1639 m->m_pkthdr.len = m->m_len = xfsize; 1640 /* 1641 * Add the buffer to the socket buffer chain. 1642 */ 1643 s = splnet(); 1644retry_space: 1645 /* 1646 * Make sure that the socket is still able to take more data. --- 78 unchanged lines hidden --- | 1621 m->m_pkthdr.len = m->m_len = xfsize; 1622 /* 1623 * Add the buffer to the socket buffer chain. 1624 */ 1625 s = splnet(); 1626retry_space: 1627 /* 1628 * Make sure that the socket is still able to take more data. --- 78 unchanged lines hidden --- |