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