Remove several layers in the vnode operations vector init code. Declare
[dragonfly.git] / sys / vfs / 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: src/sys/miscfs/specfs/spec_vnops.c,v 1.131.2.4 2001/02/26 04:23:20 jlemon Exp $
35  * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.45 2006/07/18 22:22:16 dillon Exp $
36  */
37
38 #include <sys/param.h>
39 #include <sys/proc.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/conf.h>
43 #include <sys/buf.h>
44 #include <sys/device.h>
45 #include <sys/mount.h>
46 #include <sys/vnode.h>
47 #include <sys/stat.h>
48 #include <sys/fcntl.h>
49 #include <sys/vmmeter.h>
50 #include <sys/tty.h>
51
52 #include <vm/vm.h>
53 #include <vm/vm_object.h>
54 #include <vm/vm_page.h>
55 #include <vm/vm_pager.h>
56
57 #include <machine/limits.h>
58
59 #include <sys/buf2.h>
60
61 #include <sys/thread2.h>
62
63 static int      spec_advlock (struct vop_advlock_args *);  
64 static int      spec_bmap (struct vop_bmap_args *);
65 static int      spec_close (struct vop_close_args *);
66 static int      spec_freeblks (struct vop_freeblks_args *);
67 static int      spec_fsync (struct  vop_fsync_args *);
68 static int      spec_getpages (struct vop_getpages_args *);
69 static int      spec_inactive (struct  vop_inactive_args *);
70 static int      spec_ioctl (struct vop_ioctl_args *);
71 static int      spec_open (struct vop_open_args *);
72 static int      spec_poll (struct vop_poll_args *);
73 static int      spec_kqfilter (struct vop_kqfilter_args *);
74 static int      spec_print (struct vop_print_args *);
75 static int      spec_read (struct vop_read_args *);  
76 static int      spec_strategy (struct vop_strategy_args *);
77 static int      spec_write (struct vop_write_args *);
78
79 struct vop_ops spec_vnode_vops = {
80         .vop_default =          vop_defaultop,
81         .vop_access =           (void *)vop_ebadf,
82         .vop_advlock =          spec_advlock,
83         .vop_bmap =             spec_bmap,
84         .vop_close =            spec_close,
85         .vop_old_create =       (void *)vop_panic,
86         .vop_freeblks =         spec_freeblks,
87         .vop_fsync =            spec_fsync,
88         .vop_getpages =         spec_getpages,
89         .vop_inactive =         spec_inactive,
90         .vop_ioctl =            spec_ioctl,
91         .vop_old_link =         (void *)vop_panic,
92         .vop_old_mkdir =        (void *)vop_panic,
93         .vop_old_mknod =        (void *)vop_panic,
94         .vop_open =             spec_open,
95         .vop_pathconf =         vop_stdpathconf,
96         .vop_poll =             spec_poll,
97         .vop_kqfilter =         spec_kqfilter,
98         .vop_print =            spec_print,
99         .vop_read =             spec_read,
100         .vop_readdir =          (void *)vop_panic,
101         .vop_readlink =         (void *)vop_panic,
102         .vop_reallocblks =      (void *)vop_panic,
103         .vop_reclaim =          (void *)vop_null,
104         .vop_old_remove =       (void *)vop_panic,
105         .vop_old_rename =       (void *)vop_panic,
106         .vop_old_rmdir =        (void *)vop_panic,
107         .vop_setattr =          (void *)vop_ebadf,
108         .vop_strategy =         spec_strategy,
109         .vop_old_symlink =      (void *)vop_panic,
110         .vop_write =            spec_write
111 };
112
113 struct vop_ops *spec_vnode_vops_p = &spec_vnode_vops;
114
115 VNODEOP_SET(spec_vnode_vops);
116
117 extern int dev_ref_debug;
118
119 /*
120  * spec_vnoperate(struct vnodeop_desc *a_desc, ...)
121  */
122 int
123 spec_vnoperate(struct vop_generic_args *ap)
124 {
125         return (VOCALL(&spec_vnode_vops, ap));
126 }
127
128 static void spec_getpages_iodone (struct bio *bio);
129
130 /*
131  * Open a special file.
132  *
133  * spec_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred,
134  *           struct file *a_fp, struct thread *a_td)
135  */
136 /* ARGSUSED */
137 static int
138 spec_open(struct vop_open_args *ap)
139 {
140         struct vnode *vp = ap->a_vp;
141         dev_t dev;
142         int error;
143         int isblk = (vp->v_type == VBLK) ? 1 : 0;
144         const char *cp;
145
146         /*
147          * Don't allow open if fs is mounted -nodev.
148          */
149         if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV))
150                 return (ENXIO);
151
152         /*
153          * Resolve the device.  If the vnode is already open v_rdev may
154          * already be resolved.  However, if the device changes out from
155          * under us we report it (and, for now, we allow it).  Since
156          * v_release_rdev() zero's v_opencount, we have to save and restore
157          * it when replacing the rdev reference.
158          */
159         if (vp->v_rdev != NULL) {
160                 dev = udev2dev(vp->v_udev, isblk);
161                 if (dev != vp->v_rdev) {
162                         int oc = vp->v_opencount;
163                         printf(
164                             "Warning: spec_open: dev %s was lost",
165                             vp->v_rdev->si_name);
166                         v_release_rdev(vp);
167                         error = v_associate_rdev(vp, 
168                                         udev2dev(vp->v_udev, isblk));
169                         if (error) {
170                                 printf(", reacquisition failed\n");
171                         } else {
172                                 vp->v_opencount = oc;
173                                 printf(", reacquisition successful\n");
174                         }
175                 } else {
176                         error = 0;
177                 }
178         } else {
179                 error = v_associate_rdev(vp, udev2dev(vp->v_udev, isblk));
180         }
181         if (error)
182                 return(error);
183
184         /*
185          * Prevent degenerate open/close sequences from nulling out rdev.
186          */
187         dev = vp->v_rdev;
188         KKASSERT(dev != NULL);
189
190         /*
191          * Make this field valid before any I/O in ->d_open.  XXX the
192          * device itself should probably be required to initialize
193          * this field in d_open.
194          */
195         if (!dev->si_iosize_max)
196                 dev->si_iosize_max = DFLTPHYS;
197
198         /*
199          * XXX: Disks get special billing here, but it is mostly wrong.
200          * XXX: diskpartitions can overlap and the real checks should
201          * XXX: take this into account, and consequently they need to
202          * XXX: live in the diskslicing code.  Some checks do.
203          */
204         if (vn_isdisk(vp, NULL) && ap->a_cred != FSCRED && 
205             (ap->a_mode & FWRITE)) {
206                 /*
207                  * Never allow opens for write if the device is mounted R/W
208                  */
209                 if (vp->v_rdev && vp->v_rdev->si_mountpoint &&
210                     !(vp->v_rdev->si_mountpoint->mnt_flag & MNT_RDONLY)) {
211                                 error = EBUSY;
212                                 goto done;
213                 }
214
215                 /*
216                  * When running in secure mode, do not allow opens
217                  * for writing if the device is mounted
218                  */
219                 if (securelevel >= 1 && vfs_mountedon(vp)) {
220                         error = EPERM;
221                         goto done;
222                 }
223
224                 /*
225                  * When running in very secure mode, do not allow
226                  * opens for writing of any devices.
227                  */
228                 if (securelevel >= 2) {
229                         error = EPERM;
230                         goto done;
231                 }
232         }
233
234         /* XXX: Special casing of ttys for deadfs.  Probably redundant */
235         if (dev_dflags(dev) & D_TTY)
236                 vp->v_flag |= VISTTY;
237
238         /*
239          * dev_dopen() is always called for each open.  dev_dclose() is
240          * only called for the last close unless D_TRACKCLOSE is set.
241          */
242         VOP_UNLOCK(vp, 0);
243         error = dev_dopen(dev, ap->a_mode, S_IFCHR, curthread);
244         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
245
246         if (error)
247                 goto done;
248
249         if (dev_dflags(dev) & D_TTY) {
250                 if (dev->si_tty) {
251                         struct tty *tp;
252                         tp = dev->si_tty;
253                         if (!tp->t_stop) {
254                                 printf("Warning:%s: no t_stop, using nottystop\n", devtoname(dev));
255                                 tp->t_stop = nottystop;
256                         }
257                 }
258         }
259
260         /*
261          * If this is 'disk' or disk-like device, associate a VM object
262          * with it.
263          */
264         if (vn_isdisk(vp, NULL)) {
265                 if (!dev->si_bsize_phys)
266                         dev->si_bsize_phys = DEV_BSIZE;
267                 vinitvmio(vp, IDX_TO_OFF(INT_MAX));
268         }
269         if ((dev_dflags(dev) & D_DISK) == 0) {
270                 cp = devtoname(dev);
271                 if (*cp == '#') {
272                         printf("WARNING: driver %s should register devices with make_dev() (dev_t = \"%s\")\n",
273                             dev_dname(dev), cp);
274                 }
275         }
276
277         /*
278          * If we were handed a file pointer we may be able to install a
279          * shortcut which issues device read and write operations directly
280          * from the fileops rather then having to go through spec_read()
281          * and spec_write().
282          */
283         if (ap->a_fp)
284                 vn_setspecops(ap->a_fp);
285
286         if (dev_ref_debug)
287                 printf("spec_open: %s %d\n", dev->si_name, vp->v_opencount);
288 done:
289         if (error) {
290                 if (vp->v_opencount == 0)
291                         v_release_rdev(vp);
292         } else {
293                 vop_stdopen(ap);
294         }
295         return (error);
296 }
297
298 /*
299  * Vnode op for read
300  *
301  * spec_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
302  *           struct ucred *a_cred)
303  */
304 /* ARGSUSED */
305 static int
306 spec_read(struct vop_read_args *ap)
307 {
308         struct vnode *vp;
309         struct thread *td;
310         struct uio *uio;
311         dev_t dev;
312         int error;
313
314         vp = ap->a_vp;
315         dev = vp->v_rdev;
316         uio = ap->a_uio;
317         td = uio->uio_td;
318
319         if (dev == NULL)                /* device was revoked */
320                 return (EBADF);
321         if (uio->uio_resid == 0)
322                 return (0);
323
324         VOP_UNLOCK(vp, 0);
325         error = dev_dread(dev, uio, ap->a_ioflag);
326         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
327         return (error);
328 }
329
330 /*
331  * Vnode op for write
332  *
333  * spec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
334  *            struct ucred *a_cred)
335  */
336 /* ARGSUSED */
337 static int
338 spec_write(struct vop_write_args *ap)
339 {
340         struct vnode *vp;
341         struct thread *td;
342         struct uio *uio;
343         dev_t dev;
344         int error;
345
346         vp = ap->a_vp;
347         dev = vp->v_rdev;
348         uio = ap->a_uio;
349         td = uio->uio_td;
350
351         if (dev == NULL)                /* device was revoked */
352                 return (EBADF);
353
354         VOP_UNLOCK(vp, 0);
355         error = dev_dwrite(dev, uio, ap->a_ioflag);
356         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
357         return (error);
358 }
359
360 /*
361  * Device ioctl operation.
362  *
363  * spec_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data,
364  *            int a_fflag, struct ucred *a_cred, struct thread *a_td)
365  */
366 /* ARGSUSED */
367 static int
368 spec_ioctl(struct vop_ioctl_args *ap)
369 {
370         dev_t dev;
371
372         if ((dev = ap->a_vp->v_rdev) == NULL)
373                 return (EBADF);         /* device was revoked */
374
375         return (dev_dioctl(dev, ap->a_command, ap->a_data,
376                     ap->a_fflag,curthread));
377 }
378
379 /*
380  * spec_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred,
381  *           struct thread *a_td)
382  */
383 /* ARGSUSED */
384 static int
385 spec_poll(struct vop_poll_args *ap)
386 {
387         dev_t dev;
388
389         if ((dev = ap->a_vp->v_rdev) == NULL)
390                 return (EBADF);         /* device was revoked */
391         return (dev_dpoll(dev, ap->a_events, curthread));
392 }
393
394 /*
395  * spec_kqfilter(struct vnode *a_vp, struct knote *a_kn)
396  */
397 /* ARGSUSED */
398 static int
399 spec_kqfilter(struct vop_kqfilter_args *ap)
400 {
401         dev_t dev;
402
403         if ((dev = ap->a_vp->v_rdev) == NULL)
404                 return (EBADF);         /* device was revoked */
405         return (dev_dkqfilter(dev, ap->a_kn));
406 }
407
408 /*
409  * Synch buffers associated with a block device
410  *
411  * spec_fsync(struct vnode *a_vp, struct ucred *a_cred,
412  *            int a_waitfor, struct thread *a_td)
413  */
414 /* ARGSUSED */
415 static int
416 spec_fsync(struct vop_fsync_args *ap)
417 {
418         struct vnode *vp = ap->a_vp;
419         int error;
420
421         if (!vn_isdisk(vp, NULL))
422                 return (0);
423
424         /*
425          * Flush all dirty buffers associated with a block device.
426          */
427         error = vfsync(vp, ap->a_waitfor, 10000, NULL, NULL);
428         return (error);
429 }
430
431 /*
432  * spec_inactive(struct vnode *a_vp, struct thread *a_td)
433  */
434 static int
435 spec_inactive(struct vop_inactive_args *ap)
436 {
437         return (0);
438 }
439
440 /*
441  * Just call the device strategy routine
442  *
443  * spec_strategy(struct vnode *a_vp, struct bio *a_bio)
444  */
445 static int
446 spec_strategy(struct vop_strategy_args *ap)
447 {
448         struct bio *bio = ap->a_bio;
449         struct buf *bp = bio->bio_buf;
450         struct vnode *vp;
451         struct mount *mp;
452
453         if (bp->b_cmd != BUF_CMD_READ &&
454             (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start) {
455                 (*bioops.io_start)(bp);
456         }
457
458         /*
459          * Collect statistics on synchronous and asynchronous read
460          * and write counts for disks that have associated filesystems.
461          */
462         vp = ap->a_vp;
463         KKASSERT(vp->v_rdev != NULL);   /* XXX */
464         if (vn_isdisk(vp, NULL) && (mp = vp->v_rdev->si_mountpoint) != NULL) {
465                 if (bp->b_cmd == BUF_CMD_READ) {
466                         if (bp->b_flags & B_ASYNC)
467                                 mp->mnt_stat.f_asyncreads++;
468                         else
469                                 mp->mnt_stat.f_syncreads++;
470                 } else {
471                         if (bp->b_flags & B_ASYNC)
472                                 mp->mnt_stat.f_asyncwrites++;
473                         else
474                                 mp->mnt_stat.f_syncwrites++;
475                 }
476         }
477         dev_dstrategy_chain(vp->v_rdev, bio);
478         return (0);
479 }
480
481 /*
482  * spec_freeblks(struct vnode *a_vp, daddr_t a_addr, daddr_t a_length)
483  */
484 static int
485 spec_freeblks(struct vop_freeblks_args *ap)
486 {
487         struct buf *bp;
488
489         /*
490          * XXX: This assumes that strategy does the deed right away.
491          * XXX: this may not be TRTTD.
492          */
493         KKASSERT(ap->a_vp->v_rdev != NULL);
494         if ((dev_dflags(ap->a_vp->v_rdev) & D_CANFREE) == 0)
495                 return (0);
496         bp = geteblk(ap->a_length);
497         bp->b_cmd = BUF_CMD_FREEBLKS;
498         bp->b_bio1.bio_offset = ap->a_offset;
499         bp->b_bcount = ap->a_length;
500         dev_dstrategy(ap->a_vp->v_rdev, &bp->b_bio1);
501         return (0);
502 }
503
504 /*
505  * Implement degenerate case where the block requested is the block
506  * returned, and assume that the entire device is contiguous in regards
507  * to the contiguous block range (runp and runb).
508  *
509  * spec_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp,
510  *           off_t *a_doffsetp, int *a_runp, int *a_runb)
511  */
512 static int
513 spec_bmap(struct vop_bmap_args *ap)
514 {
515         struct vnode *vp = ap->a_vp;
516
517         if (ap->a_vpp != NULL)
518                 *ap->a_vpp = vp;
519         if (ap->a_doffsetp != NULL)
520                 *ap->a_doffsetp = ap->a_loffset;
521         if (ap->a_runp != NULL)
522                 *ap->a_runp = MAXBSIZE;
523         if (ap->a_runb != NULL) {
524                 if (ap->a_loffset < MAXBSIZE)
525                         *ap->a_runb = (int)ap->a_loffset;
526                 else
527                         *ap->a_runb = MAXBSIZE;
528         }
529         return (0);
530 }
531
532 /*
533  * Device close routine
534  *
535  * spec_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred,
536  *            struct thread *a_td)
537  *
538  * NOTE: the vnode may or may not be locked on call.
539  */
540 /* ARGSUSED */
541 static int
542 spec_close(struct vop_close_args *ap)
543 {
544         struct proc *p = curproc;
545         struct vnode *vp = ap->a_vp;
546         dev_t dev = vp->v_rdev;
547         int error;
548         int needrelock;
549
550         /*
551          * Hack: a tty device that is a controlling terminal
552          * has a reference from the session structure.
553          * We cannot easily tell that a character device is
554          * a controlling terminal, unless it is the closing
555          * process' controlling terminal.  In that case,
556          * if the reference count is 2 (this last descriptor
557          * plus the session), release the reference from the session.
558          *
559          * It is possible for v_opencount to be 0 or 1 in this case, 0
560          * because the tty might have been revoked.
561          */
562         if (dev)
563                 reference_dev(dev);
564         if (vcount(vp) == 2 && vp->v_opencount <= 1 && 
565             p && vp == p->p_session->s_ttyvp) {
566                 p->p_session->s_ttyvp = NULL;
567                 vrele(vp);
568         }
569
570         /*
571          * Vnodes can be opened and close multiple times.  Do not really
572          * close the device unless (1) it is being closed forcibly,
573          * (2) the device wants to track closes, or (3) this is the last
574          * vnode doing its last close on the device.
575          *
576          * XXX the VXLOCK (force close) case can leave vnodes referencing
577          * a closed device.
578          */
579         if (dev && ((vp->v_flag & VRECLAIMED) ||
580             (dev_dflags(dev) & D_TRACKCLOSE) ||
581             (vcount(vp) <= 1 && vp->v_opencount == 1))) {
582                 needrelock = 0;
583                 if (VOP_ISLOCKED(vp, curthread)) {
584                         needrelock = 1;
585                         VOP_UNLOCK(vp, 0);
586                 }
587                 error = dev_dclose(dev, ap->a_fflag, S_IFCHR, curthread);
588                 if (needrelock)
589                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
590         } else {
591                 error = 0;
592         }
593
594         /*
595          * Track the actual opens and closes on the vnode.  The last close
596          * disassociates the rdev.  If the rdev is already disassociated 
597          * the vnode might have been revoked and no further opencount
598          * tracking occurs.
599          */
600         if (dev) {
601                 /*KKASSERT(vp->v_opencount > 0);*/
602                 if (dev_ref_debug) {
603                         printf("spec_close: %s %d\n",
604                                 dev->si_name, vp->v_opencount - 1);
605                 }
606                 if (vp->v_opencount == 1)
607                         v_release_rdev(vp);
608                 release_dev(dev);
609         }
610         vop_stdclose(ap);
611         return(error);
612 }
613
614 /*
615  * Print out the contents of a special device vnode.
616  *
617  * spec_print(struct vnode *a_vp)
618  */
619 static int
620 spec_print(struct vop_print_args *ap)
621 {
622         printf("tag VT_NON, dev %s\n", devtoname(ap->a_vp->v_rdev));
623         return (0);
624 }
625
626 /*
627  * Special device advisory byte-level locks.
628  *
629  * spec_advlock(struct vnode *a_vp, caddr_t a_id, int a_op,
630  *              struct flock *a_fl, int a_flags)
631  */
632 /* ARGSUSED */
633 static int
634 spec_advlock(struct vop_advlock_args *ap)
635 {
636         return ((ap->a_flags & F_POSIX) ? EINVAL : EOPNOTSUPP);
637 }
638
639 static void
640 spec_getpages_iodone(struct bio *bio)
641 {
642         bio->bio_buf->b_cmd = BUF_CMD_DONE;
643         wakeup(bio->bio_buf);
644 }
645
646 static int
647 spec_getpages(struct vop_getpages_args *ap)
648 {
649         vm_offset_t kva;
650         int error;
651         int i, pcount, size;
652         struct buf *bp;
653         vm_page_t m;
654         vm_ooffset_t offset;
655         int toff, nextoff, nread;
656         struct vnode *vp = ap->a_vp;
657         int blksiz;
658         int gotreqpage;
659
660         error = 0;
661         pcount = round_page(ap->a_count) / PAGE_SIZE;
662
663         /*
664          * Calculate the offset of the transfer and do sanity check.
665          */
666         offset = IDX_TO_OFF(ap->a_m[0]->pindex) + ap->a_offset;
667
668         /*
669          * Round up physical size for real devices.  We cannot round using
670          * v_mount's block size data because v_mount has nothing to do with
671          * the device.  i.e. it's usually '/dev'.  We need the physical block
672          * size for the device itself.
673          *
674          * We can't use v_rdev->si_mountpoint because it only exists when the
675          * block device is mounted.  However, we can use v_rdev.
676          */
677
678         if (vn_isdisk(vp, NULL))
679                 blksiz = vp->v_rdev->si_bsize_phys;
680         else
681                 blksiz = DEV_BSIZE;
682
683         size = (ap->a_count + blksiz - 1) & ~(blksiz - 1);
684
685         bp = getpbuf(NULL);
686         kva = (vm_offset_t)bp->b_data;
687
688         /*
689          * Map the pages to be read into the kva.
690          */
691         pmap_qenter(kva, ap->a_m, pcount);
692
693         /* Build a minimal buffer header. */
694         bp->b_cmd = BUF_CMD_READ;
695         bp->b_bcount = size;
696         bp->b_resid = 0;
697         bp->b_runningbufspace = size;
698         runningbufspace += bp->b_runningbufspace;
699
700         bp->b_bio1.bio_offset = offset;
701         bp->b_bio1.bio_done = spec_getpages_iodone;
702
703         mycpu->gd_cnt.v_vnodein++;
704         mycpu->gd_cnt.v_vnodepgsin += pcount;
705
706         /* Do the input. */
707         vn_strategy(ap->a_vp, &bp->b_bio1);
708
709         crit_enter();
710
711         /* We definitely need to be at splbio here. */
712         while (bp->b_cmd != BUF_CMD_DONE)
713                 tsleep(bp, 0, "spread", 0);
714
715         crit_exit();
716
717         if (bp->b_flags & B_ERROR) {
718                 if (bp->b_error)
719                         error = bp->b_error;
720                 else
721                         error = EIO;
722         }
723
724         /*
725          * If EOF is encountered we must zero-extend the result in order
726          * to ensure that the page does not contain garabge.  When no
727          * error occurs, an early EOF is indicated if b_bcount got truncated.
728          * b_resid is relative to b_bcount and should be 0, but some devices
729          * might indicate an EOF with b_resid instead of truncating b_bcount.
730          */
731         nread = bp->b_bcount - bp->b_resid;
732         if (nread < ap->a_count)
733                 bzero((caddr_t)kva + nread, ap->a_count - nread);
734         pmap_qremove(kva, pcount);
735
736         gotreqpage = 0;
737         for (i = 0, toff = 0; i < pcount; i++, toff = nextoff) {
738                 nextoff = toff + PAGE_SIZE;
739                 m = ap->a_m[i];
740
741                 m->flags &= ~PG_ZERO;
742
743                 if (nextoff <= nread) {
744                         m->valid = VM_PAGE_BITS_ALL;
745                         vm_page_undirty(m);
746                 } else if (toff < nread) {
747                         /*
748                          * Since this is a VM request, we have to supply the
749                          * unaligned offset to allow vm_page_set_validclean()
750                          * to zero sub-DEV_BSIZE'd portions of the page.
751                          */
752                         vm_page_set_validclean(m, 0, nread - toff);
753                 } else {
754                         m->valid = 0;
755                         vm_page_undirty(m);
756                 }
757
758                 if (i != ap->a_reqpage) {
759                         /*
760                          * Just in case someone was asking for this page we
761                          * now tell them that it is ok to use.
762                          */
763                         if (!error || (m->valid == VM_PAGE_BITS_ALL)) {
764                                 if (m->valid) {
765                                         if (m->flags & PG_WANTED) {
766                                                 vm_page_activate(m);
767                                         } else {
768                                                 vm_page_deactivate(m);
769                                         }
770                                         vm_page_wakeup(m);
771                                 } else {
772                                         vm_page_free(m);
773                                 }
774                         } else {
775                                 vm_page_free(m);
776                         }
777                 } else if (m->valid) {
778                         gotreqpage = 1;
779                         /*
780                          * Since this is a VM request, we need to make the
781                          * entire page presentable by zeroing invalid sections.
782                          */
783                         if (m->valid != VM_PAGE_BITS_ALL)
784                             vm_page_zero_invalid(m, FALSE);
785                 }
786         }
787         if (!gotreqpage) {
788                 m = ap->a_m[ap->a_reqpage];
789                 printf(
790             "spec_getpages:(%s) I/O read failure: (error=%d) bp %p vp %p\n",
791                         devtoname(vp->v_rdev), error, bp, bp->b_vp);
792                 printf(
793             "               size: %d, resid: %d, a_count: %d, valid: 0x%x\n",
794                     size, bp->b_resid, ap->a_count, m->valid);
795                 printf(
796             "               nread: %d, reqpage: %d, pindex: %lu, pcount: %d\n",
797                     nread, ap->a_reqpage, (u_long)m->pindex, pcount);
798                 /*
799                  * Free the buffer header back to the swap buffer pool.
800                  */
801                 relpbuf(bp, NULL);
802                 return VM_PAGER_ERROR;
803         }
804         /*
805          * Free the buffer header back to the swap buffer pool.
806          */
807         relpbuf(bp, NULL);
808         return VM_PAGER_OK;
809 }