Deleted Added
full compact
vnode_pager.c (12662) vnode_pager.c (12767)
1/*
2 * Copyright (c) 1990 University of Utah.
3 * Copyright (c) 1991 The Regents of the University of California.
4 * All rights reserved.
5 * Copyright (c) 1993, 1994 John S. Dyson
6 * Copyright (c) 1995, David Greenman
7 *
8 * This code is derived from software contributed to Berkeley by

--- 24 unchanged lines hidden (view full) ---

33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
1/*
2 * Copyright (c) 1990 University of Utah.
3 * Copyright (c) 1991 The Regents of the University of California.
4 * All rights reserved.
5 * Copyright (c) 1993, 1994 John S. Dyson
6 * Copyright (c) 1995, David Greenman
7 *
8 * This code is derived from software contributed to Berkeley by

--- 24 unchanged lines hidden (view full) ---

33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
41 * $Id: vnode_pager.c,v 1.53 1995/11/20 12:19:11 phk Exp $
41 * $Id: vnode_pager.c,v 1.54 1995/12/07 12:48:31 davidg Exp $
42 */
43
44/*
45 * Page to/from files (vnodes).
46 */
47
48/*
49 * TODO:

--- 16 unchanged lines hidden (view full) ---

66#include <vm/vm_param.h>
67#include <vm/vm_prot.h>
68#include <vm/vm_object.h>
69#include <vm/vm_page.h>
70#include <vm/vm_pager.h>
71#include <vm/vnode_pager.h>
72#include <vm/vm_extern.h>
73
42 */
43
44/*
45 * Page to/from files (vnodes).
46 */
47
48/*
49 * TODO:

--- 16 unchanged lines hidden (view full) ---

66#include <vm/vm_param.h>
67#include <vm/vm_prot.h>
68#include <vm/vm_object.h>
69#include <vm/vm_page.h>
70#include <vm/vm_pager.h>
71#include <vm/vnode_pager.h>
72#include <vm/vm_extern.h>
73
74extern vm_offset_t vnode_pager_addr __P((struct vnode *vp, vm_offset_t address,
74extern vm_offset_t vnode_pager_addr __P((struct vnode *vp, vm_ooffset_t address,
75 int *run));
76extern void vnode_pager_iodone __P((struct buf *bp));
77extern int vnode_pager_input_smlfs __P((vm_object_t object, vm_page_t m));
78extern int vnode_pager_input_old __P((vm_object_t object, vm_page_t m));
79
80struct pagerops vnodepagerops = {
81 NULL,
82 vnode_pager_alloc,

--- 14 unchanged lines hidden (view full) ---

97 * Allocate (or lookup) pager for a vnode.
98 * Handle is a vnode pointer.
99 */
100vm_object_t
101vnode_pager_alloc(handle, size, prot, offset)
102 void *handle;
103 vm_size_t size;
104 vm_prot_t prot;
75 int *run));
76extern void vnode_pager_iodone __P((struct buf *bp));
77extern int vnode_pager_input_smlfs __P((vm_object_t object, vm_page_t m));
78extern int vnode_pager_input_old __P((vm_object_t object, vm_page_t m));
79
80struct pagerops vnodepagerops = {
81 NULL,
82 vnode_pager_alloc,

--- 14 unchanged lines hidden (view full) ---

97 * Allocate (or lookup) pager for a vnode.
98 * Handle is a vnode pointer.
99 */
100vm_object_t
101vnode_pager_alloc(handle, size, prot, offset)
102 void *handle;
103 vm_size_t size;
104 vm_prot_t prot;
105 vm_offset_t offset;
105 vm_ooffset_t offset;
106{
107 vm_object_t object;
108 struct vnode *vp;
109
110 /*
111 * Pageout to vnode, no can do yet.
112 */
113 if (handle == NULL)

--- 18 unchanged lines hidden (view full) ---

132 while (((object = vp->v_object) != NULL) && (object->flags & OBJ_DEAD)) {
133 tsleep(object, PVM, "vadead", 0);
134 }
135
136 if (object == NULL) {
137 /*
138 * And an object of the appropriate size
139 */
106{
107 vm_object_t object;
108 struct vnode *vp;
109
110 /*
111 * Pageout to vnode, no can do yet.
112 */
113 if (handle == NULL)

--- 18 unchanged lines hidden (view full) ---

132 while (((object = vp->v_object) != NULL) && (object->flags & OBJ_DEAD)) {
133 tsleep(object, PVM, "vadead", 0);
134 }
135
136 if (object == NULL) {
137 /*
138 * And an object of the appropriate size
139 */
140 object = vm_object_allocate(OBJT_VNODE, round_page(size));
140 object = vm_object_allocate(OBJT_VNODE, size);
141 object->flags = OBJ_CANPERSIST;
142
143 /*
144 * Hold a reference to the vnode and initialize object data.
145 */
146 VREF(vp);
141 object->flags = OBJ_CANPERSIST;
142
143 /*
144 * Hold a reference to the vnode and initialize object data.
145 */
146 VREF(vp);
147 object->un_pager.vnp.vnp_size = size;
147 object->un_pager.vnp.vnp_size = (vm_ooffset_t) size * PAGE_SIZE;
148
149 object->handle = handle;
150 vp->v_object = object;
151 } else {
152 /*
153 * vm_object_reference() will remove the object from the cache if
154 * found and gain a reference to the object.
155 */

--- 33 unchanged lines hidden (view full) ---

189
190 vp->v_object = NULL;
191 vp->v_flag &= ~(VTEXT | VVMIO);
192 vp->v_flag |= VAGE;
193 vrele(vp);
194}
195
196boolean_t
148
149 object->handle = handle;
150 vp->v_object = object;
151 } else {
152 /*
153 * vm_object_reference() will remove the object from the cache if
154 * found and gain a reference to the object.
155 */

--- 33 unchanged lines hidden (view full) ---

189
190 vp->v_object = NULL;
191 vp->v_flag &= ~(VTEXT | VVMIO);
192 vp->v_flag |= VAGE;
193 vrele(vp);
194}
195
196boolean_t
197vnode_pager_haspage(object, offset, before, after)
197vnode_pager_haspage(object, pindex, before, after)
198 vm_object_t object;
198 vm_object_t object;
199 vm_offset_t offset;
199 vm_pindex_t pindex;
200 int *before;
201 int *after;
202{
203 struct vnode *vp = object->handle;
204 daddr_t bn;
205 int err;
206 daddr_t reqblock;
207 int poff;
208 int bsize;
209 int pagesperblock;
210
211 /*
212 * If filesystem no longer mounted or offset beyond end of file we do
213 * not have the page.
214 */
200 int *before;
201 int *after;
202{
203 struct vnode *vp = object->handle;
204 daddr_t bn;
205 int err;
206 daddr_t reqblock;
207 int poff;
208 int bsize;
209 int pagesperblock;
210
211 /*
212 * If filesystem no longer mounted or offset beyond end of file we do
213 * not have the page.
214 */
215 if ((vp->v_mount == NULL) || (offset >= object->un_pager.vnp.vnp_size))
215 if ((vp->v_mount == NULL) ||
216 (IDX_TO_OFF(pindex) >= object->un_pager.vnp.vnp_size))
216 return FALSE;
217
218 bsize = vp->v_mount->mnt_stat.f_iosize;
219 pagesperblock = bsize / PAGE_SIZE;
217 return FALSE;
218
219 bsize = vp->v_mount->mnt_stat.f_iosize;
220 pagesperblock = bsize / PAGE_SIZE;
220 reqblock = offset / bsize;
221 reqblock = pindex / pagesperblock;
221 err = VOP_BMAP(vp, reqblock, (struct vnode **) 0, &bn,
222 after, before);
223 if (err)
224 return TRUE;
225 if ( bn == -1)
226 return FALSE;
222 err = VOP_BMAP(vp, reqblock, (struct vnode **) 0, &bn,
223 after, before);
224 if (err)
225 return TRUE;
226 if ( bn == -1)
227 return FALSE;
227 poff = (offset - (reqblock * bsize)) / PAGE_SIZE;
228 poff = pindex - (reqblock * pagesperblock);
228 if (before) {
229 *before *= pagesperblock;
230 *before += poff;
231 }
232 if (after) {
233 int numafter;
234 *after *= pagesperblock;
235 numafter = pagesperblock - (poff + 1);
229 if (before) {
230 *before *= pagesperblock;
231 *before += poff;
232 }
233 if (after) {
234 int numafter;
235 *after *= pagesperblock;
236 numafter = pagesperblock - (poff + 1);
236 if (offset + numafter * PAGE_SIZE > object->un_pager.vnp.vnp_size) {
237 numafter = (object->un_pager.vnp.vnp_size - offset)/PAGE_SIZE;
237 if (IDX_TO_OFF(pindex + numafter) > object->un_pager.vnp.vnp_size) {
238 numafter = OFF_TO_IDX((object->un_pager.vnp.vnp_size - IDX_TO_OFF(pindex)));
238 }
239 *after += numafter;
240 }
241 return TRUE;
242}
243
244/*
245 * Lets the VM system know about a change in size for a file.
246 * We adjust our own internal size and flush any cached pages in
247 * the associated object that are affected by the size change.
248 *
249 * Note: this routine may be invoked as a result of a pager put
250 * operation (possibly at object termination time), so we must be careful.
251 */
252void
253vnode_pager_setsize(vp, nsize)
254 struct vnode *vp;
239 }
240 *after += numafter;
241 }
242 return TRUE;
243}
244
245/*
246 * Lets the VM system know about a change in size for a file.
247 * We adjust our own internal size and flush any cached pages in
248 * the associated object that are affected by the size change.
249 *
250 * Note: this routine may be invoked as a result of a pager put
251 * operation (possibly at object termination time), so we must be careful.
252 */
253void
254vnode_pager_setsize(vp, nsize)
255 struct vnode *vp;
255 u_long nsize;
256 vm_ooffset_t nsize;
256{
257 vm_object_t object = vp->v_object;
258
259 if (object == NULL)
260 return;
261
262 /*
263 * Hasn't changed size
264 */
265 if (nsize == object->un_pager.vnp.vnp_size)
266 return;
267
268 /*
269 * File has shrunk. Toss any cached pages beyond the new EOF.
270 */
271 if (nsize < object->un_pager.vnp.vnp_size) {
257{
258 vm_object_t object = vp->v_object;
259
260 if (object == NULL)
261 return;
262
263 /*
264 * Hasn't changed size
265 */
266 if (nsize == object->un_pager.vnp.vnp_size)
267 return;
268
269 /*
270 * File has shrunk. Toss any cached pages beyond the new EOF.
271 */
272 if (nsize < object->un_pager.vnp.vnp_size) {
272 if (round_page((vm_offset_t) nsize) < object->un_pager.vnp.vnp_size) {
273 vm_ooffset_t nsizerounded;
274 nsizerounded = IDX_TO_OFF(OFF_TO_IDX(nsize + PAGE_SIZE - 1));
275 if (nsizerounded < object->un_pager.vnp.vnp_size) {
273 vm_object_page_remove(object,
276 vm_object_page_remove(object,
274 round_page((vm_offset_t) nsize), object->un_pager.vnp.vnp_size, FALSE);
277 OFF_TO_IDX(nsize + PAGE_SIZE - 1),
278 OFF_TO_IDX(object->un_pager.vnp.vnp_size),
279 FALSE);
275 }
276 /*
277 * this gets rid of garbage at the end of a page that is now
278 * only partially backed by the vnode...
279 */
280 if (nsize & PAGE_MASK) {
281 vm_offset_t kva;
282 vm_page_t m;
283
280 }
281 /*
282 * this gets rid of garbage at the end of a page that is now
283 * only partially backed by the vnode...
284 */
285 if (nsize & PAGE_MASK) {
286 vm_offset_t kva;
287 vm_page_t m;
288
284 m = vm_page_lookup(object, trunc_page((vm_offset_t) nsize));
289 m = vm_page_lookup(object, OFF_TO_IDX(nsize));
285 if (m) {
286 kva = vm_pager_map_page(m);
287 bzero((caddr_t) kva + (nsize & PAGE_MASK),
290 if (m) {
291 kva = vm_pager_map_page(m);
292 bzero((caddr_t) kva + (nsize & PAGE_MASK),
288 round_page(nsize) - nsize);
293 (int) (round_page(nsize) - nsize));
289 vm_pager_unmap_page(kva);
290 }
291 }
292 }
294 vm_pager_unmap_page(kva);
295 }
296 }
297 }
293 object->un_pager.vnp.vnp_size = (vm_offset_t) nsize;
294 object->size = round_page(nsize);
298 object->un_pager.vnp.vnp_size = nsize;
299 object->size = OFF_TO_IDX(nsize + PAGE_SIZE - 1);
295}
296
297void
298vnode_pager_umount(mp)
299 register struct mount *mp;
300{
301 struct vnode *vp, *nvp;
302

--- 60 unchanged lines hidden (view full) ---

363
364/*
365 * calculate the linear (byte) disk address of specified virtual
366 * file address
367 */
368vm_offset_t
369vnode_pager_addr(vp, address, run)
370 struct vnode *vp;
300}
301
302void
303vnode_pager_umount(mp)
304 register struct mount *mp;
305{
306 struct vnode *vp, *nvp;
307

--- 60 unchanged lines hidden (view full) ---

368
369/*
370 * calculate the linear (byte) disk address of specified virtual
371 * file address
372 */
373vm_offset_t
374vnode_pager_addr(vp, address, run)
375 struct vnode *vp;
371 vm_offset_t address;
376 vm_ooffset_t address;
372 int *run;
373{
374 int rtaddress;
375 int bsize;
377 int *run;
378{
379 int rtaddress;
380 int bsize;
376 vm_offset_t block;
381 daddr_t block;
377 struct vnode *rtvp;
378 int err;
382 struct vnode *rtvp;
383 int err;
379 int vblock, voffset;
384 daddr_t vblock;
385 int voffset;
380
381 if ((int) address < 0)
382 return -1;
383
384 if (vp->v_mount == NULL)
385 return -1;
386
387 bsize = vp->v_mount->mnt_stat.f_iosize;

--- 52 unchanged lines hidden (view full) ---

440
441
442 VOP_BMAP(vp, 0, &dp, 0, NULL, NULL);
443
444 kva = vm_pager_map_page(m);
445
446 for (i = 0; i < PAGE_SIZE / bsize; i++) {
447
386
387 if ((int) address < 0)
388 return -1;
389
390 if (vp->v_mount == NULL)
391 return -1;
392
393 bsize = vp->v_mount->mnt_stat.f_iosize;

--- 52 unchanged lines hidden (view full) ---

446
447
448 VOP_BMAP(vp, 0, &dp, 0, NULL, NULL);
449
450 kva = vm_pager_map_page(m);
451
452 for (i = 0; i < PAGE_SIZE / bsize; i++) {
453
448 if ((vm_page_bits(m->offset + i * bsize, bsize) & m->valid))
454 if ((vm_page_bits(IDX_TO_OFF(m->pindex) + i * bsize, bsize) & m->valid))
449 continue;
450
455 continue;
456
451 fileaddr = vnode_pager_addr(vp, m->offset + i * bsize, (int *)0);
457 fileaddr = vnode_pager_addr(vp,
458 IDX_TO_OFF(m->pindex) + i * bsize, (int *)0);
452 if (fileaddr != -1) {
453 bp = getpbuf();
454
455 /* build a minimal buffer header */
456 bp->b_flags = B_BUSY | B_READ | B_CALL;
457 bp->b_iodone = vnode_pager_iodone;
458 bp->b_proc = curproc;
459 bp->b_rcred = bp->b_wcred = bp->b_proc->p_ucred;

--- 58 unchanged lines hidden (view full) ---

518 int size;
519 vm_offset_t kva;
520
521 error = 0;
522
523 /*
524 * Return failure if beyond current EOF
525 */
459 if (fileaddr != -1) {
460 bp = getpbuf();
461
462 /* build a minimal buffer header */
463 bp->b_flags = B_BUSY | B_READ | B_CALL;
464 bp->b_iodone = vnode_pager_iodone;
465 bp->b_proc = curproc;
466 bp->b_rcred = bp->b_wcred = bp->b_proc->p_ucred;

--- 58 unchanged lines hidden (view full) ---

525 int size;
526 vm_offset_t kva;
527
528 error = 0;
529
530 /*
531 * Return failure if beyond current EOF
532 */
526 if (m->offset >= object->un_pager.vnp.vnp_size) {
533 if (IDX_TO_OFF(m->pindex) >= object->un_pager.vnp.vnp_size) {
527 return VM_PAGER_BAD;
528 } else {
529 size = PAGE_SIZE;
534 return VM_PAGER_BAD;
535 } else {
536 size = PAGE_SIZE;
530 if (m->offset + size > object->un_pager.vnp.vnp_size)
531 size = object->un_pager.vnp.vnp_size - m->offset;
537 if (IDX_TO_OFF(m->pindex) + size > object->un_pager.vnp.vnp_size)
538 size = object->un_pager.vnp.vnp_size - IDX_TO_OFF(m->pindex);
532
533 /*
534 * Allocate a kernel virtual address and initialize so that
535 * we can use VOP_READ/WRITE routines.
536 */
537 kva = vm_pager_map_page(m);
538
539 aiov.iov_base = (caddr_t) kva;
540 aiov.iov_len = size;
541 auio.uio_iov = &aiov;
542 auio.uio_iovcnt = 1;
539
540 /*
541 * Allocate a kernel virtual address and initialize so that
542 * we can use VOP_READ/WRITE routines.
543 */
544 kva = vm_pager_map_page(m);
545
546 aiov.iov_base = (caddr_t) kva;
547 aiov.iov_len = size;
548 auio.uio_iov = &aiov;
549 auio.uio_iovcnt = 1;
543 auio.uio_offset = m->offset;
550 auio.uio_offset = IDX_TO_OFF(m->pindex);
544 auio.uio_segflg = UIO_SYSSPACE;
545 auio.uio_rw = UIO_READ;
546 auio.uio_resid = size;
547 auio.uio_procp = (struct proc *) 0;
548
549 error = VOP_READ(object->handle, &auio, 0, curproc->p_ucred);
550 if (!error) {
551 register int count = size - auio.uio_resid;

--- 34 unchanged lines hidden (view full) ---

586
587static int
588vnode_pager_leaf_getpages(object, m, count, reqpage)
589 vm_object_t object;
590 vm_page_t *m;
591 int count;
592 int reqpage;
593{
551 auio.uio_segflg = UIO_SYSSPACE;
552 auio.uio_rw = UIO_READ;
553 auio.uio_resid = size;
554 auio.uio_procp = (struct proc *) 0;
555
556 error = VOP_READ(object->handle, &auio, 0, curproc->p_ucred);
557 if (!error) {
558 register int count = size - auio.uio_resid;

--- 34 unchanged lines hidden (view full) ---

593
594static int
595vnode_pager_leaf_getpages(object, m, count, reqpage)
596 vm_object_t object;
597 vm_page_t *m;
598 int count;
599 int reqpage;
600{
594 vm_offset_t kva, foff;
601 vm_offset_t kva;
602 off_t foff;
595 int i, size, bsize, first, firstaddr;
596 struct vnode *dp, *vp;
597 int runpg;
598 int runend;
599 struct buf *bp;
600 int s;
601 int error = 0;
602

--- 4 unchanged lines hidden (view full) ---

607 bsize = vp->v_mount->mnt_stat.f_iosize;
608
609 /* get the UNDERLYING device for the file with VOP_BMAP() */
610
611 /*
612 * originally, we did not check for an error return value -- assuming
613 * an fs always has a bmap entry point -- that assumption is wrong!!!
614 */
603 int i, size, bsize, first, firstaddr;
604 struct vnode *dp, *vp;
605 int runpg;
606 int runend;
607 struct buf *bp;
608 int s;
609 int error = 0;
610

--- 4 unchanged lines hidden (view full) ---

615 bsize = vp->v_mount->mnt_stat.f_iosize;
616
617 /* get the UNDERLYING device for the file with VOP_BMAP() */
618
619 /*
620 * originally, we did not check for an error return value -- assuming
621 * an fs always has a bmap entry point -- that assumption is wrong!!!
622 */
615 foff = m[reqpage]->offset;
623 foff = IDX_TO_OFF(m[reqpage]->pindex);
616
617 /*
618 * if we can't bmap, use old VOP code
619 */
620 if (VOP_BMAP(vp, 0, &dp, 0, NULL, NULL)) {
621 for (i = 0; i < count; i++) {
622 if (i != reqpage) {
623 vnode_pager_freepage(m[i]);

--- 37 unchanged lines hidden (view full) ---

661 * here on direct device I/O
662 */
663
664 firstaddr = -1;
665 /*
666 * calculate the run that includes the required page
667 */
668 for(first = 0, i = 0; i < count; i = runend) {
624
625 /*
626 * if we can't bmap, use old VOP code
627 */
628 if (VOP_BMAP(vp, 0, &dp, 0, NULL, NULL)) {
629 for (i = 0; i < count; i++) {
630 if (i != reqpage) {
631 vnode_pager_freepage(m[i]);

--- 37 unchanged lines hidden (view full) ---

669 * here on direct device I/O
670 */
671
672 firstaddr = -1;
673 /*
674 * calculate the run that includes the required page
675 */
676 for(first = 0, i = 0; i < count; i = runend) {
669 firstaddr = vnode_pager_addr(vp, m[i]->offset, &runpg);
677 firstaddr = vnode_pager_addr(vp,
678 IDX_TO_OFF(m[i]->pindex), &runpg);
670 if (firstaddr == -1) {
671 if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {
672 panic("vnode_pager_putpages: unexpected missing page: firstaddr: %d, foff: %ld, vnp_size: %d",
673 firstaddr, foff, object->un_pager.vnp.vnp_size);
674 }
675 vnode_pager_freepage(m[i]);
676 runend = i + 1;
677 first = runend;

--- 26 unchanged lines hidden (view full) ---

704 }
705 count -= first;
706 reqpage -= first;
707 }
708
709 /*
710 * calculate the file virtual address for the transfer
711 */
679 if (firstaddr == -1) {
680 if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {
681 panic("vnode_pager_putpages: unexpected missing page: firstaddr: %d, foff: %ld, vnp_size: %d",
682 firstaddr, foff, object->un_pager.vnp.vnp_size);
683 }
684 vnode_pager_freepage(m[i]);
685 runend = i + 1;
686 first = runend;

--- 26 unchanged lines hidden (view full) ---

713 }
714 count -= first;
715 reqpage -= first;
716 }
717
718 /*
719 * calculate the file virtual address for the transfer
720 */
712 foff = m[0]->offset;
721 foff = IDX_TO_OFF(m[0]->pindex);
713
714 /*
715 * calculate the size of the transfer
716 */
717 size = count * PAGE_SIZE;
718 if ((foff + size) > object->un_pager.vnp.vnp_size)
719 size = object->un_pager.vnp.vnp_size - foff;
720

--- 114 unchanged lines hidden (view full) ---

835 int count;
836 boolean_t sync;
837 int *rtvals;
838{
839 int i;
840
841 struct vnode *vp;
842 int maxsize, ncount;
722
723 /*
724 * calculate the size of the transfer
725 */
726 size = count * PAGE_SIZE;
727 if ((foff + size) > object->un_pager.vnp.vnp_size)
728 size = object->un_pager.vnp.vnp_size - foff;
729

--- 114 unchanged lines hidden (view full) ---

844 int count;
845 boolean_t sync;
846 int *rtvals;
847{
848 int i;
849
850 struct vnode *vp;
851 int maxsize, ncount;
852 vm_ooffset_t poffset;
843 struct uio auio;
844 struct iovec aiov;
845 int error;
846
847 vp = object->handle;;
848 for (i = 0; i < count; i++)
849 rtvals[i] = VM_PAGER_AGAIN;
850
853 struct uio auio;
854 struct iovec aiov;
855 int error;
856
857 vp = object->handle;;
858 for (i = 0; i < count; i++)
859 rtvals[i] = VM_PAGER_AGAIN;
860
851 if ((int) m[0]->offset < 0) {
852 printf("vnode_pager_putpages: attempt to write meta-data!!! -- 0x%x(%x)\n", m[0]->offset, m[0]->dirty);
861 if ((int) m[0]->pindex < 0) {
862 printf("vnode_pager_putpages: attempt to write meta-data!!! -- 0x%x(%x)\n", m[0]->pindex, m[0]->dirty);
853 rtvals[0] = VM_PAGER_BAD;
854 return VM_PAGER_BAD;
855 }
856
857 maxsize = count * PAGE_SIZE;
858 ncount = count;
859
863 rtvals[0] = VM_PAGER_BAD;
864 return VM_PAGER_BAD;
865 }
866
867 maxsize = count * PAGE_SIZE;
868 ncount = count;
869
860 if (maxsize + m[0]->offset > object->un_pager.vnp.vnp_size) {
861 if (object->un_pager.vnp.vnp_size > m[0]->offset)
862 maxsize = object->un_pager.vnp.vnp_size - m[0]->offset;
870 poffset = IDX_TO_OFF(m[0]->pindex);
871 if (maxsize + poffset > object->un_pager.vnp.vnp_size) {
872 if (object->un_pager.vnp.vnp_size > poffset)
873 maxsize = object->un_pager.vnp.vnp_size - poffset;
863 else
864 maxsize = 0;
865 ncount = (maxsize + PAGE_SIZE - 1) / PAGE_SIZE;
866 if (ncount < count) {
867 for (i = ncount; i < count; i++) {
868 rtvals[i] = VM_PAGER_BAD;
869 }
874 else
875 maxsize = 0;
876 ncount = (maxsize + PAGE_SIZE - 1) / PAGE_SIZE;
877 if (ncount < count) {
878 for (i = ncount; i < count; i++) {
879 rtvals[i] = VM_PAGER_BAD;
880 }
881#ifdef BOGUS
870 if (ncount == 0) {
882 if (ncount == 0) {
871 printf("vnode_pager_putpages: write past end of file: %ld, %ld\n",
872 m[0]->offset,
873 object->un_pager.vnp.vnp_size);
883 printf("vnode_pager_putpages: write past end of file: %d, %lu\n",
884 poffset,
885 (unsigned long) object->un_pager.vnp.vnp_size);
874 return rtvals[0];
875 }
886 return rtvals[0];
887 }
888#endif
876 }
877 }
878
879 for (i = 0; i < count; i++) {
880 m[i]->busy++;
881 m[i]->flags &= ~PG_BUSY;
882 }
883
884 aiov.iov_base = (caddr_t) 0;
885 aiov.iov_len = maxsize;
886 auio.uio_iov = &aiov;
887 auio.uio_iovcnt = 1;
889 }
890 }
891
892 for (i = 0; i < count; i++) {
893 m[i]->busy++;
894 m[i]->flags &= ~PG_BUSY;
895 }
896
897 aiov.iov_base = (caddr_t) 0;
898 aiov.iov_len = maxsize;
899 auio.uio_iov = &aiov;
900 auio.uio_iovcnt = 1;
888 auio.uio_offset = m[0]->offset;
901 auio.uio_offset = poffset;
889 auio.uio_segflg = UIO_NOCOPY;
890 auio.uio_rw = UIO_WRITE;
891 auio.uio_resid = maxsize;
892 auio.uio_procp = (struct proc *) 0;
902 auio.uio_segflg = UIO_NOCOPY;
903 auio.uio_rw = UIO_WRITE;
904 auio.uio_resid = maxsize;
905 auio.uio_procp = (struct proc *) 0;
893 error = VOP_WRITE(vp, &auio, IO_VMIO, curproc->p_ucred);
906 error = VOP_WRITE(vp, &auio, IO_VMIO|(sync?IO_SYNC:0), curproc->p_ucred);
894 cnt.v_vnodeout++;
895 cnt.v_vnodepgsout += ncount;
896
897 if (error) {
898 printf("vnode_pager_putpages: I/O error %d\n", error);
899 }
900 if (auio.uio_resid) {
907 cnt.v_vnodeout++;
908 cnt.v_vnodepgsout += ncount;
909
910 if (error) {
911 printf("vnode_pager_putpages: I/O error %d\n", error);
912 }
913 if (auio.uio_resid) {
901 printf("vnode_pager_putpages: residual I/O %d at %ld\n",
902 auio.uio_resid, m[0]->offset);
914 printf("vnode_pager_putpages: residual I/O %d at %d\n",
915 auio.uio_resid, m[0]->pindex);
903 }
904 for (i = 0; i < count; i++) {
905 m[i]->busy--;
906 if (i < ncount) {
907 rtvals[i] = VM_PAGER_OK;
908 }
909 if ((m[i]->busy == 0) && (m[i]->flags & PG_WANTED))
910 wakeup(m[i]);

--- 17 unchanged lines hidden ---
916 }
917 for (i = 0; i < count; i++) {
918 m[i]->busy--;
919 if (i < ncount) {
920 rtvals[i] = VM_PAGER_OK;
921 }
922 if ((m[i]->busy == 0) && (m[i]->flags & PG_WANTED))
923 wakeup(m[i]);

--- 17 unchanged lines hidden ---