1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)spec_vnops.c 7.49 (Berkeley) 07/12/92 8 */ 9 10 #include <sys/param.h> 11 #include <sys/proc.h> 12 #include <sys/systm.h> 13 #include <sys/kernel.h> 14 #include <sys/conf.h> 15 #include <sys/buf.h> 16 #include <sys/mount.h> 17 #include <sys/namei.h> 18 #include <sys/vnode.h> 19 #include <sys/stat.h> 20 #include <sys/errno.h> 21 #include <sys/ioctl.h> 22 #include <sys/file.h> 23 #include <sys/disklabel.h> 24 #include <miscfs/specfs/specdev.h> 25 26 /* symbolic sleep message strings for devices */ 27 char devopn[] = "devopn"; 28 char devio[] = "devio"; 29 char devwait[] = "devwait"; 30 char devin[] = "devin"; 31 char devout[] = "devout"; 32 char devioc[] = "devioc"; 33 char devcls[] = "devcls"; 34 35 int (**spec_vnodeop_p)(); 36 struct vnodeopv_entry_desc spec_vnodeop_entries[] = { 37 { &vop_default_desc, vn_default_error }, 38 { &vop_lookup_desc, spec_lookup }, /* lookup */ 39 { &vop_create_desc, spec_create }, /* create */ 40 { &vop_mknod_desc, spec_mknod }, /* mknod */ 41 { &vop_open_desc, spec_open }, /* open */ 42 { &vop_close_desc, spec_close }, /* close */ 43 { &vop_access_desc, spec_access }, /* access */ 44 { &vop_getattr_desc, spec_getattr }, /* getattr */ 45 { &vop_setattr_desc, spec_setattr }, /* setattr */ 46 { &vop_read_desc, spec_read }, /* read */ 47 { &vop_write_desc, spec_write }, /* write */ 48 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 49 { &vop_select_desc, spec_select }, /* select */ 50 { &vop_mmap_desc, spec_mmap }, /* mmap */ 51 { &vop_fsync_desc, spec_fsync }, /* fsync */ 52 { &vop_seek_desc, spec_seek }, /* seek */ 53 { &vop_remove_desc, spec_remove }, /* remove */ 54 { &vop_link_desc, spec_link }, /* link */ 55 { &vop_rename_desc, spec_rename }, /* rename */ 56 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 57 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 58 { &vop_symlink_desc, spec_symlink }, /* symlink */ 59 { &vop_readdir_desc, spec_readdir }, /* readdir */ 60 { &vop_readlink_desc, spec_readlink }, /* readlink */ 61 { &vop_abortop_desc, spec_abortop }, /* abortop */ 62 { &vop_inactive_desc, spec_inactive }, /* inactive */ 63 { &vop_reclaim_desc, spec_reclaim }, /* reclaim */ 64 { &vop_lock_desc, spec_lock }, /* lock */ 65 { &vop_unlock_desc, spec_unlock }, /* unlock */ 66 { &vop_bmap_desc, spec_bmap }, /* bmap */ 67 { &vop_strategy_desc, spec_strategy }, /* strategy */ 68 { &vop_print_desc, spec_print }, /* print */ 69 { &vop_islocked_desc, spec_islocked }, /* islocked */ 70 { &vop_advlock_desc, spec_advlock }, /* advlock */ 71 { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 72 { &vop_valloc_desc, spec_valloc }, /* valloc */ 73 { &vop_vfree_desc, spec_vfree }, /* vfree */ 74 { &vop_truncate_desc, spec_truncate }, /* truncate */ 75 { &vop_update_desc, spec_update }, /* update */ 76 { &vop_bwrite_desc, spec_bwrite }, /* bwrite */ 77 { (struct vnodeop_desc*)NULL, (int(*)())NULL } 78 }; 79 struct vnodeopv_desc spec_vnodeop_opv_desc = 80 { &spec_vnodeop_p, spec_vnodeop_entries }; 81 82 /* 83 * Trivial lookup routine that always fails. 84 */ 85 int 86 spec_lookup(ap) 87 struct vop_lookup_args /* { 88 struct vnode *a_dvp; 89 struct vnode **a_vpp; 90 struct componentname *a_cnp; 91 } */ *ap; 92 { 93 94 *ap->a_vpp = NULL; 95 return (ENOTDIR); 96 } 97 98 /* 99 * Open a special file: Don't allow open if fs is mounted -nodev, 100 * and don't allow opens of block devices that are currently mounted. 101 * Otherwise, call device driver open function. 102 */ 103 /* ARGSUSED */ 104 spec_open(ap) 105 struct vop_open_args /* { 106 struct vnode *a_vp; 107 int a_mode; 108 struct ucred *a_cred; 109 struct proc *a_p; 110 } */ *ap; 111 { 112 register struct vnode *vp = ap->a_vp; 113 dev_t dev = (dev_t)vp->v_rdev; 114 register int maj = major(dev); 115 int error; 116 117 if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV)) 118 return (ENXIO); 119 120 switch (vp->v_type) { 121 122 case VCHR: 123 if ((u_int)maj >= nchrdev) 124 return (ENXIO); 125 VOP_UNLOCK(vp); 126 error = (*cdevsw[maj].d_open)(dev, ap->a_mode, S_IFCHR, ap->a_p); 127 VOP_LOCK(vp); 128 return (error); 129 130 case VBLK: 131 if ((u_int)maj >= nblkdev) 132 return (ENXIO); 133 if (error = ufs_mountedon(vp)) 134 return (error); 135 return ((*bdevsw[maj].d_open)(dev, ap->a_mode, S_IFBLK, ap->a_p)); 136 } 137 return (0); 138 } 139 140 /* 141 * Vnode op for read 142 */ 143 /* ARGSUSED */ 144 spec_read(ap) 145 struct vop_read_args /* { 146 struct vnode *a_vp; 147 struct uio *a_uio; 148 int a_ioflag; 149 struct ucred *a_cred; 150 } */ *ap; 151 { 152 register struct vnode *vp = ap->a_vp; 153 register struct uio *uio = ap->a_uio; 154 struct proc *p = uio->uio_procp; 155 struct buf *bp; 156 daddr_t bn, nextbn; 157 long bsize, bscale; 158 struct partinfo dpart; 159 register int n, on; 160 int error = 0; 161 162 #ifdef DIAGNOSTIC 163 if (uio->uio_rw != UIO_READ) 164 panic("spec_read mode"); 165 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) 166 panic("spec_read proc"); 167 #endif 168 if (uio->uio_resid == 0) 169 return (0); 170 171 switch (vp->v_type) { 172 173 case VCHR: 174 VOP_UNLOCK(vp); 175 error = (*cdevsw[major(vp->v_rdev)].d_read) 176 (vp->v_rdev, uio, ap->a_ioflag); 177 VOP_LOCK(vp); 178 return (error); 179 180 case VBLK: 181 if (uio->uio_offset < 0) 182 return (EINVAL); 183 bsize = BLKDEV_IOSIZE; 184 if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART, 185 (caddr_t)&dpart, FREAD, p) == 0) { 186 if (dpart.part->p_fstype == FS_BSDFFS && 187 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 188 bsize = dpart.part->p_frag * 189 dpart.part->p_fsize; 190 } 191 bscale = bsize / DEV_BSIZE; 192 do { 193 bn = (uio->uio_offset / DEV_BSIZE) &~ (bscale - 1); 194 on = uio->uio_offset % bsize; 195 n = min((unsigned)(bsize - on), uio->uio_resid); 196 if (vp->v_lastr + bscale == bn) { 197 nextbn = bn + bscale; 198 error = breadn(vp, bn, (int)bsize, &nextbn, 199 (int *)&bsize, 1, NOCRED, &bp); 200 } else 201 error = bread(vp, bn, (int)bsize, NOCRED, &bp); 202 vp->v_lastr = bn; 203 n = min(n, bsize - bp->b_resid); 204 if (error) { 205 brelse(bp); 206 return (error); 207 } 208 error = uiomove(bp->b_un.b_addr + on, n, uio); 209 if (n + on == bsize) 210 bp->b_flags |= B_AGE; 211 brelse(bp); 212 } while (error == 0 && uio->uio_resid > 0 && n != 0); 213 return (error); 214 215 default: 216 panic("spec_read type"); 217 } 218 /* NOTREACHED */ 219 } 220 221 /* 222 * Vnode op for write 223 */ 224 /* ARGSUSED */ 225 spec_write(ap) 226 struct vop_write_args /* { 227 struct vnode *a_vp; 228 struct uio *a_uio; 229 int a_ioflag; 230 struct ucred *a_cred; 231 } */ *ap; 232 { 233 register struct vnode *vp = ap->a_vp; 234 register struct uio *uio = ap->a_uio; 235 struct proc *p = uio->uio_procp; 236 struct buf *bp; 237 daddr_t bn; 238 int bsize, blkmask; 239 struct partinfo dpart; 240 register int n, on; 241 int error = 0; 242 243 #ifdef DIAGNOSTIC 244 if (uio->uio_rw != UIO_WRITE) 245 panic("spec_write mode"); 246 if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) 247 panic("spec_write proc"); 248 #endif 249 250 switch (vp->v_type) { 251 252 case VCHR: 253 VOP_UNLOCK(vp); 254 error = (*cdevsw[major(vp->v_rdev)].d_write) 255 (vp->v_rdev, uio, ap->a_ioflag); 256 VOP_LOCK(vp); 257 return (error); 258 259 case VBLK: 260 if (uio->uio_resid == 0) 261 return (0); 262 if (uio->uio_offset < 0) 263 return (EINVAL); 264 bsize = BLKDEV_IOSIZE; 265 if ((*bdevsw[major(vp->v_rdev)].d_ioctl)(vp->v_rdev, DIOCGPART, 266 (caddr_t)&dpart, FREAD, p) == 0) { 267 if (dpart.part->p_fstype == FS_BSDFFS && 268 dpart.part->p_frag != 0 && dpart.part->p_fsize != 0) 269 bsize = dpart.part->p_frag * 270 dpart.part->p_fsize; 271 } 272 blkmask = (bsize / DEV_BSIZE) - 1; 273 do { 274 bn = (uio->uio_offset / DEV_BSIZE) &~ blkmask; 275 on = uio->uio_offset % bsize; 276 n = min((unsigned)(bsize - on), uio->uio_resid); 277 if (n == bsize) 278 bp = getblk(vp, bn, bsize); 279 else 280 error = bread(vp, bn, bsize, NOCRED, &bp); 281 n = min(n, bsize - bp->b_resid); 282 if (error) { 283 brelse(bp); 284 return (error); 285 } 286 error = uiomove(bp->b_un.b_addr + on, n, uio); 287 if (n + on == bsize) { 288 bp->b_flags |= B_AGE; 289 bawrite(bp); 290 } else 291 bdwrite(bp); 292 } while (error == 0 && uio->uio_resid > 0 && n != 0); 293 return (error); 294 295 default: 296 panic("spec_write type"); 297 } 298 /* NOTREACHED */ 299 } 300 301 /* 302 * Device ioctl operation. 303 */ 304 /* ARGSUSED */ 305 spec_ioctl(ap) 306 struct vop_ioctl_args /* { 307 struct vnode *a_vp; 308 int a_command; 309 caddr_t a_data; 310 int a_fflag; 311 struct ucred *a_cred; 312 struct proc *a_p; 313 } */ *ap; 314 { 315 dev_t dev = ap->a_vp->v_rdev; 316 317 switch (ap->a_vp->v_type) { 318 319 case VCHR: 320 return ((*cdevsw[major(dev)].d_ioctl)(dev, ap->a_command, ap->a_data, 321 ap->a_fflag, ap->a_p)); 322 323 case VBLK: 324 if (ap->a_command == 0 && (int)ap->a_data == B_TAPE) 325 if (bdevsw[major(dev)].d_flags & B_TAPE) 326 return (0); 327 else 328 return (1); 329 return ((*bdevsw[major(dev)].d_ioctl)(dev, ap->a_command, ap->a_data, 330 ap->a_fflag, ap->a_p)); 331 332 default: 333 panic("spec_ioctl"); 334 /* NOTREACHED */ 335 } 336 } 337 338 /* ARGSUSED */ 339 spec_select(ap) 340 struct vop_select_args /* { 341 struct vnode *a_vp; 342 int a_which; 343 int a_fflags; 344 struct ucred *a_cred; 345 struct proc *a_p; 346 } */ *ap; 347 { 348 register dev_t dev; 349 350 switch (ap->a_vp->v_type) { 351 352 default: 353 return (1); /* XXX */ 354 355 case VCHR: 356 dev = ap->a_vp->v_rdev; 357 return (*cdevsw[major(dev)].d_select)(dev, ap->a_which, ap->a_p); 358 } 359 } 360 /* 361 * Synch buffers associated with a block device 362 */ 363 /* ARGSUSED */ 364 int 365 spec_fsync(ap) 366 struct vop_fsync_args /* { 367 struct vnode *a_vp; 368 struct ucred *a_cred; 369 int a_waitfor; 370 struct proc *a_p; 371 } */ *ap; 372 { 373 register struct vnode *vp = ap->a_vp; 374 register struct buf *bp; 375 struct buf *nbp; 376 int s, error, allerror = 0; 377 378 if (vp->v_type == VCHR) 379 return (0); 380 /* 381 * Flush all dirty buffers associated with a block device. 382 */ 383 loop: 384 s = splbio(); 385 for (bp = vp->v_dirtyblkhd; bp; bp = nbp) { 386 nbp = bp->b_blockf; 387 if ((bp->b_flags & B_BUSY)) 388 continue; 389 if ((bp->b_flags & B_DELWRI) == 0) 390 panic("spec_fsync: not dirty"); 391 bremfree(bp); 392 bp->b_flags |= B_BUSY; 393 splx(s); 394 if (error = bawrite(bp)) 395 allerror = error; 396 goto loop; 397 } 398 if (ap->a_waitfor == MNT_WAIT) { 399 while (vp->v_numoutput) { 400 vp->v_flag |= VBWAIT; 401 sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1); 402 } 403 #ifdef DIAGNOSTIC 404 if (vp->v_dirtyblkhd) { 405 vprint("spec_fsync: dirty", vp); 406 goto loop; 407 } 408 #endif 409 } 410 splx(s); 411 return (allerror); 412 } 413 414 /* 415 * Just call the device strategy routine 416 */ 417 spec_strategy(ap) 418 struct vop_strategy_args /* { 419 struct buf *a_bp; 420 } */ *ap; 421 { 422 423 (*bdevsw[major(ap->a_bp->b_dev)].d_strategy)(ap->a_bp); 424 return (0); 425 } 426 427 /* 428 * This is a noop, simply returning what one has been given. 429 */ 430 spec_bmap(ap) 431 struct vop_bmap_args /* { 432 struct vnode *a_vp; 433 daddr_t a_bn; 434 struct vnode **a_vpp; 435 daddr_t *a_bnp; 436 } */ *ap; 437 { 438 439 if (ap->a_vpp != NULL) 440 *ap->a_vpp = ap->a_vp; 441 if (ap->a_bnp != NULL) 442 *ap->a_bnp = ap->a_bn; 443 return (0); 444 } 445 446 /* 447 * At the moment we do not do any locking. 448 */ 449 /* ARGSUSED */ 450 spec_lock(ap) 451 struct vop_lock_args /* { 452 struct vnode *a_vp; 453 } */ *ap; 454 { 455 456 return (0); 457 } 458 459 /* ARGSUSED */ 460 spec_unlock(ap) 461 struct vop_unlock_args /* { 462 struct vnode *a_vp; 463 } */ *ap; 464 { 465 466 return (0); 467 } 468 469 /* 470 * Device close routine 471 */ 472 /* ARGSUSED */ 473 spec_close(ap) 474 struct vop_close_args /* { 475 struct vnode *a_vp; 476 int a_fflag; 477 struct ucred *a_cred; 478 struct proc *a_p; 479 } */ *ap; 480 { 481 register struct vnode *vp = ap->a_vp; 482 dev_t dev = vp->v_rdev; 483 int (*devclose) __P((dev_t, int, int, struct proc *)); 484 int mode, error; 485 486 switch (vp->v_type) { 487 488 case VCHR: 489 /* 490 * If the vnode is locked, then we are in the midst 491 * of forcably closing the device, otherwise we only 492 * close on last reference. 493 */ 494 if (vcount(vp) > 1 && (vp->v_flag & VXLOCK) == 0) 495 return (0); 496 devclose = cdevsw[major(dev)].d_close; 497 mode = S_IFCHR; 498 break; 499 500 case VBLK: 501 /* 502 * On last close of a block device (that isn't mounted) 503 * we must invalidate any in core blocks, so that 504 * we can, for instance, change floppy disks. 505 */ 506 if (error = vinvalbuf(vp, 1, ap->a_cred, ap->a_p)) 507 return (error); 508 /* 509 * We do not want to really close the device if it 510 * is still in use unless we are trying to close it 511 * forcibly. Since every use (buffer, vnode, swap, cmap) 512 * holds a reference to the vnode, and because we mark 513 * any other vnodes that alias this device, when the 514 * sum of the reference counts on all the aliased 515 * vnodes descends to one, we are on last close. 516 */ 517 if (vcount(vp) > 1 && (vp->v_flag & VXLOCK) == 0) 518 return (0); 519 devclose = bdevsw[major(dev)].d_close; 520 mode = S_IFBLK; 521 break; 522 523 default: 524 panic("spec_close: not special"); 525 } 526 527 return ((*devclose)(dev, ap->a_fflag, mode, ap->a_p)); 528 } 529 530 /* 531 * Print out the contents of a special device vnode. 532 */ 533 spec_print(ap) 534 struct vop_print_args /* { 535 struct vnode *a_vp; 536 } */ *ap; 537 { 538 539 printf("tag VT_NON, dev %d, %d\n", major(ap->a_vp->v_rdev), 540 minor(ap->a_vp->v_rdev)); 541 } 542 543 /* 544 * Special device advisory byte-level locks. 545 */ 546 /* ARGSUSED */ 547 spec_advlock(ap) 548 struct vop_advlock_args /* { 549 struct vnode *a_vp; 550 caddr_t a_id; 551 int a_op; 552 struct flock *a_fl; 553 int a_flags; 554 } */ *ap; 555 { 556 557 return (EOPNOTSUPP); 558 } 559 560 /* 561 * Special device failed operation 562 */ 563 spec_ebadf() 564 { 565 566 return (EBADF); 567 } 568 569 /* 570 * Special device bad operation 571 */ 572 spec_badop() 573 { 574 575 panic("spec_badop called"); 576 /* NOTREACHED */ 577 } 578