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); /* XXX TTY */ 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); /* XXX TTY */ 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 FILE_LOCK(fp); 797 KASSERT(fp->f_ops == &badfileops, 798 ("Could not vnode bypass device on fdops %p", fp->f_ops)); 799 fp->f_data = dev; 800 fp->f_ops = &devfs_ops_f; 801 FILE_UNLOCK(fp); 802 return (error); 803 } 804 805 static int 806 devfs_pathconf(struct vop_pathconf_args *ap) 807 { 808 809 switch (ap->a_name) { 810 case _PC_MAC_PRESENT: 811 #ifdef MAC 812 /* 813 * If MAC is enabled, devfs automatically supports 814 * trivial non-persistant label storage. 815 */ 816 *ap->a_retval = 1; 817 #else 818 *ap->a_retval = 0; 819 #endif 820 return (0); 821 default: 822 return (vop_stdpathconf(ap)); 823 } 824 /* NOTREACHED */ 825 } 826 827 /* ARGSUSED */ 828 static int 829 devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td) 830 { 831 struct cdev *dev; 832 struct cdevsw *dsw; 833 int error; 834 835 error = devfs_fp_check(fp, &dev, &dsw); 836 if (error) 837 return (error); 838 error = dsw->d_poll(dev, events, td); 839 dev_relthread(dev); 840 return(error); 841 } 842 843 /* 844 * Print out the contents of a special device vnode. 845 */ 846 static int 847 devfs_print(struct vop_print_args *ap) 848 { 849 850 printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev)); 851 return (0); 852 } 853 854 /* ARGSUSED */ 855 static int 856 devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td) 857 { 858 struct cdev *dev; 859 int ioflag, error, resid; 860 struct cdevsw *dsw; 861 862 error = devfs_fp_check(fp, &dev, &dsw); 863 if (error) 864 return (error); 865 resid = uio->uio_resid; 866 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT); 867 if (ioflag & O_DIRECT) 868 ioflag |= IO_DIRECT; 869 870 if ((flags & FOF_OFFSET) == 0) 871 uio->uio_offset = fp->f_offset; 872 873 error = dsw->d_read(dev, uio, ioflag); 874 if (uio->uio_resid != resid || (error == 0 && resid != 0)) 875 vfs_timestamp(&dev->si_atime); 876 dev_relthread(dev); 877 878 if ((flags & FOF_OFFSET) == 0) 879 fp->f_offset = uio->uio_offset; 880 fp->f_nextoff = uio->uio_offset; 881 return (error); 882 } 883 884 static int 885 devfs_readdir(struct vop_readdir_args *ap) 886 { 887 int error; 888 struct uio *uio; 889 struct dirent *dp; 890 struct devfs_dirent *dd; 891 struct devfs_dirent *de; 892 struct devfs_mount *dmp; 893 off_t off, oldoff; 894 int *tmp_ncookies = NULL; 895 896 if (ap->a_vp->v_type != VDIR) 897 return (ENOTDIR); 898 899 uio = ap->a_uio; 900 if (uio->uio_offset < 0) 901 return (EINVAL); 902 903 /* 904 * XXX: This is a temporary hack to get around this filesystem not 905 * supporting cookies. We store the location of the ncookies pointer 906 * in a temporary variable before calling vfs_subr.c:vfs_read_dirent() 907 * and set the number of cookies to 0. We then set the pointer to 908 * NULL so that vfs_read_dirent doesn't try to call realloc() on 909 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies 910 * pointer to its original location before returning to the caller. 911 */ 912 if (ap->a_ncookies != NULL) { 913 tmp_ncookies = ap->a_ncookies; 914 *ap->a_ncookies = 0; 915 ap->a_ncookies = NULL; 916 } 917 918 dmp = VFSTODEVFS(ap->a_vp->v_mount); 919 sx_xlock(&dmp->dm_lock); 920 DEVFS_DMP_HOLD(dmp); 921 devfs_populate(dmp); 922 if (DEVFS_DMP_DROP(dmp)) { 923 sx_xunlock(&dmp->dm_lock); 924 devfs_unmount_final(dmp); 925 if (tmp_ncookies != NULL) 926 ap->a_ncookies = tmp_ncookies; 927 return (EIO); 928 } 929 error = 0; 930 de = ap->a_vp->v_data; 931 off = 0; 932 oldoff = uio->uio_offset; 933 TAILQ_FOREACH(dd, &de->de_dlist, de_list) { 934 KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__)); 935 if (dd->de_flags & DE_WHITEOUT) 936 continue; 937 if (dd->de_dirent->d_type == DT_DIR) 938 de = dd->de_dir; 939 else 940 de = dd; 941 dp = dd->de_dirent; 942 if (dp->d_reclen > uio->uio_resid) 943 break; 944 dp->d_fileno = de->de_inode; 945 if (off >= uio->uio_offset) { 946 error = vfs_read_dirent(ap, dp, off); 947 if (error) 948 break; 949 } 950 off += dp->d_reclen; 951 } 952 sx_xunlock(&dmp->dm_lock); 953 uio->uio_offset = off; 954 955 /* 956 * Restore ap->a_ncookies if it wasn't originally NULL in the first 957 * place. 958 */ 959 if (tmp_ncookies != NULL) 960 ap->a_ncookies = tmp_ncookies; 961 962 return (error); 963 } 964 965 static int 966 devfs_readlink(struct vop_readlink_args *ap) 967 { 968 struct devfs_dirent *de; 969 970 de = ap->a_vp->v_data; 971 return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio)); 972 } 973 974 static int 975 devfs_reclaim(struct vop_reclaim_args *ap) 976 { 977 struct vnode *vp = ap->a_vp; 978 struct devfs_dirent *de; 979 struct cdev *dev; 980 981 mtx_lock(&devfs_de_interlock); 982 de = vp->v_data; 983 if (de != NULL) { 984 de->de_vnode = NULL; 985 vp->v_data = NULL; 986 } 987 mtx_unlock(&devfs_de_interlock); 988 989 vnode_destroy_vobject(vp); 990 991 dev_lock(); 992 dev = vp->v_rdev; 993 vp->v_rdev = NULL; 994 995 if (dev == NULL) { 996 dev_unlock(); 997 return (0); 998 } 999 1000 dev->si_usecount -= vp->v_usecount; 1001 dev_unlock(); 1002 dev_rel(dev); 1003 return (0); 1004 } 1005 1006 static int 1007 devfs_remove(struct vop_remove_args *ap) 1008 { 1009 struct vnode *vp = ap->a_vp; 1010 struct devfs_dirent *dd; 1011 struct devfs_dirent *de; 1012 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount); 1013 1014 sx_xlock(&dmp->dm_lock); 1015 dd = ap->a_dvp->v_data; 1016 de = vp->v_data; 1017 if (de->de_cdp == NULL) { 1018 TAILQ_REMOVE(&dd->de_dlist, de, de_list); 1019 devfs_delete(dmp, de, 1); 1020 } else { 1021 de->de_flags |= DE_WHITEOUT; 1022 } 1023 sx_xunlock(&dmp->dm_lock); 1024 return (0); 1025 } 1026 1027 /* 1028 * Revoke is called on a tty when a terminal session ends. The vnode 1029 * is orphaned by setting v_op to deadfs so we need to let go of it 1030 * as well so that we create a new one next time around. 1031 * 1032 */ 1033 static int 1034 devfs_revoke(struct vop_revoke_args *ap) 1035 { 1036 struct vnode *vp = ap->a_vp, *vp2; 1037 struct cdev *dev; 1038 struct cdev_priv *cdp; 1039 struct devfs_dirent *de; 1040 int i; 1041 1042 KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL")); 1043 1044 dev = vp->v_rdev; 1045 cdp = dev->si_priv; 1046 1047 dev_lock(); 1048 cdp->cdp_inuse++; 1049 dev_unlock(); 1050 1051 vhold(vp); 1052 vgone(vp); 1053 vdrop(vp); 1054 1055 VOP_UNLOCK(vp,0,curthread); 1056 loop: 1057 for (;;) { 1058 mtx_lock(&devfs_de_interlock); 1059 dev_lock(); 1060 vp2 = NULL; 1061 for (i = 0; i <= cdp->cdp_maxdirent; i++) { 1062 de = cdp->cdp_dirents[i]; 1063 if (de == NULL) 1064 continue; 1065 1066 vp2 = de->de_vnode; 1067 if (vp2 != NULL) { 1068 dev_unlock(); 1069 VI_LOCK(vp2); 1070 mtx_unlock(&devfs_de_interlock); 1071 if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK, 1072 curthread)) 1073 goto loop; 1074 vhold(vp2); 1075 vgone(vp2); 1076 vdrop(vp2); 1077 vput(vp2); 1078 break; 1079 } 1080 } 1081 if (vp2 != NULL) { 1082 continue; 1083 } 1084 dev_unlock(); 1085 mtx_unlock(&devfs_de_interlock); 1086 break; 1087 } 1088 dev_lock(); 1089 cdp->cdp_inuse--; 1090 if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) { 1091 TAILQ_REMOVE(&cdevp_list, cdp, cdp_list); 1092 dev_unlock(); 1093 dev_rel(&cdp->cdp_c); 1094 } else 1095 dev_unlock(); 1096 1097 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread); 1098 return (0); 1099 } 1100 1101 static int 1102 devfs_rioctl(struct vop_ioctl_args *ap) 1103 { 1104 int error; 1105 struct devfs_mount *dmp; 1106 1107 dmp = VFSTODEVFS(ap->a_vp->v_mount); 1108 sx_xlock(&dmp->dm_lock); 1109 DEVFS_DMP_HOLD(dmp); 1110 devfs_populate(dmp); 1111 if (DEVFS_DMP_DROP(dmp)) { 1112 sx_xunlock(&dmp->dm_lock); 1113 devfs_unmount_final(dmp); 1114 return (ENOENT); 1115 } 1116 error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td); 1117 sx_xunlock(&dmp->dm_lock); 1118 return (error); 1119 } 1120 1121 static int 1122 devfs_rread(struct vop_read_args *ap) 1123 { 1124 1125 if (ap->a_vp->v_type != VDIR) 1126 return (EINVAL); 1127 return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL)); 1128 } 1129 1130 static int 1131 devfs_setattr(struct vop_setattr_args *ap) 1132 { 1133 struct devfs_dirent *de; 1134 struct vattr *vap; 1135 struct vnode *vp; 1136 int c, error; 1137 uid_t uid; 1138 gid_t gid; 1139 1140 vap = ap->a_vap; 1141 vp = ap->a_vp; 1142 if ((vap->va_type != VNON) || 1143 (vap->va_nlink != VNOVAL) || 1144 (vap->va_fsid != VNOVAL) || 1145 (vap->va_fileid != VNOVAL) || 1146 (vap->va_blocksize != VNOVAL) || 1147 (vap->va_flags != VNOVAL && vap->va_flags != 0) || 1148 (vap->va_rdev != VNOVAL) || 1149 ((int)vap->va_bytes != VNOVAL) || 1150 (vap->va_gen != VNOVAL)) { 1151 return (EINVAL); 1152 } 1153 1154 de = vp->v_data; 1155 if (vp->v_type == VDIR) 1156 de = de->de_dir; 1157 1158 error = c = 0; 1159 if (vap->va_uid == (uid_t)VNOVAL) 1160 uid = de->de_uid; 1161 else 1162 uid = vap->va_uid; 1163 if (vap->va_gid == (gid_t)VNOVAL) 1164 gid = de->de_gid; 1165 else 1166 gid = vap->va_gid; 1167 if (uid != de->de_uid || gid != de->de_gid) { 1168 if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || 1169 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) { 1170 error = priv_check_cred(ap->a_td->td_ucred, 1171 PRIV_VFS_CHOWN, SUSER_ALLOWJAIL); 1172 if (error) 1173 return (error); 1174 } 1175 de->de_uid = uid; 1176 de->de_gid = gid; 1177 c = 1; 1178 } 1179 1180 if (vap->va_mode != (mode_t)VNOVAL) { 1181 if (ap->a_cred->cr_uid != de->de_uid) { 1182 error = priv_check_cred(ap->a_td->td_ucred, 1183 PRIV_VFS_ADMIN, SUSER_ALLOWJAIL); 1184 if (error) 1185 return (error); 1186 } 1187 de->de_mode = vap->va_mode; 1188 c = 1; 1189 } 1190 1191 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { 1192 /* See the comment in ufs_vnops::ufs_setattr(). */ 1193 if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)) && 1194 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || 1195 (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td)))) 1196 return (error); 1197 if (vap->va_atime.tv_sec != VNOVAL) { 1198 if (vp->v_type == VCHR) 1199 vp->v_rdev->si_atime = vap->va_atime; 1200 else 1201 de->de_atime = vap->va_atime; 1202 } 1203 if (vap->va_mtime.tv_sec != VNOVAL) { 1204 if (vp->v_type == VCHR) 1205 vp->v_rdev->si_mtime = vap->va_mtime; 1206 else 1207 de->de_mtime = vap->va_mtime; 1208 } 1209 c = 1; 1210 } 1211 1212 if (c) { 1213 if (vp->v_type == VCHR) 1214 vfs_timestamp(&vp->v_rdev->si_ctime); 1215 else 1216 vfs_timestamp(&de->de_mtime); 1217 } 1218 return (0); 1219 } 1220 1221 #ifdef MAC 1222 static int 1223 devfs_setlabel(struct vop_setlabel_args *ap) 1224 { 1225 struct vnode *vp; 1226 struct devfs_dirent *de; 1227 1228 vp = ap->a_vp; 1229 de = vp->v_data; 1230 1231 mac_relabel_vnode(ap->a_cred, vp, ap->a_label); 1232 mac_update_devfsdirent(vp->v_mount, de, vp); 1233 1234 return (0); 1235 } 1236 #endif 1237 1238 static int 1239 devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td) 1240 { 1241 1242 return (vnops.fo_stat(fp, sb, cred, td)); 1243 } 1244 1245 static int 1246 devfs_symlink(struct vop_symlink_args *ap) 1247 { 1248 int i, error; 1249 struct devfs_dirent *dd; 1250 struct devfs_dirent *de; 1251 struct devfs_mount *dmp; 1252 struct thread *td; 1253 1254 td = ap->a_cnp->cn_thread; 1255 KASSERT(td == curthread, ("devfs_symlink: td != curthread")); 1256 1257 error = priv_check(td, PRIV_DEVFS_SYMLINK); 1258 if (error) 1259 return(error); 1260 dmp = VFSTODEVFS(ap->a_dvp->v_mount); 1261 dd = ap->a_dvp->v_data; 1262 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen); 1263 de->de_uid = 0; 1264 de->de_gid = 0; 1265 de->de_mode = 0755; 1266 de->de_inode = alloc_unr(devfs_inos); 1267 de->de_dirent->d_type = DT_LNK; 1268 i = strlen(ap->a_target) + 1; 1269 de->de_symlink = malloc(i, M_DEVFS, M_WAITOK); 1270 bcopy(ap->a_target, de->de_symlink, i); 1271 sx_xlock(&dmp->dm_lock); 1272 #ifdef MAC 1273 mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); 1274 #endif 1275 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); 1276 return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td)); 1277 } 1278 1279 /* ARGSUSED */ 1280 static int 1281 devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td) 1282 { 1283 struct cdev *dev; 1284 int error, ioflag, resid; 1285 struct cdevsw *dsw; 1286 1287 error = devfs_fp_check(fp, &dev, &dsw); 1288 if (error) 1289 return (error); 1290 KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); 1291 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC); 1292 if (ioflag & O_DIRECT) 1293 ioflag |= IO_DIRECT; 1294 if ((flags & FOF_OFFSET) == 0) 1295 uio->uio_offset = fp->f_offset; 1296 1297 resid = uio->uio_resid; 1298 1299 error = dsw->d_write(dev, uio, ioflag); 1300 if (uio->uio_resid != resid || (error == 0 && resid != 0)) { 1301 vfs_timestamp(&dev->si_ctime); 1302 dev->si_mtime = dev->si_ctime; 1303 } 1304 dev_relthread(dev); 1305 1306 if ((flags & FOF_OFFSET) == 0) 1307 fp->f_offset = uio->uio_offset; 1308 fp->f_nextoff = uio->uio_offset; 1309 return (error); 1310 } 1311 1312 dev_t 1313 dev2udev(struct cdev *x) 1314 { 1315 if (x == NULL) 1316 return (NODEV); 1317 return (x->si_priv->cdp_inode); 1318 } 1319 1320 static struct fileops devfs_ops_f = { 1321 .fo_read = devfs_read_f, 1322 .fo_write = devfs_write_f, 1323 .fo_ioctl = devfs_ioctl_f, 1324 .fo_poll = devfs_poll_f, 1325 .fo_kqfilter = devfs_kqfilter_f, 1326 .fo_stat = devfs_stat_f, 1327 .fo_close = devfs_close_f, 1328 .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE 1329 }; 1330 1331 static struct vop_vector devfs_vnodeops = { 1332 .vop_default = &default_vnodeops, 1333 1334 .vop_access = devfs_access, 1335 .vop_getattr = devfs_getattr, 1336 .vop_ioctl = devfs_rioctl, 1337 .vop_lookup = devfs_lookup, 1338 .vop_mknod = devfs_mknod, 1339 .vop_pathconf = devfs_pathconf, 1340 .vop_read = devfs_rread, 1341 .vop_readdir = devfs_readdir, 1342 .vop_readlink = devfs_readlink, 1343 .vop_reclaim = devfs_reclaim, 1344 .vop_remove = devfs_remove, 1345 .vop_revoke = devfs_revoke, 1346 .vop_setattr = devfs_setattr, 1347 #ifdef MAC 1348 .vop_setlabel = devfs_setlabel, 1349 #endif 1350 .vop_symlink = devfs_symlink, 1351 }; 1352 1353 static struct vop_vector devfs_specops = { 1354 .vop_default = &default_vnodeops, 1355 1356 .vop_access = devfs_access, 1357 .vop_advlock = devfs_advlock, 1358 .vop_bmap = VOP_PANIC, 1359 .vop_close = devfs_close, 1360 .vop_create = VOP_PANIC, 1361 .vop_fsync = devfs_fsync, 1362 .vop_getattr = devfs_getattr, 1363 .vop_lease = VOP_NULL, 1364 .vop_link = VOP_PANIC, 1365 .vop_mkdir = VOP_PANIC, 1366 .vop_mknod = VOP_PANIC, 1367 .vop_open = devfs_open, 1368 .vop_pathconf = devfs_pathconf, 1369 .vop_print = devfs_print, 1370 .vop_read = VOP_PANIC, 1371 .vop_readdir = VOP_PANIC, 1372 .vop_readlink = VOP_PANIC, 1373 .vop_reallocblks = VOP_PANIC, 1374 .vop_reclaim = devfs_reclaim, 1375 .vop_remove = devfs_remove, 1376 .vop_rename = VOP_PANIC, 1377 .vop_revoke = devfs_revoke, 1378 .vop_rmdir = VOP_PANIC, 1379 .vop_setattr = devfs_setattr, 1380 #ifdef MAC 1381 .vop_setlabel = devfs_setlabel, 1382 #endif 1383 .vop_strategy = VOP_PANIC, 1384 .vop_symlink = VOP_PANIC, 1385 .vop_write = VOP_PANIC, 1386 }; 1387 1388 /* 1389 * Our calling convention to the device drivers used to be that we passed 1390 * vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_ 1391 * flags instead since that's what open(), close() and ioctl() takes and 1392 * we don't really want vnode.h in device drivers. 1393 * We solved the source compatibility by redefining some vnode flags to 1394 * be the same as the fcntl ones and by sending down the bitwise OR of 1395 * the respective fcntl/vnode flags. These CTASSERTS make sure nobody 1396 * pulls the rug out under this. 1397 */ 1398 CTASSERT(O_NONBLOCK == IO_NDELAY); 1399 CTASSERT(O_FSYNC == IO_SYNC); 1400