diff options
author | alc <alc@FreeBSD.org> | 2003-06-12 05:52:09 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-06-12 05:52:09 +0000 |
commit | e8221b068f0618b1fecdefbe059b3f7ca17f335c (patch) | |
tree | b41e24a9ea91a66fc5400ea81c97d20420e57928 /sys/kern | |
parent | c861fe160647d874cbd69f69aa7b07d02bb9f5a0 (diff) | |
download | FreeBSD-src-e8221b068f0618b1fecdefbe059b3f7ca17f335c.zip FreeBSD-src-e8221b068f0618b1fecdefbe059b3f7ca17f335c.tar.gz |
Finish the vm object locking in sendfile(2). More generally,
the vm locking in sendfile(2) is complete.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 4a49f8c..98be6d3 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1841,12 +1841,14 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) vm_offset_t pgoff; pindex = OFF_TO_IDX(off); + VM_OBJECT_LOCK(obj); retry_lookup: /* * Calculate the amount to transfer. Not to exceed a page, * the EOF, or the passed in nbytes. */ xfsize = obj->un_pager.vnp.vnp_size - off; + VM_OBJECT_UNLOCK(obj); if (xfsize > PAGE_SIZE) xfsize = PAGE_SIZE; pgoff = (vm_offset_t)(off & PAGE_MASK); @@ -1868,6 +1870,7 @@ retry_lookup: sbunlock(&so->so_snd); goto done; } + VM_OBJECT_LOCK(obj); /* * Attempt to look up the page. * @@ -1881,7 +1884,9 @@ retry_lookup: pg = vm_page_alloc(obj, pindex, VM_ALLOC_NORMAL | VM_ALLOC_WIRED); if (pg == NULL) { + VM_OBJECT_UNLOCK(obj); VM_WAIT; + VM_OBJECT_LOCK(obj); goto retry_lookup; } vm_page_lock_queues(); @@ -1910,6 +1915,7 @@ retry_lookup: */ vm_page_io_start(pg); vm_page_unlock_queues(); + VM_OBJECT_UNLOCK(obj); /* * Get the page from backing store. @@ -1948,7 +1954,8 @@ retry_lookup: sbunlock(&so->so_snd); goto done; } - } + } else + VM_OBJECT_UNLOCK(obj); vm_page_unlock_queues(); /* |