- local_offset = 0;
- while (size) {
- if(size > 4096 && vp->v_tag == VT_NFS) {
- xfer_size = 4096;
- size = size - xfer_size;
- } else {
- xfer_size = size;
- size = 0;
- }
- ubc_create_upl(vp, f_offset + local_offset, xfer_size,
- &vpupl, NULL, UPL_FLAGS_NONE);
- if (vpupl == (upl_t) 0) {
- result = PAGER_ABSENT;
- error = PAGER_ABSENT;
- goto out;
- }
+ dp_pgins++;
+ }
+ pages_in_upl = size / PAGE_SIZE;
+ first_pg = upl_offset / PAGE_SIZE;
+
+ /*
+ * before we start marching forward, we must make sure we end on
+ * a present page, otherwise we will be working with a freed
+ * upl
+ */
+ for (last_pg = pages_in_upl - 1; last_pg >= first_pg; last_pg--) {
+ if (upl_page_present(pl, last_pg))
+ break;
+ }
+ pages_in_upl = last_pg + 1;
+
+ for (last_pg = first_pg; last_pg < pages_in_upl;) {
+ /*
+ * scan the upl looking for the next
+ * page that is present.... if all of the
+ * pages are absent, we're done
+ */
+ for (start_pg = last_pg; last_pg < pages_in_upl; last_pg++) {
+ if (upl_page_present(pl, last_pg))
+ break;
+ }
+ if (last_pg == pages_in_upl)
+ break;
+
+ /*
+ * if we get here, we've sitting on a page
+ * that is present... we want to skip over
+ * any range of 'valid' pages... if this takes
+ * us to the end of the request, than we're done
+ */
+ for (start_pg = last_pg; last_pg < pages_in_upl; last_pg++) {
+ if (!upl_valid_page(pl, last_pg) || !upl_page_present(pl, last_pg))
+ break;
+ }
+ if (last_pg > start_pg) {
+ /*
+ * we've found a range of valid pages
+ * if we've got COMMIT responsibility
+ * commit this range of pages back to the
+ * cache unchanged
+ */
+ xsize = (last_pg - start_pg) * PAGE_SIZE;