summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_cow.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-01-03 13:24:08 +0000
committerkib <kib@FreeBSD.org>2009-01-03 13:24:08 +0000
commitac1b596fda316feecb2bc8a1cb16497b97cf347d (patch)
treef93d7d74242b43d90f0d5ae66178f38c2a8dd273 /sys/kern/uipc_cow.c
parentb56f7e98e0bd71a121a4fecc03a2679f6602fefa (diff)
downloadFreeBSD-src-ac1b596fda316feecb2bc8a1cb16497b97cf347d.zip
FreeBSD-src-ac1b596fda316feecb2bc8a1cb16497b97cf347d.tar.gz
Extend the struct vm_page wire_count to u_int to avoid the overflow
of the counter, that may happen when too many sendfile(2) calls are being executed with this vnode [1]. To keep the size of the struct vm_page and offsets of the fields accessed by out-of-tree modules, swap the types and locations of the wire_count and cow fields. Add safety checks to detect cow overflow and force fallback to the normal copy code for zero-copy sockets. [2] Reported by: Anton Yuzhaninov <citrin citrin ru> [1] Suggested by: alc [2] Reviewed by: alc MFC after: 2 weeks
Diffstat (limited to 'sys/kern/uipc_cow.c')
-rw-r--r--sys/kern/uipc_cow.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/kern/uipc_cow.c b/sys/kern/uipc_cow.c
index 2e29ee3..52988dd 100644
--- a/sys/kern/uipc_cow.c
+++ b/sys/kern/uipc_cow.c
@@ -129,7 +129,11 @@ socow_setup(struct mbuf *m0, struct uio *uio)
* set up COW
*/
vm_page_lock_queues();
- vm_page_cowsetup(pp);
+ if (vm_page_cowsetup(pp) != 0) {
+ vm_page_unhold(pp);
+ vm_page_unlock_queues();
+ return (0);
+ }
/*
* wire the page for I/O
OpenPOWER on IntegriCloud