1 /*- 2 * Copyright (c) 2000-2004 3 * Poul-Henning Kamp. All rights reserved. 4 * Copyright (c) 1989, 1992-1993, 1995 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software donated to Berkeley by 8 * Jan-Simon Pendry. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. 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 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95 32 * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43 33 * 34 * $FreeBSD$ 35 */ 36 37 /* 38 * TODO: 39 * remove empty directories 40 * mkdir: want it ? 41 */ 42 43 #include "opt_mac.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/conf.h> 48 #include <sys/dirent.h> 49 #include <sys/fcntl.h> 50 #include <sys/file.h> 51 #include <sys/filedesc.h> 52 #include <sys/filio.h> 53 #include <sys/kernel.h> 54 #include <sys/lock.h> 55 #include <sys/malloc.h> 56 #include <sys/mount.h> 57 #include <sys/namei.h> 58 #include <sys/priv.h> 59 #include <sys/proc.h> 60 #include <sys/stat.h> 61 #include <sys/sx.h> 62 #include <sys/time.h> 63 #include <sys/ttycom.h> 64 #include <sys/unistd.h> 65 #include <sys/vnode.h> 66 67 static struct vop_vector devfs_vnodeops; 68 static struct vop_vector devfs_specops; 69 static struct fileops devfs_ops_f; 70 71 #include <fs/devfs/devfs.h> 72 #include <fs/devfs/devfs_int.h> 73 74 #include <security/mac/mac_framework.h> 75 76 struct mtx devfs_de_interlock; 77 MTX_SYSINIT(devfs_de_interlock, &devfs_de_interlock, "devfs interlock", MTX_DEF); 78 79 static int 80 devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp) 81 { 82 83 *dswp = devvn_refthread(fp->f_vnode, devp); 84 if (*devp != fp->f_data) { 85 if (*dswp != NULL) 86 dev_relthread(*devp); 87 return (ENXIO); 88 } 89 KASSERT((*devp)->si_refcount > 0, 90 ("devfs: un-referenced struct cdev *(%s)", devtoname(*devp))); 91 if (*dswp == NULL) 92 return (ENXIO); 93 return (0); 94 } 95 96 /* 97 * Construct the fully qualified path name relative to the mountpoint 98 */ 99 static char * 100 devfs_fqpn(char *buf, struct vnode *dvp, struct componentname *cnp) 101 { 102 int i; 103 struct devfs_dirent *de, *dd; 104 struct devfs_mount *dmp; 105 106 dmp = VFSTODEVFS(dvp->v_mount); 107 dd = dvp->v_data; 108 i = SPECNAMELEN; 109 buf[i] = '\0'; 110 i -= cnp->cn_namelen; 111 if (i < 0) 112 return (NULL); 113 bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen); 114 de = dd; 115 while (de != dmp->dm_rootdir) { 116 i--; 117 if (i < 0) 118 return (NULL); 119 buf[i] = '/'; 120 i -= de->de_dirent->d_namlen; 121 if (i < 0) 122 return (NULL); 123 bcopy(de->de_dirent->d_name, buf + i, 124 de->de_dirent->d_namlen); 125 de = TAILQ_FIRST(&de->de_dlist); /* "." */ 126 de = TAILQ_NEXT(de, de_list); /* ".." */ 127 de = de->de_dir; 128 } 129 return (buf + i); 130 } 131 132 static int 133 devfs_allocv_drop_refs(int drop_dm_lock, struct devfs_mount *dmp, 134 struct devfs_dirent *de) 135 { 136 int not_found; 137 138 not_found = 0; 139 if (de->de_flags & DE_DOOMED) 140 not_found = 1; 141 if (DEVFS_DE_DROP(de)) { 142 KASSERT(not_found == 1, ("DEVFS de dropped but not doomed")); 143 devfs_dirent_free(de); 144 } 145 if (DEVFS_DMP_DROP(dmp)) { 146 KASSERT(not_found == 1, 147 ("DEVFS mount struct freed before dirent")); 148 not_found = 2; 149 sx_xunlock(&dmp->dm_lock); 150 devfs_unmount_final(dmp); 151 } 152 if (not_found == 1 || (drop_dm_lock && not_found != 2)) 153 sx_unlock(&dmp->dm_lock); 154 return (not_found); 155 } 156 157 static void 158 devfs_insmntque_dtr(struct vnode *vp, void *arg) 159 { 160 struct devfs_dirent *de; 161 162 de = (struct devfs_dirent *)arg; 163 mtx_lock(&devfs_de_interlock); 164 vp->v_data = NULL; 165 de->de_vnode = NULL; 166 mtx_unlock(&devfs_de_interlock); 167 vgone(vp); 168 vput(vp); 169 } 170 171 /* 172 * devfs_allocv shall be entered with dmp->dm_lock held, and it drops 173 * it on return. 174 */ 175 int 176 devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td) 177 { 178 int error; 179 struct vnode *vp; 180 struct cdev *dev; 181 struct devfs_mount *dmp; 182 183 KASSERT(td == curthread, ("devfs_allocv: td != curthread")); 184 dmp = VFSTODEVFS(mp); 185 if (de->de_flags & DE_DOOMED) { 186 sx_xunlock(&dmp->dm_lock); 187 return (ENOENT); 188 } 189 loop: 190 DEVFS_DE_HOLD(de); 191 DEVFS_DMP_HOLD(dmp); 192 mtx_lock(&devfs_de_interlock); 193 vp = de->de_vnode; 194 if (vp != NULL) { 195 VI_LOCK(vp); 196 mtx_unlock(&devfs_de_interlock); 197 sx_xunlock(&dmp->dm_lock); 198 error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td); 199 sx_xlock(&dmp->dm_lock); 200 if (devfs_allocv_drop_refs(0, dmp, de)) { 201 if (error == 0) 202 vput(vp); 203 return (ENOENT); 204 } 205 else if (error) 206 goto loop; 207 sx_xunlock(&dmp->dm_lock); 208 *vpp = vp; 209 return (0); 210 } 211 mtx_unlock(&devfs_de_interlock); 212 if (de->de_dirent->d_type == DT_CHR) { 213 if (!(de->de_cdp->cdp_flags & CDP_ACTIVE)) { 214 devfs_allocv_drop_refs(1, dmp, de); 215 return (ENOENT); 216 } 217 dev = &de->de_cdp->cdp_c; 218 } else { 219 dev = NULL; 220 } 221 error = getnewvnode("devfs", mp, &devfs_vnodeops, &vp); 222 if (error != 0) { 223 devfs_allocv_drop_refs(1, dmp, de); 224 printf("devfs_allocv: failed to allocate new vnode\n"); 225 return (error); 226 } 227 228 if (de->de_dirent->d_type == DT_CHR) { 229 vp->v_type = VCHR; 230 VI_LOCK(vp); 231 dev_lock(); 232 dev_refl(dev); 233 vp->v_rdev = dev; 234 KASSERT(vp->v_usecount == 1, 235 ("%s %d (%d)\n", __func__, __LINE__, vp->v_usecount)); 236 dev->si_usecount += vp->v_usecount; 237 dev_unlock(); 238 VI_UNLOCK(vp); 239 vp->v_op = &devfs_specops; 240 } else if (de->de_dirent->d_type == DT_DIR) { 241 vp->v_type = VDIR; 242 } else if (de->de_dirent->d_type == DT_LNK) { 243 vp->v_type = VLNK; 244 } else { 245 vp->v_type = VBAD; 246 } 247 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 248 mtx_lock(&devfs_de_interlock); 249 vp->v_data = de; 250 de->de_vnode = vp; 251 mtx_unlock(&devfs_de_interlock); 252 error = insmntque1(vp, mp, devfs_insmntque_dtr, de); 253 if (error != 0) { 254 (void) devfs_allocv_drop_refs(1, dmp, de); 255 return (error); 256 } 257 if (devfs_allocv_drop_refs(0, dmp, de)) { 258 vput(vp); 259 return (ENOENT); 260 } 261 #ifdef MAC 262 mac_associate_vnode_devfs(mp, de, vp); 263 #endif 264 sx_xunlock(&dmp->dm_lock); 265 *vpp = vp; 266 return (0); 267 } 268 269 static int 270 devfs_access(struct vop_access_args *ap) 271 { 272 struct vnode *vp = ap->a_vp; 273 struct devfs_dirent *de; 274 int error; 275 276 de = vp->v_data; 277 if (vp->v_type == VDIR) 278 de = de->de_dir; 279 280 error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid, 281 ap->a_mode, ap->a_cred, NULL); 282 if (!error) 283 return (error); 284 if (error != EACCES) 285 return (error); 286 /* We do, however, allow access to the controlling terminal */ 287 if (!(ap->a_td->td_proc->p_flag & P_CONTROLT)) 288 return (error); 289 if (ap->a_td->td_proc->p_session->s_ttyvp == de->de_vnode) 290 return (0); 291 return (error); 292 } 293 294 /* ARGSUSED */ 295 static int 296 devfs_advlock(struct vop_advlock_args *ap) 297 { 298 299 return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL); 300 } 301 302 /* ARGSUSED */ 303 static int 304 devfs_close(struct vop_close_args *ap) 305 { 306 struct vnode *vp = ap->a_vp, *oldvp; 307 struct thread *td = ap->a_td; 308 struct cdev *dev = vp->v_rdev; 309 struct cdevsw *dsw; 310 int vp_locked, error; 311 312 /* 313 * Hack: a tty device that is a controlling terminal 314 * has a reference from the session structure. 315 * We cannot easily tell that a character device is 316 * a controlling terminal, unless it is the closing 317 * process' controlling terminal. In that case, 318 * if the reference count is 2 (this last descriptor 319 * plus the session), release the reference from the session. 320 */ 321 oldvp = NULL; 322 sx_xlock(&proctree_lock); 323 if (td && vp == td->td_proc->p_session->s_ttyvp) { 324 SESS_LOCK(td->td_proc->p_session); 325 VI_LOCK(vp); 326 if (count_dev(dev) == 2 && (vp->v_iflag & VI_DOOMED) == 0) { 327 td->td_proc->p_session->s_ttyvp = NULL; 328 oldvp = vp; 329 } 330 VI_UNLOCK(vp); 331 SESS_UNLOCK(td->td_proc->p_session); 332 } 333 sx_xunlock(&proctree_lock); 334 if (oldvp != NULL) 335 vrele(oldvp); 336 /* 337 * We do not want to really close the device if it 338 * is still in use unless we are trying to close it 339 * forcibly. Since every use (buffer, vnode, swap, cmap) 340 * holds a reference to the vnode, and because we mark 341 * any other vnodes that alias this device, when the 342 * sum of the reference counts on all the aliased 343 * vnodes descends to one, we are on last close. 344 */ 345 dsw = dev_refthread(dev); 346 if (dsw == NULL) 347 return (ENXIO); 348 VI_LOCK(vp); 349 if (vp->v_iflag & VI_DOOMED) { 350 /* Forced close. */ 351 } else if (dsw->d_flags & D_TRACKCLOSE) { 352 /* Keep device updated on status. */ 353 } else if (count_dev(dev) > 1) { 354 VI_UNLOCK(vp); 355 dev_relthread(dev); 356 return (0); 357 } 358 vholdl(vp); 359 VI_UNLOCK(vp); 360 vp_locked = VOP_ISLOCKED(vp, td); 361 VOP_UNLOCK(vp, 0, td); 362 KASSERT(dev->si_refcount > 0, 363 ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev))); 364 if (!(dsw->d_flags & D_NEEDGIANT)) { 365 DROP_GIANT(); 366 error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td); 367 PICKUP_GIANT(); 368 } else { 369 error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td); 370 } 371 dev_relthread(dev); 372 vn_lock(vp, vp_locked | LK_RETRY, td); 373 vdrop(vp); 374 return (error); 375 } 376 377 static int 378 devfs_close_f(struct file *fp, struct thread *td) 379 { 380 381 return (vnops.fo_close(fp, td)); 382 } 383 384 /* ARGSUSED */ 385 static int 386 devfs_fsync(struct vop_fsync_args *ap) 387 { 388 if (!vn_isdisk(ap->a_vp, NULL)) 389 return (0); 390 391 return (vop_stdfsync(ap)); 392 } 393 394 static int 395 devfs_getattr(struct vop_getattr_args *ap) 396 { 397 struct vnode *vp = ap->a_vp; 398 struct vattr *vap = ap->a_vap; 399 int error = 0; 400 struct devfs_dirent *de; 401 struct cdev *dev; 402 403 de = vp->v_data; 404 KASSERT(de != NULL, ("Null dirent in devfs_getattr vp=%p", vp)); 405 if (vp->v_type == VDIR) { 406 de = de->de_dir; 407 KASSERT(de != NULL, 408 ("Null dir dirent in devfs_getattr vp=%p", vp)); 409 } 410 bzero((caddr_t) vap, sizeof(*vap)); 411 vattr_null(vap); 412 vap->va_uid = de->de_uid; 413 vap->va_gid = de->de_gid; 414 vap->va_mode = de->de_mode; 415 if (vp->v_type == VLNK) 416 vap->va_size = strlen(de->de_symlink); 417 else if (vp->v_type == VDIR) 418 vap->va_size = vap->va_bytes = DEV_BSIZE; 419 else 420 vap->va_size = 0; 421 if (vp->v_type != VDIR) 422 vap->va_bytes = 0; 423 vap->va_blocksize = DEV_BSIZE; 424 vap->va_type = vp->v_type; 425 426 #define fix(aa) \ 427 do { \ 428 if ((aa).tv_sec == 0) { \ 429 (aa).tv_sec = boottime.tv_sec; \ 430 (aa).tv_nsec = boottime.tv_usec * 1000; \ 431 } \ 432 } while (0) 433 434 if (vp->v_type != VCHR) { 435 fix(de->de_atime); 436 vap->va_atime = de->de_atime; 437 fix(de->de_mtime); 438 vap->va_mtime = de->de_mtime; 439 fix(de->de_ctime); 440 vap->va_ctime = de->de_ctime; 441 } else { 442 dev = vp->v_rdev; 443 fix(dev->si_atime); 444 vap->va_atime = dev->si_atime; 445 fix(dev->si_mtime); 446 vap->va_mtime = dev->si_mtime; 447 fix(dev->si_ctime); 448 vap->va_ctime = dev->si_ctime; 449 450 vap->va_rdev = dev->si_priv->cdp_inode; 451 } 452 vap->va_gen = 0; 453 vap->va_flags = 0; 454 vap->va_nlink = de->de_links; 455 vap->va_fileid = de->de_inode; 456 457 return (error); 458 } 459 460 /* ARGSUSED */ 461 static int 462 devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td) 463 { 464 struct cdev *dev; 465 struct cdevsw *dsw; 466 struct vnode *vp; 467 struct vnode *vpold; 468 int error, i; 469 const char *p; 470 struct fiodgname_arg *fgn; 471 472 error = devfs_fp_check(fp, &dev, &dsw); 473 if (error) 474 return (error); 475 476 if (com == FIODTYPE) { 477 *(int *)data = dsw->d_flags & D_TYPEMASK; 478 dev_relthread(dev); 479 return (0); 480 } else if (com == FIODGNAME) { 481 fgn = data; 482 p = devtoname(dev); 483 i = strlen(p) + 1; 484 if (i > fgn->len) 485 error = EINVAL; 486 else 487 error = copyout(p, fgn->buf, i); 488 dev_relthread(dev); 489 return (error); 490 } 491 error = dsw->d_ioctl(dev, com, data, fp->f_flag, td); 492 dev_relthread(dev); 493 if (error == ENOIOCTL) 494 error = ENOTTY; 495 if (error == 0 && com == TIOCSCTTY) { 496 vp = fp->f_vnode; 497 498 /* Do nothing if reassigning same control tty */ 499 sx_slock(&proctree_lock); 500 if (td->td_proc->p_session->s_ttyvp == vp) { 501 sx_sunlock(&proctree_lock); 502 return (0); 503 } 504 505 mtx_lock(&Giant); 506 507 vpold = td->td_proc->p_session->s_ttyvp; 508 VREF(vp); 509 SESS_LOCK(td->td_proc->p_session); 510 td->td_proc->p_session->s_ttyvp = vp; 511 SESS_UNLOCK(td->td_proc->p_session); 512 513 sx_sunlock(&proctree_lock); 514 515 /* Get rid of reference to old control tty */ 516 if (vpold) 517 vrele(vpold); 518 mtx_unlock(&Giant); 519 } 520 return (error); 521 } 522 523 /* ARGSUSED */ 524 static int 525 devfs_kqfilter_f(struct file *fp, struct knote *kn) 526 { 527 struct cdev *dev; 528 struct cdevsw *dsw; 529 int error; 530 531 error = devfs_fp_check(fp, &dev, &dsw); 532 if (error) 533 return (error); 534 error = dsw->d_kqfilter(dev, kn); 535 dev_relthread(dev); 536 return (error); 537 } 538 539 static int 540 devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) 541 { 542 struct componentname *cnp; 543 struct vnode *dvp, **vpp; 544 struct thread *td; 545 struct devfs_dirent *de, *dd; 546 struct devfs_dirent **dde; 547 struct devfs_mount *dmp; 548 struct cdev *cdev; 549 int error, flags, nameiop; 550 char specname[SPECNAMELEN + 1], *pname; 551 552 cnp = ap->a_cnp; 553 vpp = ap->a_vpp; 554 dvp = ap->a_dvp; 555 pname = cnp->cn_nameptr; 556 td = cnp->cn_thread; 557 flags = cnp->cn_flags; 558 nameiop = cnp->cn_nameiop; 559 dmp = VFSTODEVFS(dvp->v_mount); 560 dd = dvp->v_data; 561 *vpp = NULLVP; 562 563 if ((flags & ISLASTCN) && nameiop == RENAME) 564 return (EOPNOTSUPP); 565 566 if (dvp->v_type != VDIR) 567 return (ENOTDIR); 568 569 if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT)) 570 return (EIO); 571 572 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td); 573 if (error) 574 return (error); 575 576 if (cnp->cn_namelen == 1 && *pname == '.') { 577 if ((flags & ISLASTCN) && nameiop != LOOKUP) 578 return (EINVAL); 579 *vpp = dvp; 580 VREF(dvp); 581 return (0); 582 } 583 584 if (flags & ISDOTDOT) { 585 if ((flags & ISLASTCN) && nameiop != LOOKUP) 586 return (EINVAL); 587 VOP_UNLOCK(dvp, 0, td); 588 de = TAILQ_FIRST(&dd->de_dlist); /* "." */ 589 de = TAILQ_NEXT(de, de_list); /* ".." */ 590 de = de->de_dir; 591 error = devfs_allocv(de, dvp->v_mount, vpp, td); 592 *dm_unlock = 0; 593 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td); 594 return (error); 595 } 596 597 DEVFS_DMP_HOLD(dmp); 598 devfs_populate(dmp); 599 if (DEVFS_DMP_DROP(dmp)) { 600 *dm_unlock = 0; 601 sx_xunlock(&dmp->dm_lock); 602 devfs_unmount_final(dmp); 603 return (ENOENT); 604 } 605 dd = dvp->v_data; 606 de = devfs_find(dd, cnp->cn_nameptr, cnp->cn_namelen); 607 while (de == NULL) { /* While(...) so we can use break */ 608 609 if (nameiop == DELETE) 610 return (ENOENT); 611 612 /* 613 * OK, we didn't have an entry for the name we were asked for 614 * so we try to see if anybody can create it on demand. 615 */ 616 pname = devfs_fqpn(specname, dvp, cnp); 617 if (pname == NULL) 618 break; 619 620 cdev = NULL; 621 EVENTHANDLER_INVOKE(dev_clone, 622 td->td_ucred, pname, strlen(pname), &cdev); 623 if (cdev == NULL) 624 break; 625 626 DEVFS_DMP_HOLD(dmp); 627 devfs_populate(dmp); 628 if (DEVFS_DMP_DROP(dmp)) { 629 *dm_unlock = 0; 630 sx_xunlock(&dmp->dm_lock); 631 devfs_unmount_final(dmp); 632 return (ENOENT); 633 } 634 635 dev_lock(); 636 dde = &cdev->si_priv->cdp_dirents[dmp->dm_idx]; 637 if (dde != NULL && *dde != NULL) 638 de = *dde; 639 dev_unlock(); 640 dev_rel(cdev); 641 break; 642 } 643 644 if (de == NULL || de->de_flags & DE_WHITEOUT) { 645 if ((nameiop == CREATE || nameiop == RENAME) && 646 (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) { 647 cnp->cn_flags |= SAVENAME; 648 return (EJUSTRETURN); 649 } 650 return (ENOENT); 651 } 652 653 if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) { 654 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); 655 if (error) 656 return (error); 657 if (*vpp == dvp) { 658 VREF(dvp); 659 *vpp = dvp; 660 return (0); 661 } 662 } 663 error = devfs_allocv(de, dvp->v_mount, vpp, td); 664 *dm_unlock = 0; 665 return (error); 666 } 667 668 static int 669 devfs_lookup(struct vop_lookup_args *ap) 670 { 671 int j; 672 struct devfs_mount *dmp; 673 int dm_unlock; 674 675 dmp = VFSTODEVFS(ap->a_dvp->v_mount); 676 dm_unlock = 1; 677 sx_xlock(&dmp->dm_lock); 678 j = devfs_lookupx(ap, &dm_unlock); 679 if (dm_unlock == 1) 680 sx_xunlock(&dmp->dm_lock); 681 return (j); 682 } 683 684 static int 685 devfs_mknod(struct vop_mknod_args *ap) 686 { 687 struct componentname *cnp; 688 struct vnode *dvp, **vpp; 689 struct thread *td; 690 struct devfs_dirent *dd, *de; 691 struct devfs_mount *dmp; 692 int error; 693 694 /* 695 * The only type of node we should be creating here is a 696 * character device, for anything else return EOPNOTSUPP. 697 */ 698 if (ap->a_vap->va_type != VCHR) 699 return (EOPNOTSUPP); 700 dvp = ap->a_dvp; 701 dmp = VFSTODEVFS(dvp->v_mount); 702 703 cnp = ap->a_cnp; 704 vpp = ap->a_vpp; 705 td = cnp->cn_thread; 706 dd = dvp->v_data; 707 708 error = ENOENT; 709 sx_xlock(&dmp->dm_lock); 710 TAILQ_FOREACH(de, &dd->de_dlist, de_list) { 711 if (cnp->cn_namelen != de->de_dirent->d_namlen) 712 continue; 713 if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name, 714 de->de_dirent->d_namlen) != 0) 715 continue; 716 if (de->de_flags & DE_WHITEOUT) 717 break; 718 goto notfound; 719 } 720 if (de == NULL) 721 goto notfound; 722 de->de_flags &= ~DE_WHITEOUT; 723 error = devfs_allocv(de, dvp->v_mount, vpp, td); 724 return (error); 725 notfound: 726 sx_xunlock(&dmp->dm_lock); 727 return (error); 728 } 729 730 /* ARGSUSED */ 731 static int 732 devfs_open(struct vop_open_args *ap) 733 { 734 struct thread *td = ap->a_td; 735 struct vnode *vp = ap->a_vp; 736 struct cdev *dev = vp->v_rdev; 737 struct file *fp; 738 int error; 739 struct cdevsw *dsw; 740 741 if (vp->v_type == VBLK) 742 return (ENXIO); 743 744 if (dev == NULL) 745 return (ENXIO); 746 747 /* Make this field valid before any I/O in d_open. */ 748 if (dev->si_iosize_max == 0) 749 dev->si_iosize_max = DFLTPHYS; 750 751 dsw = dev_refthread(dev); 752 if (dsw == NULL) 753 return (ENXIO); 754 755 /* XXX: Special casing of ttys for deadfs. Probably redundant. */ 756 if (dsw->d_flags & D_TTY) 757 vp->v_vflag |= VV_ISTTY; 758 759 VOP_UNLOCK(vp, 0, td); 760 761 if(!(dsw->d_flags & D_NEEDGIANT)) { 762 DROP_GIANT(); 763 if (dsw->d_fdopen != NULL) 764 error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx); 765 else 766 error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td); 767 PICKUP_GIANT(); 768 } else { 769 if (dsw->d_fdopen != NULL) 770 error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx); 771 else 772 error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td); 773 } 774 775 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 776 777 dev_relthread(dev); 778 779 if (error) 780 return (error); 781 782 #if 0 /* /dev/console */ 783 KASSERT(ap->a_fdidx >= 0, 784 ("Could not vnode bypass device on fd %d", ap->a_fdidx)); 785 #else 786 if(ap->a_fdidx < 0) 787 return (error); 788 #endif 789 /* 790 * This is a pretty disgustingly long chain, but I am not 791 * sure there is any better way. Passing the fdidx into 792 * VOP_OPEN() offers us more information than just passing 793 * the file *. 794 */ 795 fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx]; 796 KASSERT(fp->f_ops == &badfileops, 797 ("Could not vnode bypass device on fdops %p", fp->f_ops)); 798 fp->f_ops = &devfs_ops_f; 799 fp->f_data = dev; 800 return (error); 801 } 802 803 static int 804 devfs_pathconf(struct vop_pathconf_args *ap) 805 { 806 807 switch (ap->a_name) { 808 case _PC_MAC_PRESENT: 809 #ifdef MAC 810 /* 811 * If MAC is enabled, devfs automatically supports 812 * trivial non-persistant label storage. 813 */ 814 *ap->a_retval = 1; 815 #else 816 *ap->a_retval = 0; 817 #endif 818 return (0); 819 default: 820 return (vop_stdpathconf(ap)); 821 } 822 /* NOTREACHED */ 823 } 824 825 /* ARGSUSED */ 826 static int 827 devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td) 828 { 829 struct cdev *dev; 830 struct cdevsw *dsw; 831 int error; 832 833 error = devfs_fp_check(fp, &dev, &dsw); 834 if (error) 835 return (error); 836 error = dsw->d_poll(dev, events, td); 837 dev_relthread(dev); 838 return(error); 839 } 840 841 /* 842 * Print out the contents of a special device vnode. 843 */ 844 static int 845 devfs_print(struct vop_print_args *ap) 846 { 847 848 printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev)); 849 return (0); 850 } 851 852 /* ARGSUSED */ 853 static int 854 devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td) 855 { 856 struct cdev *dev; 857 int ioflag, error, resid; 858 struct cdevsw *dsw; 859 860 error = devfs_fp_check(fp, &dev, &dsw); 861 if (error) 862 return (error); 863 resid = uio->uio_resid; 864 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT); 865 if (ioflag & O_DIRECT) 866 ioflag |= IO_DIRECT; 867 868 if ((flags & FOF_OFFSET) == 0) 869 uio->uio_offset = fp->f_offset; 870 871 error = dsw->d_read(dev, uio, ioflag); 872 if (uio->uio_resid != resid || (error == 0 && resid != 0)) 873 vfs_timestamp(&dev->si_atime); 874 dev_relthread(dev); 875 876 if ((flags & FOF_OFFSET) == 0) 877 fp->f_offset = uio->uio_offset; 878 fp->f_nextoff = uio->uio_offset; 879 return (error); 880 } 881 882 static int 883 devfs_readdir(struct vop_readdir_args *ap) 884 { 885 int error; 886 struct uio *uio; 887 struct dirent *dp; 888 struct devfs_dirent *dd; 889 struct devfs_dirent *de; 890 struct devfs_mount *dmp; 891 off_t off, oldoff; 892 int *tmp_ncookies = NULL; 893 894 if (ap->a_vp->v_type != VDIR) 895 return (ENOTDIR); 896 897 uio = ap->a_uio; 898 if (uio->uio_offset < 0) 899 return (EINVAL); 900 901 /* 902 * XXX: This is a temporary hack to get around this filesystem not 903 * supporting cookies. We store the location of the ncookies pointer 904 * in a temporary variable before calling vfs_subr.c:vfs_read_dirent() 905 * and set the number of cookies to 0. We then set the pointer to 906 * NULL so that vfs_read_dirent doesn't try to call realloc() on 907 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies 908 * pointer to its original location before returning to the caller. 909 */ 910 if (ap->a_ncookies != NULL) { 911 tmp_ncookies = ap->a_ncookies; 912 *ap->a_ncookies = 0; 913 ap->a_ncookies = NULL; 914 } 915 916 dmp = VFSTODEVFS(ap->a_vp->v_mount); 917 sx_xlock(&dmp->dm_lock); 918 DEVFS_DMP_HOLD(dmp); 919 devfs_populate(dmp); 920 if (DEVFS_DMP_DROP(dmp)) { 921 sx_xunlock(&dmp->dm_lock); 922 devfs_unmount_final(dmp); 923 if (tmp_ncookies != NULL) 924 ap->a_ncookies = tmp_ncookies; 925 return (EIO); 926 } 927 error = 0; 928 de = ap->a_vp->v_data; 929 off = 0; 930 oldoff = uio->uio_offset; 931 TAILQ_FOREACH(dd, &de->de_dlist, de_list) { 932 KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__)); 933 if (dd->de_flags & DE_WHITEOUT) 934 continue; 935 if (dd->de_dirent->d_type == DT_DIR) 936 de = dd->de_dir; 937 else 938 de = dd; 939 dp = dd->de_dirent; 940 if (dp->d_reclen > uio->uio_resid) 941 break; 942 dp->d_fileno = de->de_inode; 943 if (off >= uio->uio_offset) { 944 error = vfs_read_dirent(ap, dp, off); 945 if (error) 946 break; 947 } 948 off += dp->d_reclen; 949 } 950 sx_xunlock(&dmp->dm_lock); 951 uio->uio_offset = off; 952 953 /* 954 * Restore ap->a_ncookies if it wasn't originally NULL in the first 955 * place. 956 */ 957 if (tmp_ncookies != NULL) 958 ap->a_ncookies = tmp_ncookies; 959 960 return (error); 961 } 962 963 static int 964 devfs_readlink(struct vop_readlink_args *ap) 965 { 966 struct devfs_dirent *de; 967 968 de = ap->a_vp->v_data; 969 return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio)); 970 } 971 972 static int 973 devfs_reclaim(struct vop_reclaim_args *ap) 974 { 975 struct vnode *vp = ap->a_vp; 976 struct devfs_dirent *de; 977 struct cdev *dev; 978 979 mtx_lock(&devfs_de_interlock); 980 de = vp->v_data; 981 if (de != NULL) { 982 de->de_vnode = NULL; 983 vp->v_data = NULL; 984 } 985 mtx_unlock(&devfs_de_interlock); 986 987 vnode_destroy_vobject(vp); 988 989 dev_lock(); 990 dev = vp->v_rdev; 991 vp->v_rdev = NULL; 992 993 if (dev == NULL) { 994 dev_unlock(); 995 return (0); 996 } 997 998 dev->si_usecount -= vp->v_usecount; 999 dev_unlock(); 1000 dev_rel(dev); 1001 return (0); 1002 } 1003 1004 static int 1005 devfs_remove(struct vop_remove_args *ap) 1006 { 1007 struct vnode *vp = ap->a_vp; 1008 struct devfs_dirent *dd; 1009 struct devfs_dirent *de; 1010 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount); 1011 1012 sx_xlock(&dmp->dm_lock); 1013 dd = ap->a_dvp->v_data; 1014 de = vp->v_data; 1015 if (de->de_cdp == NULL) { 1016 TAILQ_REMOVE(&dd->de_dlist, de, de_list); 1017 devfs_delete(dmp, de, 1); 1018 } else { 1019 de->de_flags |= DE_WHITEOUT; 1020 } 1021 sx_xunlock(&dmp->dm_lock); 1022 return (0); 1023 } 1024 1025 /* 1026 * Revoke is called on a tty when a terminal session ends. The vnode 1027 * is orphaned by setting v_op to deadfs so we need to let go of it 1028 * as well so that we create a new one next time around. 1029 * 1030 */ 1031 static int 1032 devfs_revoke(struct vop_revoke_args *ap) 1033 { 1034 struct vnode *vp = ap->a_vp, *vp2; 1035 struct cdev *dev; 1036 struct cdev_priv *cdp; 1037 struct devfs_dirent *de; 1038 int i; 1039 1040 KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL")); 1041 1042 dev = vp->v_rdev; 1043 cdp = dev->si_priv; 1044 1045 dev_lock(); 1046 cdp->cdp_inuse++; 1047 dev_unlock(); 1048 1049 vhold(vp); 1050 vgone(vp); 1051 vdrop(vp); 1052 1053 VOP_UNLOCK(vp,0,curthread); 1054 loop: 1055 for (;;) { 1056 mtx_lock(&devfs_de_interlock); 1057 dev_lock(); 1058 vp2 = NULL; 1059 for (i = 0; i <= cdp->cdp_maxdirent; i++) { 1060 de = cdp->cdp_dirents[i]; 1061 if (de == NULL) 1062 continue; 1063 1064 vp2 = de->de_vnode; 1065 if (vp2 != NULL) { 1066 dev_unlock(); 1067 VI_LOCK(vp2); 1068 mtx_unlock(&devfs_de_interlock); 1069 if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK, 1070 curthread)) 1071 goto loop; 1072 vhold(vp2); 1073 vgone(vp2); 1074 vdrop(vp2); 1075 vput(vp2); 1076 break; 1077 } 1078 } 1079 if (vp2 != NULL) { 1080 continue; 1081 } 1082 dev_unlock(); 1083 mtx_unlock(&devfs_de_interlock); 1084 break; 1085 } 1086 dev_lock(); 1087 cdp->cdp_inuse--; 1088 if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) { 1089 TAILQ_REMOVE(&cdevp_list, cdp, cdp_list); 1090 dev_unlock(); 1091 dev_rel(&cdp->cdp_c); 1092 } else 1093 dev_unlock(); 1094 1095 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); 1096 return (0); 1097 } 1098 1099 static int 1100 devfs_rioctl(struct vop_ioctl_args *ap) 1101 { 1102 int error; 1103 struct devfs_mount *dmp; 1104 1105 dmp = VFSTODEVFS(ap->a_vp->v_mount); 1106 sx_xlock(&dmp->dm_lock); 1107 DEVFS_DMP_HOLD(dmp); 1108 devfs_populate(dmp); 1109 if (DEVFS_DMP_DROP(dmp)) { 1110 sx_xunlock(&dmp->dm_lock); 1111 devfs_unmount_final(dmp); 1112 return (ENOENT); 1113 } 1114 error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td); 1115 sx_xunlock(&dmp->dm_lock); 1116 return (error); 1117 } 1118 1119 static int 1120 devfs_rread(struct vop_read_args *ap) 1121 { 1122 1123 if (ap->a_vp->v_type != VDIR) 1124 return (EINVAL); 1125 return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL)); 1126 } 1127 1128 static int 1129 devfs_setattr(struct vop_setattr_args *ap) 1130 { 1131 struct devfs_dirent *de; 1132 struct vattr *vap; 1133 struct vnode *vp; 1134 int c, error; 1135 uid_t uid; 1136 gid_t gid; 1137 1138 vap = ap->a_vap; 1139 vp = ap->a_vp; 1140 if ((vap->va_type != VNON) || 1141 (vap->va_nlink != VNOVAL) || 1142 (vap->va_fsid != VNOVAL) || 1143 (vap->va_fileid != VNOVAL) || 1144 (vap->va_blocksize != VNOVAL) || 1145 (vap->va_flags != VNOVAL && vap->va_flags != 0) || 1146 (vap->va_rdev != VNOVAL) || 1147 ((int)vap->va_bytes != VNOVAL) || 1148 (vap->va_gen != VNOVAL)) { 1149 return (EINVAL); 1150 } 1151 1152 de = vp->v_data; 1153 if (vp->v_type == VDIR) 1154 de = de->de_dir; 1155 1156 error = c = 0; 1157 if (vap->va_uid == (uid_t)VNOVAL) 1158 uid = de->de_uid; 1159 else 1160 uid = vap->va_uid; 1161 if (vap->va_gid == (gid_t)VNOVAL) 1162 gid = de->de_gid; 1163 else 1164 gid = vap->va_gid; 1165 if (uid != de->de_uid || gid != de->de_gid) { 1166 if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || 1167 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) { 1168 error = priv_check_cred(ap->a_td->td_ucred, 1169 PRIV_VFS_CHOWN, SUSER_ALLOWJAIL); 1170 if (error) 1171 return (error); 1172 } 1173 de->de_uid = uid; 1174 de->de_gid = gid; 1175 c = 1; 1176 } 1177 1178 if (vap->va_mode != (mode_t)VNOVAL) { 1179 if (ap->a_cred->cr_uid != de->de_uid) { 1180 error = priv_check_cred(ap->a_td->td_ucred, 1181 PRIV_VFS_ADMIN, SUSER_ALLOWJAIL); 1182 if (error) 1183 return (error); 1184 } 1185 de->de_mode = vap->va_mode; 1186 c = 1; 1187 } 1188 1189 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 1190 /* See the comment in ufs_vnops::ufs_setattr(). */ 1191 if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)) && 1192 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 1193 (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td)))) 1194 return (error); 1195 if (vap->va_atime.tv_sec != VNOVAL) { 1196 if (vp->v_type == VCHR) 1197 vp->v_rdev->si_atime = vap->va_atime; 1198 else 1199 de->de_atime = vap->va_atime; 1200 } 1201 if (vap->va_mtime.tv_sec != VNOVAL) { 1202 if (vp->v_type == VCHR) 1203 vp->v_rdev->si_mtime = vap->va_mtime; 1204 else 1205 de->de_mtime = vap->va_mtime; 1206 } 1207 c = 1; 1208 } 1209 1210 if (c) { 1211 if (vp->v_type == VCHR) 1212 vfs_timestamp(&vp->v_rdev->si_ctime); 1213 else 1214 vfs_timestamp(&de->de_mtime); 1215 } 1216 return (0); 1217 } 1218 1219 #ifdef MAC 1220 static int 1221 devfs_setlabel(struct vop_setlabel_args *ap) 1222 { 1223 struct vnode *vp; 1224 struct devfs_dirent *de; 1225 1226 vp = ap->a_vp; 1227 de = vp->v_data; 1228 1229 mac_relabel_vnode(ap->a_cred, vp, ap->a_label); 1230 mac_update_devfsdirent(vp->v_mount, de, vp); 1231 1232 return (0); 1233 } 1234 #endif 1235 1236 static int 1237 devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td) 1238 { 1239 1240 return (vnops.fo_stat(fp, sb, cred, td)); 1241 } 1242 1243 static int 1244 devfs_symlink(struct vop_symlink_args *ap) 1245 { 1246 int i, error; 1247 struct devfs_dirent *dd; 1248 struct devfs_dirent *de; 1249 struct devfs_mount *dmp; 1250 struct thread *td; 1251 1252 td = ap->a_cnp->cn_thread; 1253 KASSERT(td == curthread, ("devfs_symlink: td != curthread")); 1254 1255 error = priv_check(td, PRIV_DEVFS_SYMLINK); 1256 if (error) 1257 return(error); 1258 dmp = VFSTODEVFS(ap->a_dvp->v_mount); 1259 dd = ap->a_dvp->v_data; 1260 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen); 1261 de->de_uid = 0; 1262 de->de_gid = 0; 1263 de->de_mode = 0755; 1264 de->de_inode = alloc_unr(devfs_inos); 1265 de->de_dirent->d_type = DT_LNK; 1266 i = strlen(ap->a_target) + 1; 1267 de->de_symlink = malloc(i, M_DEVFS, M_WAITOK); 1268 bcopy(ap->a_target, de->de_symlink, i); 1269 sx_xlock(&dmp->dm_lock); 1270 #ifdef MAC 1271 mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); 1272 #endif 1273 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); 1274 return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td)); 1275 } 1276 1277 /* ARGSUSED */ 1278 static int 1279 devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td) 1280 { 1281 struct cdev *dev; 1282 int error, ioflag, resid; 1283 struct cdevsw *dsw; 1284 1285 error = devfs_fp_check(fp, &dev, &dsw); 1286 if (error) 1287 return (error); 1288 KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); 1289 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC); 1290 if (ioflag & O_DIRECT) 1291 ioflag |= IO_DIRECT; 1292 if ((flags & FOF_OFFSET) == 0) 1293 uio->uio_offset = fp->f_offset; 1294 1295 resid = uio->uio_resid; 1296 1297 error = dsw->d_write(dev, uio, ioflag); 1298 if (uio->uio_resid != resid || (error == 0 && resid != 0)) { 1299 vfs_timestamp(&dev->si_ctime); 1300 dev->si_mtime = dev->si_ctime; 1301 } 1302 dev_relthread(dev); 1303 1304 if ((flags & FOF_OFFSET) == 0) 1305 fp->f_offset = uio->uio_offset; 1306 fp->f_nextoff = uio->uio_offset; 1307 return (error); 1308 } 1309 1310 dev_t 1311 dev2udev(struct cdev *x) 1312 { 1313 if (x == NULL) 1314 return (NODEV); 1315 return (x->si_priv->cdp_inode); 1316 } 1317 1318 static struct fileops devfs_ops_f = { 1319 .fo_read = devfs_read_f, 1320 .fo_write = devfs_write_f, 1321 .fo_ioctl = devfs_ioctl_f, 1322 .fo_poll = devfs_poll_f, 1323 .fo_kqfilter = devfs_kqfilter_f, 1324 .fo_stat = devfs_stat_f, 1325 .fo_close = devfs_close_f, 1326 .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE 1327 }; 1328 1329 static struct vop_vector devfs_vnodeops = { 1330 .vop_default = &default_vnodeops, 1331 1332 .vop_access = devfs_access, 1333 .vop_getattr = devfs_getattr, 1334 .vop_ioctl = devfs_rioctl, 1335 .vop_lookup = devfs_lookup, 1336 .vop_mknod = devfs_mknod, 1337 .vop_pathconf = devfs_pathconf, 1338 .vop_read = devfs_rread, 1339 .vop_readdir = devfs_readdir, 1340 .vop_readlink = devfs_readlink, 1341 .vop_reclaim = devfs_reclaim, 1342 .vop_remove = devfs_remove, 1343 .vop_revoke = devfs_revoke, 1344 .vop_setattr = devfs_setattr, 1345 #ifdef MAC 1346 .vop_setlabel = devfs_setlabel, 1347 #endif 1348 .vop_symlink = devfs_symlink, 1349 }; 1350 1351 static struct vop_vector devfs_specops = { 1352 .vop_default = &default_vnodeops, 1353 1354 .vop_access = devfs_access, 1355 .vop_advlock = devfs_advlock, 1356 .vop_bmap = VOP_PANIC, 1357 .vop_close = devfs_close, 1358 .vop_create = VOP_PANIC, 1359 .vop_fsync = devfs_fsync, 1360 .vop_getattr = devfs_getattr, 1361 .vop_lease = VOP_NULL, 1362 .vop_link = VOP_PANIC, 1363 .vop_mkdir = VOP_PANIC, 1364 .vop_mknod = VOP_PANIC, 1365 .vop_open = devfs_open, 1366 .vop_pathconf = devfs_pathconf, 1367 .vop_print = devfs_print, 1368 .vop_read = VOP_PANIC, 1369 .vop_readdir = VOP_PANIC, 1370 .vop_readlink = VOP_PANIC, 1371 .vop_reallocblks = VOP_PANIC, 1372 .vop_reclaim = devfs_reclaim, 1373 .vop_remove = devfs_remove, 1374 .vop_rename = VOP_PANIC, 1375 .vop_revoke = devfs_revoke, 1376 .vop_rmdir = VOP_PANIC, 1377 .vop_setattr = devfs_setattr, 1378 #ifdef MAC 1379 .vop_setlabel = devfs_setlabel, 1380 #endif 1381 .vop_strategy = VOP_PANIC, 1382 .vop_symlink = VOP_PANIC, 1383 .vop_write = VOP_PANIC, 1384 }; 1385 1386 /* 1387 * Our calling convention to the device drivers used to be that we passed 1388 * vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_ 1389 * flags instead since that's what open(), close() and ioctl() takes and 1390 * we don't really want vnode.h in device drivers. 1391 * We solved the source compatibility by redefining some vnode flags to 1392 * be the same as the fcntl ones and by sending down the bitwise OR of 1393 * the respective fcntl/vnode flags. These CTASSERTS make sure nobody 1394 * pulls the rug out under this. 1395 */ 1396 CTASSERT(O_NONBLOCK == IO_NDELAY); 1397 CTASSERT(O_FSYNC == IO_SYNC); 1398