1 /* $NetBSD: spec_vnops.c,v 1.85 2005/12/11 12:24:51 christos 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.85 2005/12/11 12:24:51 christos 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 = uio->uio_lwp; 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_segflg == UIO_USERSPACE && uio->uio_lwp != curlwp) 295 panic("spec_read proc"); 296 #endif 297 if (uio->uio_resid == 0) 298 return (0); 299 300 switch (vp->v_type) { 301 302 case VCHR: 303 VOP_UNLOCK(vp, 0); 304 cdev = cdevsw_lookup(vp->v_rdev); 305 if (cdev != NULL) 306 error = (*cdev->d_read)(vp->v_rdev, uio, ap->a_ioflag); 307 else 308 error = ENXIO; 309 vn_lock(vp, LK_SHARED | LK_RETRY); 310 return (error); 311 312 case VBLK: 313 if (uio->uio_offset < 0) 314 return (EINVAL); 315 bsize = BLKDEV_IOSIZE; 316 bdev = bdevsw_lookup(vp->v_rdev); 317 if (bdev != NULL && 318 (*bdev->d_ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, 319 FREAD, l) == 0) { 320 if (dpart.part->p_fstype == FS_BSDFFS && 321 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 322 bsize = dpart.part->p_frag * 323 dpart.part->p_fsize; 324 } 325 bscale = bsize >> DEV_BSHIFT; 326 do { 327 bn = (uio->uio_offset >> DEV_BSHIFT) &~ (bscale - 1); 328 on = uio->uio_offset % bsize; 329 n = min((unsigned)(bsize - on), uio->uio_resid); 330 error = bread(vp, bn, bsize, NOCRED, &bp); 331 n = min(n, bsize - bp->b_resid); 332 if (error) { 333 brelse(bp); 334 return (error); 335 } 336 error = uiomove((char *)bp->b_data + on, n, uio); 337 brelse(bp); 338 } while (error == 0 && uio->uio_resid > 0 && n != 0); 339 return (error); 340 341 default: 342 panic("spec_read type"); 343 } 344 /* NOTREACHED */ 345 } 346 347 /* 348 * Vnode op for write 349 */ 350 /* ARGSUSED */ 351 int 352 spec_write(v) 353 void *v; 354 { 355 struct vop_write_args /* { 356 struct vnode *a_vp; 357 struct uio *a_uio; 358 int a_ioflag; 359 struct ucred *a_cred; 360 } */ *ap = v; 361 struct vnode *vp = ap->a_vp; 362 struct uio *uio = ap->a_uio; 363 struct lwp *l = uio->uio_lwp; 364 struct buf *bp; 365 const struct bdevsw *bdev; 366 const struct cdevsw *cdev; 367 daddr_t bn; 368 int bsize, bscale; 369 struct partinfo dpart; 370 int n, on; 371 int error = 0; 372 373 #ifdef DIAGNOSTIC 374 if (uio->uio_rw != UIO_WRITE) 375 panic("spec_write mode"); 376 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_lwp != curlwp) 377 panic("spec_write proc"); 378 #endif 379 380 switch (vp->v_type) { 381 382 case VCHR: 383 VOP_UNLOCK(vp, 0); 384 cdev = cdevsw_lookup(vp->v_rdev); 385 if (cdev != NULL) 386 error = (*cdev->d_write)(vp->v_rdev, uio, ap->a_ioflag); 387 else 388 error = ENXIO; 389 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 390 return (error); 391 392 case VBLK: 393 if (uio->uio_resid == 0) 394 return (0); 395 if (uio->uio_offset < 0) 396 return (EINVAL); 397 bsize = BLKDEV_IOSIZE; 398 bdev = bdevsw_lookup(vp->v_rdev); 399 if (bdev != NULL && 400 (*bdev->d_ioctl)(vp->v_rdev, DIOCGPART, (caddr_t)&dpart, 401 FREAD, l) == 0) { 402 if (dpart.part->p_fstype == FS_BSDFFS && 403 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 404 bsize = dpart.part->p_frag * 405 dpart.part->p_fsize; 406 } 407 bscale = bsize >> DEV_BSHIFT; 408 do { 409 bn = (uio->uio_offset >> DEV_BSHIFT) &~ (bscale - 1); 410 on = uio->uio_offset % bsize; 411 n = min((unsigned)(bsize - on), uio->uio_resid); 412 if (n == bsize) 413 bp = getblk(vp, bn, bsize, 0, 0); 414 else 415 error = bread(vp, bn, bsize, NOCRED, &bp); 416 if (error) { 417 brelse(bp); 418 return (error); 419 } 420 n = min(n, bsize - bp->b_resid); 421 error = uiomove((char *)bp->b_data + on, n, uio); 422 if (error) 423 brelse(bp); 424 else { 425 if (n + on == bsize) 426 bawrite(bp); 427 else 428 bdwrite(bp); 429 if (bp->b_flags & B_ERROR) 430 error = bp->b_error; 431 } 432 } while (error == 0 && uio->uio_resid > 0 && n != 0); 433 return (error); 434 435 default: 436 panic("spec_write type"); 437 } 438 /* NOTREACHED */ 439 } 440 441 /* 442 * Device ioctl operation. 443 */ 444 /* ARGSUSED */ 445 int 446 spec_ioctl(v) 447 void *v; 448 { 449 struct vop_ioctl_args /* { 450 struct vnode *a_vp; 451 u_long a_command; 452 void *a_data; 453 int a_fflag; 454 struct ucred *a_cred; 455 struct lwp *a_l; 456 } */ *ap = v; 457 const struct bdevsw *bdev; 458 const struct cdevsw *cdev; 459 struct vnode *vp; 460 dev_t dev; 461 462 /* 463 * Extract all the info we need from the vnode, taking care to 464 * avoid a race with VOP_REVOKE(). 465 */ 466 467 vp = ap->a_vp; 468 dev = NODEV; 469 simple_lock(&vp->v_interlock); 470 if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) { 471 dev = vp->v_rdev; 472 } 473 simple_unlock(&vp->v_interlock); 474 if (dev == NODEV) { 475 return ENXIO; 476 } 477 478 switch (vp->v_type) { 479 480 case VCHR: 481 cdev = cdevsw_lookup(dev); 482 if (cdev == NULL) 483 return (ENXIO); 484 return ((*cdev->d_ioctl)(dev, ap->a_command, ap->a_data, 485 ap->a_fflag, ap->a_l)); 486 487 case VBLK: 488 bdev = bdevsw_lookup(dev); 489 if (bdev == NULL) 490 return (ENXIO); 491 if (ap->a_command == 0 && (long)ap->a_data == B_TAPE) { 492 if (bdev->d_type == D_TAPE) 493 return (0); 494 else 495 return (1); 496 } 497 return ((*bdev->d_ioctl)(dev, ap->a_command, ap->a_data, 498 ap->a_fflag, ap->a_l)); 499 500 default: 501 panic("spec_ioctl"); 502 /* NOTREACHED */ 503 } 504 } 505 506 /* ARGSUSED */ 507 int 508 spec_poll(v) 509 void *v; 510 { 511 struct vop_poll_args /* { 512 struct vnode *a_vp; 513 int a_events; 514 struct lwp *a_l; 515 } */ *ap = v; 516 const struct cdevsw *cdev; 517 dev_t dev; 518 519 switch (ap->a_vp->v_type) { 520 521 case VCHR: 522 dev = ap->a_vp->v_rdev; 523 cdev = cdevsw_lookup(dev); 524 if (cdev == NULL) 525 return (POLLERR); 526 return (*cdev->d_poll)(dev, ap->a_events, ap->a_l); 527 528 default: 529 return (genfs_poll(v)); 530 } 531 } 532 533 /* ARGSUSED */ 534 int 535 spec_kqfilter(v) 536 void *v; 537 { 538 struct vop_kqfilter_args /* { 539 struct vnode *a_vp; 540 struct proc *a_kn; 541 } */ *ap = v; 542 const struct cdevsw *cdev; 543 dev_t dev; 544 545 switch (ap->a_vp->v_type) { 546 547 case VCHR: 548 dev = ap->a_vp->v_rdev; 549 cdev = cdevsw_lookup(dev); 550 if (cdev == NULL) 551 return (ENXIO); 552 return (*cdev->d_kqfilter)(dev, ap->a_kn); 553 default: 554 /* 555 * Block devices don't support kqfilter, and refuse it 556 * for any other files (like those vflush()ed) too. 557 */ 558 return (EOPNOTSUPP); 559 } 560 } 561 562 /* 563 * Synch buffers associated with a block device 564 */ 565 /* ARGSUSED */ 566 int 567 spec_fsync(v) 568 void *v; 569 { 570 struct vop_fsync_args /* { 571 struct vnode *a_vp; 572 struct ucred *a_cred; 573 int a_flags; 574 off_t offlo; 575 off_t offhi; 576 struct lwp *a_l; 577 } */ *ap = v; 578 struct vnode *vp = ap->a_vp; 579 580 if (vp->v_type == VBLK) 581 vflushbuf(vp, (ap->a_flags & FSYNC_WAIT) != 0); 582 return (0); 583 } 584 585 /* 586 * Just call the device strategy routine 587 */ 588 int 589 spec_strategy(v) 590 void *v; 591 { 592 struct vop_strategy_args /* { 593 struct vnode *a_vp; 594 struct buf *a_bp; 595 } */ *ap = v; 596 struct vnode *vp = ap->a_vp; 597 struct buf *bp = ap->a_bp; 598 int error, s; 599 struct spec_cow_entry *e; 600 601 error = 0; 602 bp->b_dev = vp->v_rdev; 603 if (!(bp->b_flags & B_READ) && 604 (LIST_FIRST(&bp->b_dep)) != NULL && bioops.io_start) 605 (*bioops.io_start)(bp); 606 607 if (!(bp->b_flags & B_READ) && !SLIST_EMPTY(&vp->v_spec_cow_head)) { 608 SPEC_COW_LOCK(vp->v_specinfo, s); 609 while (vp->v_spec_cow_req > 0) 610 ltsleep(&vp->v_spec_cow_req, PRIBIO, "cowlist", 0, 611 &vp->v_spec_cow_slock); 612 vp->v_spec_cow_count++; 613 SPEC_COW_UNLOCK(vp->v_specinfo, s); 614 615 SLIST_FOREACH(e, &vp->v_spec_cow_head, ce_list) { 616 if ((error = (*e->ce_func)(e->ce_cookie, bp)) != 0) 617 break; 618 } 619 620 SPEC_COW_LOCK(vp->v_specinfo, s); 621 vp->v_spec_cow_count--; 622 if (vp->v_spec_cow_req && vp->v_spec_cow_count == 0) 623 wakeup(&vp->v_spec_cow_req); 624 SPEC_COW_UNLOCK(vp->v_specinfo, s); 625 } 626 627 if (error) { 628 bp->b_error = error; 629 bp->b_flags |= B_ERROR; 630 biodone(bp); 631 return (error); 632 } 633 634 DEV_STRATEGY(bp); 635 636 return (0); 637 } 638 639 int 640 spec_inactive(v) 641 void *v; 642 { 643 struct vop_inactive_args /* { 644 struct vnode *a_vp; 645 struct proc *a_l; 646 } */ *ap = v; 647 648 VOP_UNLOCK(ap->a_vp, 0); 649 return (0); 650 } 651 652 /* 653 * This is a noop, simply returning what one has been given. 654 */ 655 int 656 spec_bmap(v) 657 void *v; 658 { 659 struct vop_bmap_args /* { 660 struct vnode *a_vp; 661 daddr_t a_bn; 662 struct vnode **a_vpp; 663 daddr_t *a_bnp; 664 int *a_runp; 665 } */ *ap = v; 666 667 if (ap->a_vpp != NULL) 668 *ap->a_vpp = ap->a_vp; 669 if (ap->a_bnp != NULL) 670 *ap->a_bnp = ap->a_bn; 671 if (ap->a_runp != NULL) 672 *ap->a_runp = (MAXBSIZE >> DEV_BSHIFT) - 1; 673 return (0); 674 } 675 676 /* 677 * Device close routine 678 */ 679 /* ARGSUSED */ 680 int 681 spec_close(v) 682 void *v; 683 { 684 struct vop_close_args /* { 685 struct vnode *a_vp; 686 int a_fflag; 687 struct ucred *a_cred; 688 struct lwp *a_l; 689 } */ *ap = v; 690 struct vnode *vp = ap->a_vp; 691 const struct bdevsw *bdev; 692 const struct cdevsw *cdev; 693 struct session *sess; 694 dev_t dev = vp->v_rdev; 695 int (*devclose)(dev_t, int, int, struct lwp *); 696 int mode, error, count, flags, flags1; 697 698 count = vcount(vp); 699 flags = vp->v_flag; 700 701 switch (vp->v_type) { 702 703 case VCHR: 704 /* 705 * Hack: a tty device that is a controlling terminal 706 * has a reference from the session structure. 707 * We cannot easily tell that a character device is 708 * a controlling terminal, unless it is the closing 709 * process' controlling terminal. In that case, 710 * if the reference count is 2 (this last descriptor 711 * plus the session), release the reference from the session. 712 * Also remove the link from the tty back to the session 713 * and pgrp - due to the way consoles are handled we cannot 714 * guarantee that the vrele() will do the final close on the 715 * actual tty device. 716 */ 717 if (count == 2 && ap->a_l && 718 vp == (sess = ap->a_l->l_proc->p_session)->s_ttyvp) { 719 sess->s_ttyvp = NULL; 720 if (sess->s_ttyp->t_session != NULL) { 721 sess->s_ttyp->t_pgrp = NULL; 722 sess->s_ttyp->t_session = NULL; 723 SESSRELE(sess); 724 } else if (sess->s_ttyp->t_pgrp != NULL) 725 panic("spec_close: spurious pgrp ref"); 726 vrele(vp); 727 count--; 728 } 729 /* 730 * If the vnode is locked, then we are in the midst 731 * of forcably closing the device, otherwise we only 732 * close on last reference. 733 */ 734 if (count > 1 && (flags & VXLOCK) == 0) 735 return (0); 736 cdev = cdevsw_lookup(dev); 737 if (cdev != NULL) 738 devclose = cdev->d_close; 739 else 740 devclose = NULL; 741 mode = S_IFCHR; 742 break; 743 744 case VBLK: 745 /* 746 * On last close of a block device (that isn't mounted) 747 * we must invalidate any in core blocks, so that 748 * we can, for instance, change floppy disks. 749 */ 750 error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_l, 0, 0); 751 if (error) 752 return (error); 753 /* 754 * We do not want to really close the device if it 755 * is still in use unless we are trying to close it 756 * forcibly. Since every use (buffer, vnode, swap, cmap) 757 * holds a reference to the vnode, and because we mark 758 * any other vnodes that alias this device, when the 759 * sum of the reference counts on all the aliased 760 * vnodes descends to one, we are on last close. 761 */ 762 if (count > 1 && (flags & VXLOCK) == 0) 763 return (0); 764 bdev = bdevsw_lookup(dev); 765 if (bdev != NULL) 766 devclose = bdev->d_close; 767 else 768 devclose = NULL; 769 mode = S_IFBLK; 770 break; 771 772 default: 773 panic("spec_close: not special"); 774 } 775 776 flags1 = ap->a_fflag; 777 778 /* 779 * if VXLOCK is set, then we're going away soon, so make this 780 * non-blocking. Also ensures that we won't wedge in vn_lock below. 781 */ 782 if (flags & VXLOCK) 783 flags1 |= FNONBLOCK; 784 785 /* 786 * If we're able to block, release the vnode lock & reacquire. We 787 * might end up sleeping for someone else who wants our queues. They 788 * won't get them if we hold the vnode locked. Also, if VXLOCK is set, 789 * don't release the lock as we won't be able to regain it. 790 */ 791 if (!(flags1 & FNONBLOCK)) 792 VOP_UNLOCK(vp, 0); 793 794 if (devclose != NULL) 795 error = (*devclose)(dev, flags1, mode, ap->a_l); 796 else 797 error = ENXIO; 798 799 if (!(flags1 & FNONBLOCK)) 800 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 801 802 return (error); 803 } 804 805 /* 806 * Print out the contents of a special device vnode. 807 */ 808 int 809 spec_print(v) 810 void *v; 811 { 812 struct vop_print_args /* { 813 struct vnode *a_vp; 814 } */ *ap = v; 815 816 printf("tag VT_NON, dev %d, %d\n", major(ap->a_vp->v_rdev), 817 minor(ap->a_vp->v_rdev)); 818 return 0; 819 } 820 821 /* 822 * Return POSIX pathconf information applicable to special devices. 823 */ 824 int 825 spec_pathconf(v) 826 void *v; 827 { 828 struct vop_pathconf_args /* { 829 struct vnode *a_vp; 830 int a_name; 831 register_t *a_retval; 832 } */ *ap = v; 833 834 switch (ap->a_name) { 835 case _PC_LINK_MAX: 836 *ap->a_retval = LINK_MAX; 837 return (0); 838 case _PC_MAX_CANON: 839 *ap->a_retval = MAX_CANON; 840 return (0); 841 case _PC_MAX_INPUT: 842 *ap->a_retval = MAX_INPUT; 843 return (0); 844 case _PC_PIPE_BUF: 845 *ap->a_retval = PIPE_BUF; 846 return (0); 847 case _PC_CHOWN_RESTRICTED: 848 *ap->a_retval = 1; 849 return (0); 850 case _PC_VDISABLE: 851 *ap->a_retval = _POSIX_VDISABLE; 852 return (0); 853 case _PC_SYNC_IO: 854 *ap->a_retval = 1; 855 return (0); 856 default: 857 return (EINVAL); 858 } 859 /* NOTREACHED */ 860 } 861 862 /* 863 * Advisory record locking support. 864 */ 865 int 866 spec_advlock(v) 867 void *v; 868 { 869 struct vop_advlock_args /* { 870 struct vnode *a_vp; 871 void *a_id; 872 int a_op; 873 struct flock *a_fl; 874 int a_flags; 875 } */ *ap = v; 876 struct vnode *vp = ap->a_vp; 877 878 return lf_advlock(ap, &vp->v_speclockf, (off_t)0); 879 } 880