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