+ failed_size = 0;
+
+ /*
+ * Adjust counts and send response to VM. Optimize for the
+ * common case, i.e. no error and/or partial data.
+ * If there was an error, then we need to error the entire
+ * range, even if some data was successfully read.
+ * If there was a partial read we may supply some
+ * data and may error some as well. In all cases the
+ * VM must receive some notification for every page in the
+ * range.
+ */
+ if ((error == KERN_SUCCESS) && (residual == 0)) {
+ /*
+ * Got everything we asked for, supply the data to
+ * the VM. Note that as a side effect of supplying
+ * the data, the buffer holding the supplied data is
+ * deallocated from the pager's address space.
+ */
+ pvs_object_data_provided(vs, upl, vs_offset, xfer_size);
+ } else {
+ failed_size = xfer_size;
+
+ if (error == KERN_SUCCESS) {
+ if (residual == xfer_size) {
+ /*
+ * If a read operation returns no error
+ * and no data moved, we turn it into
+ * an error, assuming we're reading at
+ * or beyong EOF.
+ * Fall through and error the entire
+ * range.
+ */
+ error = KERN_FAILURE;
+ } else {
+ /*
+ * Otherwise, we have partial read. If
+ * the part read is a integral number
+ * of pages supply it. Otherwise round
+ * it up to a page boundary, zero fill
+ * the unread part, and supply it.
+ * Fall through and error the remainder
+ * of the range, if any.
+ */
+ int fill, lsize;
+
+ fill = residual & ~vm_page_size;
+ lsize = (xfer_size - residual) + fill;
+ pvs_object_data_provided(vs, upl, vs_offset, lsize);
+
+ if (lsize < xfer_size) {
+ failed_size = xfer_size - lsize;
+ error = KERN_FAILURE;
+ }
+ }
+ }
+ }