1 /* $NetBSD: spec_vnops.c,v 1.96 2006/11/04 09:30:00 elad Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)spec_vnops.c 8.15 (Berkeley) 7/14/95 32 */ 33 34 #if defined(_KERNEL_OPT) 35 #include "veriexec.h" 36 #endif 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.96 2006/11/04 09:30:00 elad Exp $"); 40 41 #include <sys/param.h> 42 #include <sys/proc.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/conf.h> 46 #include <sys/buf.h> 47 #include <sys/mount.h> 48 #include <sys/namei.h> 49 #include <sys/vnode.h> 50 #include <sys/stat.h> 51 #include <sys/errno.h> 52 #include <sys/ioctl.h> 53 #include <sys/poll.h> 54 #include <sys/file.h> 55 #include <sys/disklabel.h> 56 #include <sys/lockf.h> 57 #include <sys/tty.h> 58 #include <sys/kauth.h> 59 60 #include <miscfs/genfs/genfs.h> 61 #include <miscfs/specfs/specdev.h> 62 63 #if NVERIEXEC > 0 64 #include <sys/verified_exec.h> 65 #endif /* NVERIEXEC > 0 */ 66 67 /* symbolic sleep message strings for devices */ 68 const char devopn[] = "devopn"; 69 const char devio[] = "devio"; 70 const char devwait[] = "devwait"; 71 const char devin[] = "devin"; 72 const char devout[] = "devout"; 73 const char devioc[] = "devioc"; 74 const char devcls[] = "devcls"; 75 76 struct vnode *speclisth[SPECHSZ]; 77 78 /* 79 * This vnode operations vector is used for two things only: 80 * - special device nodes created from whole cloth by the kernel. 81 * - as a temporary vnodeops replacement for vnodes which were found to 82 * be aliased by callers of checkalias(). 83 * For the ops vector for vnodes built from special devices found in a 84 * filesystem, see (e.g) ffs_specop_entries[] in ffs_vnops.c or the 85 * equivalent for other filesystems. 86 */ 87 88 int (**spec_vnodeop_p)(void *); 89 const struct vnodeopv_entry_desc spec_vnodeop_entries[] = { 90 { &vop_default_desc, vn_default_error }, 91 { &vop_lookup_desc, spec_lookup }, /* lookup */ 92 { &vop_create_desc, spec_create }, /* create */ 93 { &vop_mknod_desc, spec_mknod }, /* mknod */ 94 { &vop_open_desc, spec_open }, /* open */ 95 { &vop_close_desc, spec_close }, /* close */ 96 { &vop_access_desc, spec_access }, /* access */ 97 { &vop_getattr_desc, spec_getattr }, /* getattr */ 98 { &vop_setattr_desc, spec_setattr }, /* setattr */ 99 { &vop_read_desc, spec_read }, /* read */ 100 { &vop_write_desc, spec_write }, /* write */ 101 { &vop_lease_desc, spec_lease_check }, /* lease */ 102 { &vop_fcntl_desc, spec_fcntl }, /* fcntl */ 103 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 104 { &vop_poll_desc, spec_poll }, /* poll */ 105 { &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */ 106 { &vop_revoke_desc, spec_revoke }, /* revoke */ 107 { &vop_mmap_desc, spec_mmap }, /* mmap */ 108 { &vop_fsync_desc, spec_fsync }, /* fsync */ 109 { &vop_seek_desc, spec_seek }, /* seek */ 110 { &vop_remove_desc, spec_remove }, /* remove */ 111 { &vop_link_desc, spec_link }, /* link */ 112 { &vop_rename_desc, spec_rename }, /* rename */ 113 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 114 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 115 { &vop_symlink_desc, spec_symlink }, /* symlink */ 116 { &vop_readdir_desc, spec_readdir }, /* readdir */ 117 { &vop_readlink_desc, spec_readlink }, /* readlink */ 118 { &vop_abortop_desc, spec_abortop }, /* abortop */ 119 { &vop_inactive_desc, spec_inactive }, /* inactive */ 120 { &vop_reclaim_desc, spec_reclaim }, /* reclaim */ 121 { &vop_lock_desc, spec_lock }, /* lock */ 122 { &vop_unlock_desc, spec_unlock }, /* unlock */ 123 { &vop_bmap_desc, spec_bmap }, /* bmap */ 124 { &vop_strategy_desc, spec_strategy }, /* strategy */ 125 { &vop_print_desc, spec_print }, /* print */ 126 { &vop_islocked_desc, spec_islocked }, /* islocked */ 127 { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 128 { &vop_advlock_desc, spec_advlock }, /* advlock */ 129 { &vop_bwrite_desc, spec_bwrite }, /* bwrite */ 130 { &vop_getpages_desc, spec_getpages }, /* getpages */ 131 { &vop_putpages_desc, spec_putpages }, /* putpages */ 132 { NULL, NULL } 133 }; 134 const struct vnodeopv_desc spec_vnodeop_opv_desc = 135 { &spec_vnodeop_p, spec_vnodeop_entries }; 136 137 /* 138 * Trivial lookup routine that always fails. 139 */ 140 int 141 spec_lookup(v) 142 void *v; 143 { 144 struct vop_lookup_args /* { 145 struct vnode *a_dvp; 146 struct vnode **a_vpp; 147 struct componentname *a_cnp; 148 } */ *ap = v; 149 150 *ap->a_vpp = NULL; 151 return (ENOTDIR); 152 } 153 154 /* 155 * Returns true if dev is /dev/mem or /dev/kmem. 156 */ 157 int 158 iskmemdev(dev_t dev) 159 { 160 /* mem_no is emitted by config(8) to generated devsw.c */ 161 extern const int mem_no; 162 163 /* minor 14 is /dev/io on i386 with COMPAT_10 */ 164 return (major(dev) == mem_no && (minor(dev) < 2 || minor(dev) == 14)); 165 } 166 167 /* 168 * Open a special file. 169 */ 170 /* ARGSUSED */ 171 int 172 spec_open(v) 173 void *v; 174 { 175 struct vop_open_args /* { 176 struct vnode *a_vp; 177 int a_mode; 178 kauth_cred_t a_cred; 179 struct lwp *a_l; 180 } */ *ap = v; 181 struct lwp *l = ap->a_l; 182 struct vnode *vp = ap->a_vp; 183 const struct bdevsw *bdev; 184 const struct cdevsw *cdev; 185 dev_t dev = (dev_t)vp->v_rdev; 186 int error; 187 struct partinfo pi; 188 int (*d_ioctl)(dev_t, u_long, caddr_t, int, struct lwp *); 189 enum kauth_device_req req; 190 191 /* 192 * Don't allow open if fs is mounted -nodev. 193 */ 194 if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV)) 195 return (ENXIO); 196 197 #define M2K(m) (((m) & FREAD) && ((m) & FWRITE) ? \ 198 KAUTH_REQ_DEVICE_RAWIO_SPEC_RW : \ 199 (m) & FWRITE ? KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE : \ 200 KAUTH_REQ_DEVICE_RAWIO_SPEC_READ) 201 202 switch (vp->v_type) { 203 204 case VCHR: 205 cdev = cdevsw_lookup(dev); 206 if (cdev == NULL) 207 return (ENXIO); 208 209 req = M2K(ap->a_mode); 210 211 error = kauth_authorize_device_spec(ap->a_cred, req, vp); 212 if (error) 213 return (error); 214 215 #if NVERIEXEC > 0 216 if (ap->a_mode & FWRITE) { 217 if (iskmemdev(dev)) { 218 if (veriexec_strict >= VERIEXEC_IPS) 219 return (EPERM); 220 } else { 221 struct vnode *bvp; 222 dev_t blkdev; 223 224 blkdev = devsw_chr2blk(dev); 225 if (blkdev != NODEV) { 226 bvp = NULL; 227 vfinddev(blkdev, VBLK, &bvp); 228 error = veriexec_rawchk(bvp); 229 if (error) 230 return (error); 231 } 232 } 233 } 234 #endif /* NVERIEXEC > 0 */ 235 236 if (cdev->d_type == D_TTY) 237 vp->v_flag |= VISTTY; 238 VOP_UNLOCK(vp, 0); 239 error = (*cdev->d_open)(dev, ap->a_mode, S_IFCHR, l); 240 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 241 if (cdev->d_type != D_DISK) 242 return error; 243 d_ioctl = cdev->d_ioctl; 244 break; 245 246 case VBLK: 247 bdev = bdevsw_lookup(dev); 248 if (bdev == NULL) 249 return (ENXIO); 250 251 req = M2K(ap->a_mode); 252 253 error = kauth_authorize_device_spec(ap->a_cred, req, vp); 254 if (error) 255 return (error); 256 257 #if NVERIEXEC > 0 258 error = veriexec_rawchk(vp); 259 if (error) 260 return (error); 261 #endif /* NVERIEXEC > 0 */ 262 263 error = (*bdev->d_open)(dev, ap->a_mode, S_IFBLK, l); 264 d_ioctl = bdev->d_ioctl; 265 break; 266 267 case VNON: 268 case VLNK: 269 case VDIR: 270 case VREG: 271 case VBAD: 272 case VFIFO: 273 case VSOCK: 274 default: 275 return 0; 276 } 277 278 #undef M2K 279 280 if (error) 281 return error; 282 if (!(*d_ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&pi, FREAD, curlwp)) 283 vp->v_size = (voff_t)pi.disklab->d_secsize * pi.part->p_size; 284 return 0; 285 } 286 287 /* 288 * Vnode op for read 289 */ 290 /* ARGSUSED */ 291 int 292 spec_read(v) 293 void *v; 294 { 295 struct vop_read_args /* { 296 struct vnode *a_vp; 297 struct uio *a_uio; 298 int a_ioflag; 299 kauth_cred_t a_cred; 300 } */ *ap = v; 301 struct vnode *vp = ap->a_vp; 302 struct uio *uio = ap->a_uio; 303 struct lwp *l = curlwp; 304 struct buf *bp; 305 const struct bdevsw *bdev; 306 const struct cdevsw *cdev; 307 daddr_t bn; 308 int bsize, bscale; 309 struct partinfo dpart; 310 int n, on; 311 int error = 0; 312 313 #ifdef DIAGNOSTIC 314 if (uio->uio_rw != UIO_READ) 315 panic("spec_read mode"); 316 if (&uio->uio_vmspace->vm_map != kernel_map && 317 uio->uio_vmspace != curproc->p_vmspace) 318 panic("spec_read proc"); 319 #endif 320 if (uio->uio_resid == 0) 321 return (0); 322 323 switch (vp->v_type) { 324 325 case VCHR: 326 VOP_UNLOCK(vp, 0); 327 cdev = cdevsw_lookup(vp->v_rdev); 328 if (cdev != NULL) 329 error = (*cdev->d_read)(vp->v_rdev, uio, ap->a_ioflag); 330 else 331 error = ENXIO; 332 vn_lock(vp, LK_SHARED | LK_RETRY); 333 return (error); 334 335 case VBLK: 336 if (uio->uio_offset < 0) 337 return (EINVAL); 338 bsize = BLKDEV_IOSIZE; 339 bdev = bdevsw_lookup(vp->v_rdev); 340 if (bdev != NULL && 341 (*bdev->d_ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, 342 FREAD, l) == 0) { 343 if (dpart.part->p_fstype == FS_BSDFFS && 344 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 345 bsize = dpart.part->p_frag * 346 dpart.part->p_fsize; 347 } 348 bscale = bsize >> DEV_BSHIFT; 349 do { 350 bn = (uio->uio_offset >> DEV_BSHIFT) &~ (bscale - 1); 351 on = uio->uio_offset % bsize; 352 n = min((unsigned)(bsize - on), uio->uio_resid); 353 error = bread(vp, bn, bsize, NOCRED, &bp); 354 n = min(n, bsize - bp->b_resid); 355 if (error) { 356 brelse(bp); 357 return (error); 358 } 359 error = uiomove((char *)bp->b_data + on, n, uio); 360 brelse(bp); 361 } while (error == 0 && uio->uio_resid > 0 && n != 0); 362 return (error); 363 364 default: 365 panic("spec_read type"); 366 } 367 /* NOTREACHED */ 368 } 369 370 /* 371 * Vnode op for write 372 */ 373 /* ARGSUSED */ 374 int 375 spec_write(v) 376 void *v; 377 { 378 struct vop_write_args /* { 379 struct vnode *a_vp; 380 struct uio *a_uio; 381 int a_ioflag; 382 kauth_cred_t a_cred; 383 } */ *ap = v; 384 struct vnode *vp = ap->a_vp; 385 struct uio *uio = ap->a_uio; 386 struct lwp *l = curlwp; 387 struct buf *bp; 388 const struct bdevsw *bdev; 389 const struct cdevsw *cdev; 390 daddr_t bn; 391 int bsize, bscale; 392 struct partinfo dpart; 393 int n, on; 394 int error = 0; 395 396 #ifdef DIAGNOSTIC 397 if (uio->uio_rw != UIO_WRITE) 398 panic("spec_write mode"); 399 if (&uio->uio_vmspace->vm_map != kernel_map && 400 uio->uio_vmspace != curproc->p_vmspace) 401 panic("spec_write proc"); 402 #endif 403 404 switch (vp->v_type) { 405 406 case VCHR: 407 VOP_UNLOCK(vp, 0); 408 cdev = cdevsw_lookup(vp->v_rdev); 409 if (cdev != NULL) 410 error = (*cdev->d_write)(vp->v_rdev, uio, ap->a_ioflag); 411 else 412 error = ENXIO; 413 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 414 return (error); 415 416 case VBLK: 417 if (uio->uio_resid == 0) 418 return (0); 419 if (uio->uio_offset < 0) 420 return (EINVAL); 421 bsize = BLKDEV_IOSIZE; 422 bdev = bdevsw_lookup(vp->v_rdev); 423 if (bdev != NULL && 424 (*bdev->d_ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, 425 FREAD, l) == 0) { 426 if (dpart.part->p_fstype == FS_BSDFFS && 427 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 428 bsize = dpart.part->p_frag * 429 dpart.part->p_fsize; 430 } 431 bscale = bsize >> DEV_BSHIFT; 432 do { 433 bn = (uio->uio_offset >> DEV_BSHIFT) &~ (bscale - 1); 434 on = uio->uio_offset % bsize; 435 n = min((unsigned)(bsize - on), uio->uio_resid); 436 if (n == bsize) 437 bp = getblk(vp, bn, bsize, 0, 0); 438 else 439 error = bread(vp, bn, bsize, NOCRED, &bp); 440 if (error) { 441 brelse(bp); 442 return (error); 443 } 444 n = min(n, bsize - bp->b_resid); 445 error = uiomove((char *)bp->b_data + on, n, uio); 446 if (error) 447 brelse(bp); 448 else { 449 if (n + on == bsize) 450 bawrite(bp); 451 else 452 bdwrite(bp); 453 if (bp->b_flags & B_ERROR) 454 error = bp->b_error; 455 } 456 } while (error == 0 && uio->uio_resid > 0 && n != 0); 457 return (error); 458 459 default: 460 panic("spec_write type"); 461 } 462 /* NOTREACHED */ 463 } 464 465 /* 466 * Device ioctl operation. 467 */ 468 /* ARGSUSED */ 469 int 470 spec_ioctl(v) 471 void *v; 472 { 473 struct vop_ioctl_args /* { 474 struct vnode *a_vp; 475 u_long a_command; 476 void *a_data; 477 int a_fflag; 478 kauth_cred_t a_cred; 479 struct lwp *a_l; 480 } */ *ap = v; 481 const struct bdevsw *bdev; 482 const struct cdevsw *cdev; 483 struct vnode *vp; 484 dev_t dev; 485 486 /* 487 * Extract all the info we need from the vnode, taking care to 488 * avoid a race with VOP_REVOKE(). 489 */ 490 491 vp = ap->a_vp; 492 dev = NODEV; 493 simple_lock(&vp->v_interlock); 494 if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) { 495 dev = vp->v_rdev; 496 } 497 simple_unlock(&vp->v_interlock); 498 if (dev == NODEV) { 499 return ENXIO; 500 } 501 502 switch (vp->v_type) { 503 504 case VCHR: 505 cdev = cdevsw_lookup(dev); 506 if (cdev == NULL) 507 return (ENXIO); 508 return ((*cdev->d_ioctl)(dev, ap->a_command, ap->a_data, 509 ap->a_fflag, ap->a_l)); 510 511 case VBLK: 512 bdev = bdevsw_lookup(dev); 513 if (bdev == NULL) 514 return (ENXIO); 515 if (ap->a_command == 0 && (long)ap->a_data == B_TAPE) { 516 if (bdev->d_type == D_TAPE) 517 return (0); 518 else 519 return (1); 520 } 521 return ((*bdev->d_ioctl)(dev, ap->a_command, ap->a_data, 522 ap->a_fflag, ap->a_l)); 523 524 default: 525 panic("spec_ioctl"); 526 /* NOTREACHED */ 527 } 528 } 529 530 /* ARGSUSED */ 531 int 532 spec_poll(v) 533 void *v; 534 { 535 struct vop_poll_args /* { 536 struct vnode *a_vp; 537 int a_events; 538 struct lwp *a_l; 539 } */ *ap = v; 540 const struct cdevsw *cdev; 541 struct vnode *vp; 542 dev_t dev; 543 544 /* 545 * Extract all the info we need from the vnode, taking care to 546 * avoid a race with VOP_REVOKE(). 547 */ 548 549 vp = ap->a_vp; 550 dev = NODEV; 551 simple_lock(&vp->v_interlock); 552 if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) { 553 dev = vp->v_rdev; 554 } 555 simple_unlock(&vp->v_interlock); 556 if (dev == NODEV) { 557 return POLLERR; 558 } 559 560 switch (vp->v_type) { 561 562 case VCHR: 563 cdev = cdevsw_lookup(dev); 564 if (cdev == NULL) 565 return (POLLERR); 566 return (*cdev->d_poll)(dev, ap->a_events, ap->a_l); 567 568 default: 569 return (genfs_poll(v)); 570 } 571 } 572 573 /* ARGSUSED */ 574 int 575 spec_kqfilter(v) 576 void *v; 577 { 578 struct vop_kqfilter_args /* { 579 struct vnode *a_vp; 580 struct proc *a_kn; 581 } */ *ap = v; 582 const struct cdevsw *cdev; 583 dev_t dev; 584 585 switch (ap->a_vp->v_type) { 586 587 case VCHR: 588 dev = ap->a_vp->v_rdev; 589 cdev = cdevsw_lookup(dev); 590 if (cdev == NULL) 591 return (ENXIO); 592 return (*cdev->d_kqfilter)(dev, ap->a_kn); 593 default: 594 /* 595 * Block devices don't support kqfilter, and refuse it 596 * for any other files (like those vflush()ed) too. 597 */ 598 return (EOPNOTSUPP); 599 } 600 } 601 602 /* 603 * Synch buffers associated with a block device 604 */ 605 /* ARGSUSED */ 606 int 607 spec_fsync(v) 608 void *v; 609 { 610 struct vop_fsync_args /* { 611 struct vnode *a_vp; 612 kauth_cred_t a_cred; 613 int a_flags; 614 off_t offlo; 615 off_t offhi; 616 struct lwp *a_l; 617 } */ *ap = v; 618 struct vnode *vp = ap->a_vp; 619 620 if (vp->v_type == VBLK) 621 vflushbuf(vp, (ap->a_flags & FSYNC_WAIT) != 0); 622 return (0); 623 } 624 625 /* 626 * Just call the device strategy routine 627 */ 628 int 629 spec_strategy(v) 630 void *v; 631 { 632 struct vop_strategy_args /* { 633 struct vnode *a_vp; 634 struct buf *a_bp; 635 } */ *ap = v; 636 struct vnode *vp = ap->a_vp; 637 struct buf *bp = ap->a_bp; 638 int error, s; 639 struct spec_cow_entry *e; 640 641 error = 0; 642 bp->b_dev = vp->v_rdev; 643 if (!(bp->b_flags & B_READ) && 644 (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start) 645 (*bioops.io_start)(bp); 646 647 if (!(bp->b_flags & B_READ) && !SLIST_EMPTY(&vp->v_spec_cow_head)) { 648 SPEC_COW_LOCK(vp->v_specinfo, s); 649 while (vp->v_spec_cow_req > 0) 650 ltsleep(&vp->v_spec_cow_req, PRIBIO, "cowlist", 0, 651 &vp->v_spec_cow_slock); 652 vp->v_spec_cow_count++; 653 SPEC_COW_UNLOCK(vp->v_specinfo, s); 654 655 SLIST_FOREACH(e, &vp->v_spec_cow_head, ce_list) { 656 if ((error = (*e->ce_func)(e->ce_cookie, bp)) != 0) 657 break; 658 } 659 660 SPEC_COW_LOCK(vp->v_specinfo, s); 661 vp->v_spec_cow_count--; 662 if (vp->v_spec_cow_req && vp->v_spec_cow_count == 0) 663 wakeup(&vp->v_spec_cow_req); 664 SPEC_COW_UNLOCK(vp->v_specinfo, s); 665 } 666 667 if (error) { 668 bp->b_error = error; 669 bp->b_flags |= B_ERROR; 670 biodone(bp); 671 return (error); 672 } 673 674 DEV_STRATEGY(bp); 675 676 return (0); 677 } 678 679 int 680 spec_inactive(v) 681 void *v; 682 { 683 struct vop_inactive_args /* { 684 struct vnode *a_vp; 685 struct proc *a_l; 686 } */ *ap = v; 687 688 VOP_UNLOCK(ap->a_vp, 0); 689 return (0); 690 } 691 692 /* 693 * This is a noop, simply returning what one has been given. 694 */ 695 int 696 spec_bmap(v) 697 void *v; 698 { 699 struct vop_bmap_args /* { 700 struct vnode *a_vp; 701 daddr_t a_bn; 702 struct vnode **a_vpp; 703 daddr_t *a_bnp; 704 int *a_runp; 705 } */ *ap = v; 706 707 if (ap->a_vpp != NULL) 708 *ap->a_vpp = ap->a_vp; 709 if (ap->a_bnp != NULL) 710 *ap->a_bnp = ap->a_bn; 711 if (ap->a_runp != NULL) 712 *ap->a_runp = (MAXBSIZE >> DEV_BSHIFT) - 1; 713 return (0); 714 } 715 716 /* 717 * Device close routine 718 */ 719 /* ARGSUSED */ 720 int 721 spec_close(v) 722 void *v; 723 { 724 struct vop_close_args /* { 725 struct vnode *a_vp; 726 int a_fflag; 727 kauth_cred_t a_cred; 728 struct lwp *a_l; 729 } */ *ap = v; 730 struct vnode *vp = ap->a_vp; 731 const struct bdevsw *bdev; 732 const struct cdevsw *cdev; 733 struct session *sess; 734 dev_t dev = vp->v_rdev; 735 int (*devclose)(dev_t, int, int, struct lwp *); 736 int mode, error, count, flags, flags1; 737 738 count = vcount(vp); 739 flags = vp->v_flag; 740 741 switch (vp->v_type) { 742 743 case VCHR: 744 /* 745 * Hack: a tty device that is a controlling terminal 746 * has a reference from the session structure. 747 * We cannot easily tell that a character device is 748 * a controlling terminal, unless it is the closing 749 * process' controlling terminal. In that case, 750 * if the reference count is 2 (this last descriptor 751 * plus the session), release the reference from the session. 752 * Also remove the link from the tty back to the session 753 * and pgrp - due to the way consoles are handled we cannot 754 * guarantee that the vrele() will do the final close on the 755 * actual tty device. 756 */ 757 if (count == 2 && ap->a_l && 758 vp == (sess = ap->a_l->l_proc->p_session)->s_ttyvp) { 759 sess->s_ttyvp = NULL; 760 if (sess->s_ttyp->t_session != NULL) { 761 sess->s_ttyp->t_pgrp = NULL; 762 sess->s_ttyp->t_session = NULL; 763 SESSRELE(sess); 764 } else if (sess->s_ttyp->t_pgrp != NULL) 765 panic("spec_close: spurious pgrp ref"); 766 vrele(vp); 767 count--; 768 } 769 /* 770 * If the vnode is locked, then we are in the midst 771 * of forcably closing the device, otherwise we only 772 * close on last reference. 773 */ 774 if (count > 1 && (flags & VXLOCK) == 0) 775 return (0); 776 cdev = cdevsw_lookup(dev); 777 if (cdev != NULL) 778 devclose = cdev->d_close; 779 else 780 devclose = NULL; 781 mode = S_IFCHR; 782 break; 783 784 case VBLK: 785 /* 786 * On last close of a block device (that isn't mounted) 787 * we must invalidate any in core blocks, so that 788 * we can, for instance, change floppy disks. 789 */ 790 error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_l, 0, 0); 791 if (error) 792 return (error); 793 /* 794 * We do not want to really close the device if it 795 * is still in use unless we are trying to close it 796 * forcibly. Since every use (buffer, vnode, swap, cmap) 797 * holds a reference to the vnode, and because we mark 798 * any other vnodes that alias this device, when the 799 * sum of the reference counts on all the aliased 800 * vnodes descends to one, we are on last close. 801 */ 802 if (count > 1 && (flags & VXLOCK) == 0) 803 return (0); 804 bdev = bdevsw_lookup(dev); 805 if (bdev != NULL) 806 devclose = bdev->d_close; 807 else 808 devclose = NULL; 809 mode = S_IFBLK; 810 break; 811 812 default: 813 panic("spec_close: not special"); 814 } 815 816 flags1 = ap->a_fflag; 817 818 /* 819 * if VXLOCK is set, then we're going away soon, so make this 820 * non-blocking. Also ensures that we won't wedge in vn_lock below. 821 */ 822 if (flags & VXLOCK) 823 flags1 |= FNONBLOCK; 824 825 /* 826 * If we're able to block, release the vnode lock & reacquire. We 827 * might end up sleeping for someone else who wants our queues. They 828 * won't get them if we hold the vnode locked. Also, if VXLOCK is set, 829 * don't release the lock as we won't be able to regain it. 830 */ 831 if (!(flags1 & FNONBLOCK)) 832 VOP_UNLOCK(vp, 0); 833 834 if (devclose != NULL) 835 error = (*devclose)(dev, flags1, mode, ap->a_l); 836 else 837 error = ENXIO; 838 839 if (!(flags1 & FNONBLOCK)) 840 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 841 842 return (error); 843 } 844 845 /* 846 * Print out the contents of a special device vnode. 847 */ 848 int 849 spec_print(v) 850 void *v; 851 { 852 struct vop_print_args /* { 853 struct vnode *a_vp; 854 } */ *ap = v; 855 856 printf("tag VT_NON, dev %d, %d\n", major(ap->a_vp->v_rdev), 857 minor(ap->a_vp->v_rdev)); 858 return 0; 859 } 860 861 /* 862 * Return POSIX pathconf information applicable to special devices. 863 */ 864 int 865 spec_pathconf(v) 866 void *v; 867 { 868 struct vop_pathconf_args /* { 869 struct vnode *a_vp; 870 int a_name; 871 register_t *a_retval; 872 } */ *ap = v; 873 874 switch (ap->a_name) { 875 case _PC_LINK_MAX: 876 *ap->a_retval = LINK_MAX; 877 return (0); 878 case _PC_MAX_CANON: 879 *ap->a_retval = MAX_CANON; 880 return (0); 881 case _PC_MAX_INPUT: 882 *ap->a_retval = MAX_INPUT; 883 return (0); 884 case _PC_PIPE_BUF: 885 *ap->a_retval = PIPE_BUF; 886 return (0); 887 case _PC_CHOWN_RESTRICTED: 888 *ap->a_retval = 1; 889 return (0); 890 case _PC_VDISABLE: 891 *ap->a_retval = _POSIX_VDISABLE; 892 return (0); 893 case _PC_SYNC_IO: 894 *ap->a_retval = 1; 895 return (0); 896 default: 897 return (EINVAL); 898 } 899 /* NOTREACHED */ 900 } 901 902 /* 903 * Advisory record locking support. 904 */ 905 int 906 spec_advlock(v) 907 void *v; 908 { 909 struct vop_advlock_args /* { 910 struct vnode *a_vp; 911 void *a_id; 912 int a_op; 913 struct flock *a_fl; 914 int a_flags; 915 } */ *ap = v; 916 struct vnode *vp = ap->a_vp; 917 918 return lf_advlock(ap, &vp->v_speclockf, (off_t)0); 919 } 920