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