]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/fs/specfs/spec_vnops.c
Remove unused #includes.
[FreeBSD/FreeBSD.git] / sys / fs / specfs / spec_vnops.c
1 /*
2  * Copyright (c) 1989, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      @(#)spec_vnops.c        8.14 (Berkeley) 5/21/95
34  * $FreeBSD$
35  */
36
37 #include <sys/param.h>
38 #include <sys/proc.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/conf.h>
42 #include <sys/buf.h>
43 #include <sys/mount.h>
44 #include <sys/vnode.h>
45 #include <sys/stat.h>
46 #include <sys/fcntl.h>
47 #include <sys/vmmeter.h>
48 #include <sys/tty.h>
49
50 #include <vm/vm.h>
51 #include <vm/vm_object.h>
52 #include <vm/vm_page.h>
53 #include <vm/vm_pager.h>
54
55 static int      spec_advlock __P((struct vop_advlock_args *));  
56 static int      spec_bmap __P((struct vop_bmap_args *));
57 static int      spec_close __P((struct vop_close_args *));
58 static int      spec_freeblks __P((struct vop_freeblks_args *));
59 static int      spec_fsync __P((struct  vop_fsync_args *));
60 static int      spec_getpages __P((struct vop_getpages_args *));
61 static int      spec_inactive __P((struct  vop_inactive_args *));
62 static int      spec_ioctl __P((struct vop_ioctl_args *));
63 static int      spec_open __P((struct vop_open_args *));
64 static int      spec_poll __P((struct vop_poll_args *));
65 static int      spec_print __P((struct vop_print_args *));
66 static int      spec_read __P((struct vop_read_args *));  
67 static int      spec_strategy __P((struct vop_strategy_args *));
68 static int      spec_write __P((struct vop_write_args *));
69
70 vop_t **spec_vnodeop_p;
71 static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
72         { &vop_default_desc,            (vop_t *) vop_defaultop },
73         { &vop_access_desc,             (vop_t *) vop_ebadf },
74         { &vop_advlock_desc,            (vop_t *) spec_advlock },
75         { &vop_bmap_desc,               (vop_t *) spec_bmap },
76         { &vop_close_desc,              (vop_t *) spec_close },
77         { &vop_create_desc,             (vop_t *) vop_panic },
78         { &vop_freeblks_desc,           (vop_t *) spec_freeblks },
79         { &vop_fsync_desc,              (vop_t *) spec_fsync },
80         { &vop_getpages_desc,           (vop_t *) spec_getpages },
81         { &vop_inactive_desc,           (vop_t *) spec_inactive },
82         { &vop_ioctl_desc,              (vop_t *) spec_ioctl },
83         { &vop_lease_desc,              (vop_t *) vop_null },
84         { &vop_link_desc,               (vop_t *) vop_panic },
85         { &vop_mkdir_desc,              (vop_t *) vop_panic },
86         { &vop_mknod_desc,              (vop_t *) vop_panic },
87         { &vop_open_desc,               (vop_t *) spec_open },
88         { &vop_pathconf_desc,           (vop_t *) vop_stdpathconf },
89         { &vop_poll_desc,               (vop_t *) spec_poll },
90         { &vop_print_desc,              (vop_t *) spec_print },
91         { &vop_read_desc,               (vop_t *) spec_read },
92         { &vop_readdir_desc,            (vop_t *) vop_panic },
93         { &vop_readlink_desc,           (vop_t *) vop_panic },
94         { &vop_reallocblks_desc,        (vop_t *) vop_panic },
95         { &vop_reclaim_desc,            (vop_t *) vop_null },
96         { &vop_remove_desc,             (vop_t *) vop_panic },
97         { &vop_rename_desc,             (vop_t *) vop_panic },
98         { &vop_rmdir_desc,              (vop_t *) vop_panic },
99         { &vop_setattr_desc,            (vop_t *) vop_ebadf },
100         { &vop_strategy_desc,           (vop_t *) spec_strategy },
101         { &vop_symlink_desc,            (vop_t *) vop_panic },
102         { &vop_write_desc,              (vop_t *) spec_write },
103         { NULL, NULL }
104 };
105 static struct vnodeopv_desc spec_vnodeop_opv_desc =
106         { &spec_vnodeop_p, spec_vnodeop_entries };
107
108 VNODEOP_SET(spec_vnodeop_opv_desc);
109
110 int
111 spec_vnoperate(ap)
112         struct vop_generic_args /* {
113                 struct vnodeop_desc *a_desc;
114                 <other random data follows, presumably>
115         } */ *ap;
116 {
117         return (VOCALL(spec_vnodeop_p, ap->a_desc->vdesc_offset, ap));
118 }
119
120 static void spec_getpages_iodone __P((struct buf *bp));
121
122 /*
123  * Open a special file.
124  */
125 /* ARGSUSED */
126 static int
127 spec_open(ap)
128         struct vop_open_args /* {
129                 struct vnode *a_vp;
130                 int  a_mode;
131                 struct ucred *a_cred;
132                 struct proc *a_p;
133         } */ *ap;
134 {
135         struct proc *p = ap->a_p;
136         struct vnode *vp = ap->a_vp;
137         dev_t dev = vp->v_rdev;
138         int error;
139         struct cdevsw *dsw;
140         const char *cp;
141
142         /*
143          * Don't allow open if fs is mounted -nodev.
144          */
145         if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV))
146                 return (ENXIO);
147
148         dsw = devsw(dev);
149         if ( (dsw == NULL) || (dsw->d_open == NULL))
150                 return ENXIO;
151
152         /* Make this field valid before any I/O in ->d_open */
153         if (!dev->si_iosize_max)
154                 dev->si_iosize_max = DFLTPHYS;
155
156         /*
157          * XXX: Disks get special billing here, but it is mostly wrong.
158          * XXX: diskpartitions can overlap and the real checks should
159          * XXX: take this into account, and consequently they need to
160          * XXX: live in the diskslicing code.  Some checks do.
161          */
162         if (vn_isdisk(vp) && ap->a_cred != FSCRED && (ap->a_mode & FWRITE)) {
163                 /*
164                  * Never allow opens for write if the device is mounted R/W
165                  */
166                 if (vp->v_specmountpoint != NULL &&
167                     !(vp->v_specmountpoint->mnt_flag & MNT_RDONLY))
168                                 return (EBUSY);
169
170                 /*
171                  * When running in secure mode, do not allow opens
172                  * for writing if the device is mounted
173                  */
174                 if (securelevel >= 1 && vp->v_specmountpoint != NULL)
175                         return (EPERM);
176
177                 /*
178                  * When running in very secure mode, do not allow
179                  * opens for writing of any devices.
180                  */
181                 if (securelevel >= 2)
182                         return (EPERM);
183         }
184
185         /* XXX: Special casing of ttys for deadfs.  Probably redundant */
186         if (dsw->d_flags & D_TTY)
187                 vp->v_flag |= VISTTY;
188
189         VOP_UNLOCK(vp, 0, p);
190         error = (*dsw->d_open)(dev, ap->a_mode, S_IFCHR, p);
191         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
192
193         if (error)
194                 return (error);
195
196         if (dsw->d_flags & D_TTY) {
197                 if (dev->si_tty) {
198                         struct tty *tp;
199                         tp = dev->si_tty;
200                         if (!tp->t_stop) {
201                                 printf("Warning:%s: no t_stop, using nottystop\n", devtoname(dev));
202                                 tp->t_stop = nottystop;
203                         }
204                 }
205         }
206
207         if (vn_isdisk(vp)) {
208                 if (!dev->si_bsize_phys)
209                         dev->si_bsize_phys = DEV_BSIZE;
210         }
211         if ((dsw->d_flags & D_DISK) == 0) {
212                 cp = devtoname(dev);
213                 if (*cp == '#' && (dsw->d_flags & D_NAGGED) == 0) {
214                         printf("WARNING: driver %s should register devices with make_dev() (dev_t = \"%s\")\n",
215                             dsw->d_name, cp);
216                         dsw->d_flags |= D_NAGGED;       
217                 }
218         }
219         return (error);
220 }
221
222 /*
223  * Vnode op for read
224  */
225 /* ARGSUSED */
226 static int
227 spec_read(ap)
228         struct vop_read_args /* {
229                 struct vnode *a_vp;
230                 struct uio *a_uio;
231                 int a_ioflag;
232                 struct ucred *a_cred;
233         } */ *ap;
234 {
235         struct vnode *vp;
236         struct proc *p;
237         struct uio *uio;
238         dev_t dev;
239         int error;
240
241         vp = ap->a_vp;
242         dev = vp->v_rdev;
243         uio = ap->a_uio;
244         p = uio->uio_procp;
245
246         if (uio->uio_resid == 0)
247                 return (0);
248
249         VOP_UNLOCK(vp, 0, p);
250         error = (*devsw(dev)->d_read) (dev, uio, ap->a_ioflag);
251         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
252         return (error);
253 }
254
255 /*
256  * Vnode op for write
257  */
258 /* ARGSUSED */
259 static int
260 spec_write(ap)
261         struct vop_write_args /* {
262                 struct vnode *a_vp;
263                 struct uio *a_uio;
264                 int a_ioflag;
265                 struct ucred *a_cred;
266         } */ *ap;
267 {
268         struct vnode *vp;
269         struct proc *p;
270         struct uio *uio;
271         dev_t dev;
272         int error;
273
274         vp = ap->a_vp;
275         dev = vp->v_rdev;
276         uio = ap->a_uio;
277         p = uio->uio_procp;
278
279         VOP_UNLOCK(vp, 0, p);
280         error = (*devsw(dev)->d_write) (dev, uio, ap->a_ioflag);
281         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
282         return (error);
283 }
284
285 /*
286  * Device ioctl operation.
287  */
288 /* ARGSUSED */
289 static int
290 spec_ioctl(ap)
291         struct vop_ioctl_args /* {
292                 struct vnode *a_vp;
293                 int  a_command;
294                 caddr_t  a_data;
295                 int  a_fflag;
296                 struct ucred *a_cred;
297                 struct proc *a_p;
298         } */ *ap;
299 {
300         dev_t dev;
301
302         dev = ap->a_vp->v_rdev;
303         return ((*devsw(dev)->d_ioctl)(dev, ap->a_command, 
304             ap->a_data, ap->a_fflag, ap->a_p));
305 }
306
307 /* ARGSUSED */
308 static int
309 spec_poll(ap)
310         struct vop_poll_args /* {
311                 struct vnode *a_vp;
312                 int  a_events;
313                 struct ucred *a_cred;
314                 struct proc *a_p;
315         } */ *ap;
316 {
317         dev_t dev;
318
319         dev = ap->a_vp->v_rdev;
320         return (*devsw(dev)->d_poll)(dev, ap->a_events, ap->a_p);
321 }
322 /*
323  * Synch buffers associated with a block device
324  */
325 /* ARGSUSED */
326 static int
327 spec_fsync(ap)
328         struct vop_fsync_args /* {
329                 struct vnode *a_vp;
330                 struct ucred *a_cred;
331                 int  a_waitfor;
332                 struct proc *a_p;
333         } */ *ap;
334 {
335         struct vnode *vp = ap->a_vp;
336         struct buf *bp;
337         struct buf *nbp;
338         int s;
339
340         if (!vn_isdisk(vp))
341                 return (0);
342
343         /*
344          * Flush all dirty buffers associated with a block device.
345          */
346 loop:
347         s = splbio();
348         for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
349                 nbp = TAILQ_NEXT(bp, b_vnbufs);
350                 if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
351                         continue;
352                 if ((bp->b_flags & B_DELWRI) == 0)
353                         panic("spec_fsync: not dirty");
354                 if ((vp->v_flag & VOBJBUF) && (bp->b_flags & B_CLUSTEROK)) {
355                         BUF_UNLOCK(bp);
356                         vfs_bio_awrite(bp);
357                         splx(s);
358                 } else {
359                         bremfree(bp);
360                         splx(s);
361                         bawrite(bp);
362                 }
363                 goto loop;
364         }
365         if (ap->a_waitfor == MNT_WAIT) {
366                 while (vp->v_numoutput) {
367                         vp->v_flag |= VBWAIT;
368                         (void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "spfsyn", 0);
369                 }
370 #ifdef DIAGNOSTIC
371                 if (!TAILQ_EMPTY(&vp->v_dirtyblkhd)) {
372                         vprint("spec_fsync: dirty", vp);
373                         splx(s);
374                         goto loop;
375                 }
376 #endif
377         }
378         splx(s);
379         return (0);
380 }
381
382 static int
383 spec_inactive(ap)
384         struct vop_inactive_args /* {
385                 struct vnode *a_vp;
386                 struct proc *a_p;
387         } */ *ap;
388 {
389
390         VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
391         return (0);
392 }
393
394 /*
395  * Just call the device strategy routine
396  */
397 static int
398 spec_strategy(ap)
399         struct vop_strategy_args /* {
400                 struct vnode *a_vp;
401                 struct buf *a_bp;
402         } */ *ap;
403 {
404         struct buf *bp;
405         struct vnode *vp;
406         struct mount *mp;
407
408         bp = ap->a_bp;
409         if (((bp->b_flags & B_READ) == 0) &&
410                 (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start)
411                 (*bioops.io_start)(bp);
412
413         /*
414          * Collect statistics on synchronous and asynchronous read
415          * and write counts for disks that have associated filesystems.
416          */
417         vp = ap->a_vp;
418         if (vn_isdisk(vp) && (mp = vp->v_specmountpoint) != NULL) {
419                 if ((bp->b_flags & B_READ) == 0) {
420                         if (bp->b_lock.lk_lockholder == LK_KERNPROC)
421                                 mp->mnt_stat.f_asyncwrites++;
422                         else
423                                 mp->mnt_stat.f_syncwrites++;
424                 } else {
425                         if (bp->b_lock.lk_lockholder == LK_KERNPROC)
426                                 mp->mnt_stat.f_asyncreads++;
427                         else
428                                 mp->mnt_stat.f_syncreads++;
429                 }
430         }
431         KASSERT(devsw(bp->b_dev) != NULL, 
432            ("No devsw on dev %s responsible for buffer %p\n", 
433            devtoname(bp->b_dev), bp));
434         KASSERT(devsw(bp->b_dev)->d_strategy != NULL, 
435            ("No strategy on dev %s responsible for buffer %p\n", 
436            devtoname(bp->b_dev), bp));
437         BUF_STRATEGY(bp, 0);
438         return (0);
439 }
440
441 static int
442 spec_freeblks(ap)
443         struct vop_freeblks_args /* {
444                 struct vnode *a_vp;
445                 daddr_t a_addr;
446                 daddr_t a_length;
447         } */ *ap;
448 {
449         struct cdevsw *bsw;
450         struct buf *bp;
451
452         /*
453          * XXX: This assumes that strategy does the deed right away.
454          * XXX: this may not be TRTTD.
455          */
456         bsw = devsw(ap->a_vp->v_rdev);
457         if ((bsw->d_flags & D_CANFREE) == 0)
458                 return (0);
459         bp = geteblk(ap->a_length);
460         bp->b_flags |= B_FREEBUF;
461         bp->b_dev = ap->a_vp->v_rdev;
462         bp->b_blkno = ap->a_addr;
463         bp->b_offset = dbtob(ap->a_addr);
464         bp->b_bcount = ap->a_length;
465         BUF_STRATEGY(bp, 0);
466         return (0);
467 }
468
469 /*
470  * Implement degenerate case where the block requested is the block
471  * returned, and assume that the entire device is contiguous in regards
472  * to the contiguous block range (runp and runb).
473  */
474 static int
475 spec_bmap(ap)
476         struct vop_bmap_args /* {
477                 struct vnode *a_vp;
478                 daddr_t  a_bn;
479                 struct vnode **a_vpp;
480                 daddr_t *a_bnp;
481                 int *a_runp;
482                 int *a_runb;
483         } */ *ap;
484 {
485         struct vnode *vp = ap->a_vp;
486         int runp = 0;
487         int runb = 0;
488
489         if (ap->a_vpp != NULL)
490                 *ap->a_vpp = vp;
491         if (ap->a_bnp != NULL)
492                 *ap->a_bnp = ap->a_bn;
493         if (vp->v_mount != NULL)
494                 runp = runb = MAXBSIZE / vp->v_mount->mnt_stat.f_iosize;
495         if (ap->a_runp != NULL)
496                 *ap->a_runp = runp;
497         if (ap->a_runb != NULL)
498                 *ap->a_runb = runb;
499         return (0);
500 }
501
502 /*
503  * Device close routine
504  */
505 /* ARGSUSED */
506 static int
507 spec_close(ap)
508         struct vop_close_args /* {
509                 struct vnode *a_vp;
510                 int  a_fflag;
511                 struct ucred *a_cred;
512                 struct proc *a_p;
513         } */ *ap;
514 {
515         struct vnode *vp = ap->a_vp;
516         struct proc *p = ap->a_p;
517         dev_t dev = vp->v_rdev;
518
519         /*
520          * Hack: a tty device that is a controlling terminal
521          * has a reference from the session structure.
522          * We cannot easily tell that a character device is
523          * a controlling terminal, unless it is the closing
524          * process' controlling terminal.  In that case,
525          * if the reference count is 2 (this last descriptor
526          * plus the session), release the reference from the session.
527          */
528         if (vcount(vp) == 2 && p && (vp->v_flag & VXLOCK) == 0 &&
529             vp == p->p_session->s_ttyvp) {
530                 vrele(vp);
531                 p->p_session->s_ttyvp = NULL;
532         }
533         /*
534          * We do not want to really close the device if it
535          * is still in use unless we are trying to close it
536          * forcibly. Since every use (buffer, vnode, swap, cmap)
537          * holds a reference to the vnode, and because we mark
538          * any other vnodes that alias this device, when the
539          * sum of the reference counts on all the aliased
540          * vnodes descends to one, we are on last close.
541          */
542         if (vp->v_flag & VXLOCK) {
543                 /* Forced close */
544         } else if (devsw(dev)->d_flags & D_TRACKCLOSE) {
545                 /* Keep device updated on status */
546         } else if (vcount(vp) > 1) {
547                 return (0);
548         }
549         return (devsw(dev)->d_close(dev, ap->a_fflag, S_IFCHR, p));
550 }
551
552 /*
553  * Print out the contents of a special device vnode.
554  */
555 static int
556 spec_print(ap)
557         struct vop_print_args /* {
558                 struct vnode *a_vp;
559         } */ *ap;
560 {
561
562         printf("tag VT_NON, dev %s\n", devtoname(ap->a_vp->v_rdev));
563         return (0);
564 }
565
566 /*
567  * Special device advisory byte-level locks.
568  */
569 /* ARGSUSED */
570 static int
571 spec_advlock(ap)
572         struct vop_advlock_args /* {
573                 struct vnode *a_vp;
574                 caddr_t  a_id;
575                 int  a_op;
576                 struct flock *a_fl;
577                 int  a_flags;
578         } */ *ap;
579 {
580
581         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
582 }
583
584 static void
585 spec_getpages_iodone(bp)
586         struct buf *bp;
587 {
588
589         bp->b_flags |= B_DONE;
590         wakeup(bp);
591 }
592
593 static int
594 spec_getpages(ap)
595         struct vop_getpages_args *ap;
596 {
597         vm_offset_t kva;
598         int error;
599         int i, pcount, size, s;
600         daddr_t blkno;
601         struct buf *bp;
602         vm_page_t m;
603         vm_ooffset_t offset;
604         int toff, nextoff, nread;
605         struct vnode *vp = ap->a_vp;
606         int blksiz;
607         int gotreqpage;
608
609         error = 0;
610         pcount = round_page(ap->a_count) / PAGE_SIZE;
611
612         /*
613          * Calculate the offset of the transfer and do sanity check.
614          * FreeBSD currently only supports an 8 TB range due to b_blkno
615          * being in DEV_BSIZE ( usually 512 ) byte chunks on call to
616          * VOP_STRATEGY.  XXX
617          */
618         offset = IDX_TO_OFF(ap->a_m[0]->pindex) + ap->a_offset;
619
620 #define DADDR_T_BIT     (sizeof(daddr_t)*8)
621 #define OFFSET_MAX      ((1LL << (DADDR_T_BIT + DEV_BSHIFT)) - 1)
622
623         if (offset < 0 || offset > OFFSET_MAX) {
624                 /* XXX still no %q in kernel. */
625                 printf("spec_getpages: preposterous offset 0x%x%08x\n",
626                        (u_int)((u_quad_t)offset >> 32),
627                        (u_int)(offset & 0xffffffff));
628                 return (VM_PAGER_ERROR);
629         }
630
631         blkno = btodb(offset);
632
633         /*
634          * Round up physical size for real devices.  We cannot round using
635          * v_mount's block size data because v_mount has nothing to do with
636          * the device.  i.e. it's usually '/dev'.  We need the physical block
637          * size for the device itself.
638          *
639          * We can't use v_specmountpoint because it only exists when the
640          * block device is mounted.  However, we can use v_rdev.
641          */
642
643         if (vn_isdisk(vp))
644                 blksiz = vp->v_rdev->si_bsize_phys;
645         else
646                 blksiz = DEV_BSIZE;
647
648         size = (ap->a_count + blksiz - 1) & ~(blksiz - 1);
649
650         bp = getpbuf(NULL);
651         kva = (vm_offset_t)bp->b_data;
652
653         /*
654          * Map the pages to be read into the kva.
655          */
656         pmap_qenter(kva, ap->a_m, pcount);
657
658         /* Build a minimal buffer header. */
659         bp->b_flags = B_READ | B_CALL;
660         bp->b_iodone = spec_getpages_iodone;
661
662         /* B_PHYS is not set, but it is nice to fill this in. */
663         bp->b_rcred = bp->b_wcred = curproc->p_ucred;
664         if (bp->b_rcred != NOCRED)
665                 crhold(bp->b_rcred);
666         if (bp->b_wcred != NOCRED)
667                 crhold(bp->b_wcred);
668         bp->b_blkno = blkno;
669         bp->b_lblkno = blkno;
670         pbgetvp(ap->a_vp, bp);
671         bp->b_bcount = size;
672         bp->b_bufsize = size;
673         bp->b_resid = 0;
674
675         cnt.v_vnodein++;
676         cnt.v_vnodepgsin += pcount;
677
678         /* Do the input. */
679         VOP_STRATEGY(bp->b_vp, bp);
680
681         s = splbio();
682
683         /* We definitely need to be at splbio here. */
684         while ((bp->b_flags & B_DONE) == 0)
685                 tsleep(bp, PVM, "spread", 0);
686
687         splx(s);
688
689         if ((bp->b_flags & B_ERROR) != 0) {
690                 if (bp->b_error)
691                         error = bp->b_error;
692                 else
693                         error = EIO;
694         }
695
696         nread = size - bp->b_resid;
697
698         if (nread < ap->a_count) {
699                 bzero((caddr_t)kva + nread,
700                         ap->a_count - nread);
701         }
702         pmap_qremove(kva, pcount);
703
704
705         gotreqpage = 0;
706         for (i = 0, toff = 0; i < pcount; i++, toff = nextoff) {
707                 nextoff = toff + PAGE_SIZE;
708                 m = ap->a_m[i];
709
710                 m->flags &= ~PG_ZERO;
711
712                 if (nextoff <= nread) {
713                         m->valid = VM_PAGE_BITS_ALL;
714                         vm_page_undirty(m);
715                 } else if (toff < nread) {
716                         /*
717                          * Since this is a VM request, we have to supply the
718                          * unaligned offset to allow vm_page_set_validclean()
719                          * to zero sub-DEV_BSIZE'd portions of the page.
720                          */
721                         vm_page_set_validclean(m, 0, nread - toff);
722                 } else {
723                         m->valid = 0;
724                         vm_page_undirty(m);
725                 }
726
727                 if (i != ap->a_reqpage) {
728                         /*
729                          * Just in case someone was asking for this page we
730                          * now tell them that it is ok to use.
731                          */
732                         if (!error || (m->valid == VM_PAGE_BITS_ALL)) {
733                                 if (m->valid) {
734                                         if (m->flags & PG_WANTED) {
735                                                 vm_page_activate(m);
736                                         } else {
737                                                 vm_page_deactivate(m);
738                                         }
739                                         vm_page_wakeup(m);
740                                 } else {
741                                         vm_page_free(m);
742                                 }
743                         } else {
744                                 vm_page_free(m);
745                         }
746                 } else if (m->valid) {
747                         gotreqpage = 1;
748                         /*
749                          * Since this is a VM request, we need to make the
750                          * entire page presentable by zeroing invalid sections.
751                          */
752                         if (m->valid != VM_PAGE_BITS_ALL)
753                             vm_page_zero_invalid(m, FALSE);
754                 }
755         }
756         if (!gotreqpage) {
757                 m = ap->a_m[ap->a_reqpage];
758 #ifndef MAX_PERF
759                 printf(
760             "spec_getpages:(%s) I/O read failure: (error=%d) bp %p vp %p\n",
761                         devtoname(bp->b_dev), error, bp, bp->b_vp);
762                 printf(
763             "               size: %d, resid: %ld, a_count: %d, valid: 0x%x\n",
764                     size, bp->b_resid, ap->a_count, m->valid);
765                 printf(
766             "               nread: %d, reqpage: %d, pindex: %lu, pcount: %d\n",
767                     nread, ap->a_reqpage, (u_long)m->pindex, pcount);
768 #endif
769                 /*
770                  * Free the buffer header back to the swap buffer pool.
771                  */
772                 relpbuf(bp, NULL);
773                 return VM_PAGER_ERROR;
774         }
775         /*
776          * Free the buffer header back to the swap buffer pool.
777          */
778         relpbuf(bp, NULL);
779         return VM_PAGER_OK;
780 }