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