diff options
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-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(); /* |