+ if ( (upl_flags & UPL_IOSYNC) && io_error)
+ upl_flags |= UPL_KEEPCACHED;
+
+ while (cnt) {
+ kern_return_t kr;
+
+ size = (cnt < (PAGE_SIZE * MAX_UPL_TRANSFER)) ? cnt : (PAGE_SIZE * MAX_UPL_TRANSFER); /* effective max */
+
+ request_flags = UPL_RET_ONLY_DIRTY | UPL_COPYOUT_FROM | UPL_CLEAN_IN_PLACE |
+ UPL_SET_INTERNAL | UPL_SET_LITE;
+
+ kr = memory_object_upl_request(vnode_object->control_handle,
+ offset, size, &upl, NULL, NULL, request_flags);
+ if (kr != KERN_SUCCESS)
+ panic("vnode_pager_cluster_write: upl request failed\n");
+
+ vnode_pageout(vnode_object->vnode_handle,
+ upl, (vm_offset_t)0, offset, size, upl_flags, &errno);
+
+ if ( (upl_flags & UPL_KEEPCACHED) ) {
+ if ( (*io_error = errno) )
+ break;
+ }
+ cnt -= size;
+ offset += size;
+ }
+ if (resid_offset)
+ *resid_offset = offset;
+
+ } else {
+ vm_object_offset_t vnode_size;
+ vm_object_offset_t base_offset;
+ vm_object_t object;
+ vm_page_t target_page;
+ int ticket;
+
+ /*
+ * this is the pageout path
+ */
+ vnode_size = vnode_pager_get_filesize(vnode_object->vnode_handle);
+
+ if (vnode_size > (offset + PAGE_SIZE)) {
+ /*
+ * preset the maximum size of the cluster
+ * and put us on a nice cluster boundary...
+ * and then clip the size to insure we
+ * don't request past the end of the underlying file
+ */
+ size = PAGE_SIZE * MAX_UPL_TRANSFER;
+ base_offset = offset & ~((signed)(size - 1));
+
+ if ((base_offset + size) > vnode_size)
+ size = round_page_32(((vm_size_t)(vnode_size - base_offset)));
+ } else {
+ /*
+ * we've been requested to page out a page beyond the current
+ * end of the 'file'... don't try to cluster in this case...
+ * we still need to send this page through because it might
+ * be marked precious and the underlying filesystem may need
+ * to do something with it (besides page it out)...
+ */
+ base_offset = offset;
+ size = PAGE_SIZE;
+ }
+ object = memory_object_control_to_vm_object(vnode_object->control_handle);
+
+ if (object == VM_OBJECT_NULL)
+ panic("vnode_pager_cluster_write: NULL vm_object in control handle\n");
+
+ request_flags = UPL_NOBLOCK | UPL_FOR_PAGEOUT | UPL_CLEAN_IN_PLACE |
+ UPL_RET_ONLY_DIRTY | UPL_COPYOUT_FROM |
+ UPL_SET_INTERNAL | UPL_SET_LITE;
+
+ vm_object_lock(object);
+
+ if ((target_page = vm_page_lookup(object, offset)) != VM_PAGE_NULL) {
+ /*
+ * only pick up pages whose ticket number matches
+ * the ticket number of the page orginally targeted
+ * for pageout
+ */
+ ticket = target_page->page_ticket;
+
+ request_flags |= ((ticket << UPL_PAGE_TICKET_SHIFT) & UPL_PAGE_TICKET_MASK);