diff options
author | kib <kib@FreeBSD.org> | 2009-01-03 13:24:08 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-01-03 13:24:08 +0000 |
commit | ac1b596fda316feecb2bc8a1cb16497b97cf347d (patch) | |
tree | f93d7d74242b43d90f0d5ae66178f38c2a8dd273 /sys/kern/uipc_cow.c | |
parent | b56f7e98e0bd71a121a4fecc03a2679f6602fefa (diff) | |
download | FreeBSD-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.c | 6 |
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 |