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.
7 * This code is derived from software donated to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
31 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95
32 * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43
39 * remove empty directories
45 #include <sys/param.h>
46 #include <sys/systm.h>
48 #include <sys/dirent.h>
49 #include <sys/fcntl.h>
51 #include <sys/filedesc.h>
52 #include <sys/filio.h>
53 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #include <sys/mount.h>
57 #include <sys/namei.h>
63 #include <sys/ttycom.h>
64 #include <sys/unistd.h>
65 #include <sys/vnode.h>
67 static struct vop_vector devfs_vnodeops;
68 static struct vop_vector devfs_specops;
69 static struct fileops devfs_ops_f;
71 #include <fs/devfs/devfs.h>
72 #include <fs/devfs/devfs_int.h>
74 #include <security/mac/mac_framework.h>
76 static MALLOC_DEFINE(M_CDEVPDATA, "DEVFSP", "Metainfo for cdev-fp data");
78 struct mtx devfs_de_interlock;
79 MTX_SYSINIT(devfs_de_interlock, &devfs_de_interlock, "devfs interlock", MTX_DEF);
80 struct sx clone_drain_lock;
81 SX_SYSINIT(clone_drain_lock, &clone_drain_lock, "clone events drain lock");
82 struct mtx cdevpriv_mtx;
83 MTX_SYSINIT(cdevpriv_mtx, &cdevpriv_mtx, "cdevpriv lock", MTX_DEF);
86 devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp)
89 *dswp = devvn_refthread(fp->f_vnode, devp);
90 if (*devp != fp->f_data) {
95 KASSERT((*devp)->si_refcount > 0,
96 ("devfs: un-referenced struct cdev *(%s)", devtoname(*devp)));
99 curthread->td_fpop = fp;
104 devfs_get_cdevpriv(void **datap)
107 struct cdev_privdata *p;
110 fp = curthread->td_fpop;
116 *datap = p->cdpd_data;
123 devfs_set_cdevpriv(void *priv, cdevpriv_dtr_t priv_dtr)
126 struct cdev_priv *cdp;
127 struct cdev_privdata *p;
130 fp = curthread->td_fpop;
133 cdp = ((struct cdev *)fp->f_data)->si_priv;
134 p = malloc(sizeof(struct cdev_privdata), M_CDEVPDATA, M_WAITOK);
136 p->cdpd_dtr = priv_dtr;
138 mtx_lock(&cdevpriv_mtx);
139 if (fp->f_cdevpriv == NULL) {
140 LIST_INSERT_HEAD(&cdp->cdp_fdpriv, p, cdpd_list);
142 mtx_unlock(&cdevpriv_mtx);
145 mtx_unlock(&cdevpriv_mtx);
146 free(p, M_CDEVPDATA);
153 devfs_destroy_cdevpriv(struct cdev_privdata *p)
156 mtx_assert(&cdevpriv_mtx, MA_OWNED);
157 p->cdpd_fp->f_cdevpriv = NULL;
158 LIST_REMOVE(p, cdpd_list);
159 mtx_unlock(&cdevpriv_mtx);
160 (p->cdpd_dtr)(p->cdpd_data);
161 free(p, M_CDEVPDATA);
165 devfs_fpdrop(struct file *fp)
167 struct cdev_privdata *p;
169 mtx_lock(&cdevpriv_mtx);
170 if ((p = fp->f_cdevpriv) == NULL) {
171 mtx_unlock(&cdevpriv_mtx);
174 devfs_destroy_cdevpriv(p);
178 devfs_clear_cdevpriv(void)
182 fp = curthread->td_fpop;
189 * Construct the fully qualified path name relative to the mountpoint
192 devfs_fqpn(char *buf, struct vnode *dvp, struct componentname *cnp)
195 struct devfs_dirent *de, *dd;
196 struct devfs_mount *dmp;
198 dmp = VFSTODEVFS(dvp->v_mount);
202 i -= cnp->cn_namelen;
205 bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen);
207 while (de != dmp->dm_rootdir) {
212 i -= de->de_dirent->d_namlen;
215 bcopy(de->de_dirent->d_name, buf + i,
216 de->de_dirent->d_namlen);
217 de = TAILQ_FIRST(&de->de_dlist); /* "." */
218 de = TAILQ_NEXT(de, de_list); /* ".." */
225 devfs_allocv_drop_refs(int drop_dm_lock, struct devfs_mount *dmp,
226 struct devfs_dirent *de)
231 if (de->de_flags & DE_DOOMED)
233 if (DEVFS_DE_DROP(de)) {
234 KASSERT(not_found == 1, ("DEVFS de dropped but not doomed"));
235 devfs_dirent_free(de);
237 if (DEVFS_DMP_DROP(dmp)) {
238 KASSERT(not_found == 1,
239 ("DEVFS mount struct freed before dirent"));
241 sx_xunlock(&dmp->dm_lock);
242 devfs_unmount_final(dmp);
244 if (not_found == 1 || (drop_dm_lock && not_found != 2))
245 sx_unlock(&dmp->dm_lock);
250 devfs_insmntque_dtr(struct vnode *vp, void *arg)
252 struct devfs_dirent *de;
254 de = (struct devfs_dirent *)arg;
255 mtx_lock(&devfs_de_interlock);
258 mtx_unlock(&devfs_de_interlock);
264 * devfs_allocv shall be entered with dmp->dm_lock held, and it drops
268 devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td)
273 struct devfs_mount *dmp;
275 KASSERT(td == curthread, ("devfs_allocv: td != curthread"));
276 dmp = VFSTODEVFS(mp);
277 if (de->de_flags & DE_DOOMED) {
278 sx_xunlock(&dmp->dm_lock);
283 mtx_lock(&devfs_de_interlock);
287 mtx_unlock(&devfs_de_interlock);
288 sx_xunlock(&dmp->dm_lock);
289 error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
290 sx_xlock(&dmp->dm_lock);
291 if (devfs_allocv_drop_refs(0, dmp, de)) {
297 sx_xunlock(&dmp->dm_lock);
300 sx_xunlock(&dmp->dm_lock);
304 mtx_unlock(&devfs_de_interlock);
305 if (de->de_dirent->d_type == DT_CHR) {
306 if (!(de->de_cdp->cdp_flags & CDP_ACTIVE)) {
307 devfs_allocv_drop_refs(1, dmp, de);
310 dev = &de->de_cdp->cdp_c;
314 error = getnewvnode("devfs", mp, &devfs_vnodeops, &vp);
316 devfs_allocv_drop_refs(1, dmp, de);
317 printf("devfs_allocv: failed to allocate new vnode\n");
321 if (de->de_dirent->d_type == DT_CHR) {
326 /* XXX: v_rdev should be protect by vnode lock */
328 KASSERT(vp->v_usecount == 1,
329 ("%s %d (%d)\n", __func__, __LINE__, vp->v_usecount));
330 dev->si_usecount += vp->v_usecount;
333 vp->v_op = &devfs_specops;
334 } else if (de->de_dirent->d_type == DT_DIR) {
336 } else if (de->de_dirent->d_type == DT_LNK) {
341 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
342 mtx_lock(&devfs_de_interlock);
345 mtx_unlock(&devfs_de_interlock);
346 error = insmntque1(vp, mp, devfs_insmntque_dtr, de);
348 (void) devfs_allocv_drop_refs(1, dmp, de);
351 if (devfs_allocv_drop_refs(0, dmp, de)) {
356 mac_associate_vnode_devfs(mp, de, vp);
358 sx_xunlock(&dmp->dm_lock);
364 devfs_access(struct vop_access_args *ap)
366 struct vnode *vp = ap->a_vp;
367 struct devfs_dirent *de;
371 if (vp->v_type == VDIR)
374 error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
375 ap->a_mode, ap->a_cred, NULL);
380 /* We do, however, allow access to the controlling terminal */
381 if (!(ap->a_td->td_proc->p_flag & P_CONTROLT))
383 if (ap->a_td->td_proc->p_session->s_ttyvp == de->de_vnode)
390 devfs_close(struct vop_close_args *ap)
392 struct vnode *vp = ap->a_vp, *oldvp;
393 struct thread *td = ap->a_td;
394 struct cdev *dev = vp->v_rdev;
396 int vp_locked, error;
399 * Hack: a tty device that is a controlling terminal
400 * has a reference from the session structure.
401 * We cannot easily tell that a character device is
402 * a controlling terminal, unless it is the closing
403 * process' controlling terminal. In that case,
404 * if the reference count is 2 (this last descriptor
405 * plus the session), release the reference from the session.
408 sx_xlock(&proctree_lock);
409 if (td && vp == td->td_proc->p_session->s_ttyvp) {
410 SESS_LOCK(td->td_proc->p_session);
412 if (count_dev(dev) == 2 && (vp->v_iflag & VI_DOOMED) == 0) {
413 td->td_proc->p_session->s_ttyvp = NULL;
417 SESS_UNLOCK(td->td_proc->p_session);
419 sx_xunlock(&proctree_lock);
423 * We do not want to really close the device if it
424 * is still in use unless we are trying to close it
425 * forcibly. Since every use (buffer, vnode, swap, cmap)
426 * holds a reference to the vnode, and because we mark
427 * any other vnodes that alias this device, when the
428 * sum of the reference counts on all the aliased
429 * vnodes descends to one, we are on last close.
431 dsw = dev_refthread(dev);
435 if (vp->v_iflag & VI_DOOMED) {
437 } else if (dsw->d_flags & D_TRACKCLOSE) {
438 /* Keep device updated on status. */
439 } else if (count_dev(dev) > 1) {
446 vp_locked = VOP_ISLOCKED(vp, td);
447 VOP_UNLOCK(vp, 0, td);
448 KASSERT(dev->si_refcount > 0,
449 ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
450 if (!(dsw->d_flags & D_NEEDGIANT)) {
452 error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
455 error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
458 vn_lock(vp, vp_locked | LK_RETRY, td);
464 devfs_close_f(struct file *fp, struct thread *td)
471 error = vnops.fo_close(fp, td);
477 devfs_fsync(struct vop_fsync_args *ap)
481 struct devfs_dirent *de;
483 if (!vn_isdisk(ap->a_vp, &error)) {
484 bo = &ap->a_vp->v_bufobj;
485 de = ap->a_vp->v_data;
486 if (error == ENXIO && bo->bo_dirty.bv_cnt > 0) {
487 printf("Device %s went missing before all of the data "
488 "could be written to it; expect data loss.\n",
489 de->de_dirent->d_name);
491 error = vop_stdfsync(ap);
492 if (bo->bo_dirty.bv_cnt != 0 || error != 0)
493 panic("devfs_fsync: vop_stdfsync failed.");
499 return (vop_stdfsync(ap));
503 devfs_getattr(struct vop_getattr_args *ap)
505 struct vnode *vp = ap->a_vp;
506 struct vattr *vap = ap->a_vap;
508 struct devfs_dirent *de;
512 KASSERT(de != NULL, ("Null dirent in devfs_getattr vp=%p", vp));
513 if (vp->v_type == VDIR) {
516 ("Null dir dirent in devfs_getattr vp=%p", vp));
518 vap->va_uid = de->de_uid;
519 vap->va_gid = de->de_gid;
520 vap->va_mode = de->de_mode;
521 if (vp->v_type == VLNK)
522 vap->va_size = strlen(de->de_symlink);
523 else if (vp->v_type == VDIR)
524 vap->va_size = vap->va_bytes = DEV_BSIZE;
527 if (vp->v_type != VDIR)
529 vap->va_blocksize = DEV_BSIZE;
530 vap->va_type = vp->v_type;
534 if ((aa).tv_sec <= 3600) { \
535 (aa).tv_sec = boottime.tv_sec; \
536 (aa).tv_nsec = boottime.tv_usec * 1000; \
540 if (vp->v_type != VCHR) {
542 vap->va_atime = de->de_atime;
544 vap->va_mtime = de->de_mtime;
546 vap->va_ctime = de->de_ctime;
550 vap->va_atime = dev->si_atime;
552 vap->va_mtime = dev->si_mtime;
554 vap->va_ctime = dev->si_ctime;
556 vap->va_rdev = dev->si_priv->cdp_inode;
561 vap->va_nlink = de->de_links;
562 vap->va_fileid = de->de_inode;
569 devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td)
577 struct fiodgname_arg *fgn;
581 error = devfs_fp_check(fp, &dev, &dsw);
585 if (com == FIODTYPE) {
586 *(int *)data = dsw->d_flags & D_TYPEMASK;
590 } else if (com == FIODGNAME) {
597 error = copyout(p, fgn->buf, i);
602 error = dsw->d_ioctl(dev, com, data, fp->f_flag, td);
605 if (error == ENOIOCTL)
607 if (error == 0 && com == TIOCSCTTY) {
610 /* Do nothing if reassigning same control tty */
611 sx_slock(&proctree_lock);
612 if (td->td_proc->p_session->s_ttyvp == vp) {
613 sx_sunlock(&proctree_lock);
617 mtx_lock(&Giant); /* XXX TTY */
619 vpold = td->td_proc->p_session->s_ttyvp;
621 SESS_LOCK(td->td_proc->p_session);
622 td->td_proc->p_session->s_ttyvp = vp;
623 SESS_UNLOCK(td->td_proc->p_session);
625 sx_sunlock(&proctree_lock);
627 /* Get rid of reference to old control tty */
630 mtx_unlock(&Giant); /* XXX TTY */
637 devfs_kqfilter_f(struct file *fp, struct knote *kn)
647 error = devfs_fp_check(fp, &dev, &dsw);
650 error = dsw->d_kqfilter(dev, kn);
657 devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
659 struct componentname *cnp;
660 struct vnode *dvp, **vpp;
662 struct devfs_dirent *de, *dd;
663 struct devfs_dirent **dde;
664 struct devfs_mount *dmp;
666 int error, flags, nameiop;
667 char specname[SPECNAMELEN + 1], *pname;
672 pname = cnp->cn_nameptr;
674 flags = cnp->cn_flags;
675 nameiop = cnp->cn_nameiop;
676 dmp = VFSTODEVFS(dvp->v_mount);
680 if ((flags & ISLASTCN) && nameiop == RENAME)
683 if (dvp->v_type != VDIR)
686 if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT))
689 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
693 if (cnp->cn_namelen == 1 && *pname == '.') {
694 if ((flags & ISLASTCN) && nameiop != LOOKUP)
701 if (flags & ISDOTDOT) {
702 if ((flags & ISLASTCN) && nameiop != LOOKUP)
704 VOP_UNLOCK(dvp, 0, td);
705 de = TAILQ_FIRST(&dd->de_dlist); /* "." */
706 de = TAILQ_NEXT(de, de_list); /* ".." */
708 error = devfs_allocv(de, dvp->v_mount, vpp, td);
710 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
716 if (DEVFS_DMP_DROP(dmp)) {
718 sx_xunlock(&dmp->dm_lock);
719 devfs_unmount_final(dmp);
723 de = devfs_find(dd, cnp->cn_nameptr, cnp->cn_namelen);
724 while (de == NULL) { /* While(...) so we can use break */
726 if (nameiop == DELETE)
730 * OK, we didn't have an entry for the name we were asked for
731 * so we try to see if anybody can create it on demand.
733 pname = devfs_fqpn(specname, dvp, cnp);
739 sx_xunlock(&dmp->dm_lock);
740 sx_slock(&clone_drain_lock);
741 EVENTHANDLER_INVOKE(dev_clone,
742 td->td_ucred, pname, strlen(pname), &cdev);
743 sx_sunlock(&clone_drain_lock);
744 sx_xlock(&dmp->dm_lock);
745 if (DEVFS_DMP_DROP(dmp)) {
747 sx_xunlock(&dmp->dm_lock);
748 devfs_unmount_final(dmp);
756 if (DEVFS_DMP_DROP(dmp)) {
758 sx_xunlock(&dmp->dm_lock);
759 devfs_unmount_final(dmp);
764 dde = &cdev->si_priv->cdp_dirents[dmp->dm_idx];
765 if (dde != NULL && *dde != NULL)
772 if (de == NULL || de->de_flags & DE_WHITEOUT) {
773 if ((nameiop == CREATE || nameiop == RENAME) &&
774 (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
775 cnp->cn_flags |= SAVENAME;
776 return (EJUSTRETURN);
781 if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
782 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
791 error = devfs_allocv(de, dvp->v_mount, vpp, td);
797 devfs_lookup(struct vop_lookup_args *ap)
800 struct devfs_mount *dmp;
803 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
805 sx_xlock(&dmp->dm_lock);
806 j = devfs_lookupx(ap, &dm_unlock);
808 sx_xunlock(&dmp->dm_lock);
813 devfs_mknod(struct vop_mknod_args *ap)
815 struct componentname *cnp;
816 struct vnode *dvp, **vpp;
818 struct devfs_dirent *dd, *de;
819 struct devfs_mount *dmp;
823 * The only type of node we should be creating here is a
824 * character device, for anything else return EOPNOTSUPP.
826 if (ap->a_vap->va_type != VCHR)
829 dmp = VFSTODEVFS(dvp->v_mount);
837 sx_xlock(&dmp->dm_lock);
838 TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
839 if (cnp->cn_namelen != de->de_dirent->d_namlen)
841 if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
842 de->de_dirent->d_namlen) != 0)
844 if (de->de_flags & DE_WHITEOUT)
850 de->de_flags &= ~DE_WHITEOUT;
851 error = devfs_allocv(de, dvp->v_mount, vpp, td);
854 sx_xunlock(&dmp->dm_lock);
860 devfs_open(struct vop_open_args *ap)
862 struct thread *td = ap->a_td;
863 struct vnode *vp = ap->a_vp;
864 struct cdev *dev = vp->v_rdev;
865 struct file *fp = ap->a_fp;
870 if (vp->v_type == VBLK)
876 /* Make this field valid before any I/O in d_open. */
877 if (dev->si_iosize_max == 0)
878 dev->si_iosize_max = DFLTPHYS;
880 dsw = dev_refthread(dev);
884 /* XXX: Special casing of ttys for deadfs. Probably redundant. */
885 if (dsw->d_flags & D_TTY)
886 vp->v_vflag |= VV_ISTTY;
888 VOP_UNLOCK(vp, 0, td);
897 if(!(dsw->d_flags & D_NEEDGIANT)) {
899 if (dsw->d_fdopen != NULL)
900 error = dsw->d_fdopen(dev, ap->a_mode, td, fp);
902 error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
905 if (dsw->d_fdopen != NULL)
906 error = dsw->d_fdopen(dev, ap->a_mode, td, fp);
908 error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
912 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
919 #if 0 /* /dev/console */
921 ("Could not vnode bypass device on NULL fp"));
927 KASSERT(fp->f_ops == &badfileops,
928 ("Could not vnode bypass device on fdops %p", fp->f_ops));
929 fp->f_ops = &devfs_ops_f;
935 devfs_pathconf(struct vop_pathconf_args *ap)
938 switch (ap->a_name) {
939 case _PC_MAC_PRESENT:
942 * If MAC is enabled, devfs automatically supports
943 * trivial non-persistant label storage.
951 return (vop_stdpathconf(ap));
958 devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
966 error = devfs_fp_check(fp, &dev, &dsw);
968 return (poll_no_poll(events));
969 error = dsw->d_poll(dev, events, td);
976 * Print out the contents of a special device vnode.
979 devfs_print(struct vop_print_args *ap)
982 printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev));
988 devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
991 int ioflag, error, resid;
996 error = devfs_fp_check(fp, &dev, &dsw);
999 resid = uio->uio_resid;
1000 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT);
1001 if (ioflag & O_DIRECT)
1002 ioflag |= IO_DIRECT;
1004 if ((flags & FOF_OFFSET) == 0)
1005 uio->uio_offset = fp->f_offset;
1007 error = dsw->d_read(dev, uio, ioflag);
1008 if (uio->uio_resid != resid || (error == 0 && resid != 0))
1009 vfs_timestamp(&dev->si_atime);
1013 if ((flags & FOF_OFFSET) == 0)
1014 fp->f_offset = uio->uio_offset;
1015 fp->f_nextoff = uio->uio_offset;
1020 devfs_readdir(struct vop_readdir_args *ap)
1025 struct devfs_dirent *dd;
1026 struct devfs_dirent *de;
1027 struct devfs_mount *dmp;
1029 int *tmp_ncookies = NULL;
1031 if (ap->a_vp->v_type != VDIR)
1035 if (uio->uio_offset < 0)
1039 * XXX: This is a temporary hack to get around this filesystem not
1040 * supporting cookies. We store the location of the ncookies pointer
1041 * in a temporary variable before calling vfs_subr.c:vfs_read_dirent()
1042 * and set the number of cookies to 0. We then set the pointer to
1043 * NULL so that vfs_read_dirent doesn't try to call realloc() on
1044 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies
1045 * pointer to its original location before returning to the caller.
1047 if (ap->a_ncookies != NULL) {
1048 tmp_ncookies = ap->a_ncookies;
1049 *ap->a_ncookies = 0;
1050 ap->a_ncookies = NULL;
1053 dmp = VFSTODEVFS(ap->a_vp->v_mount);
1054 sx_xlock(&dmp->dm_lock);
1055 DEVFS_DMP_HOLD(dmp);
1056 devfs_populate(dmp);
1057 if (DEVFS_DMP_DROP(dmp)) {
1058 sx_xunlock(&dmp->dm_lock);
1059 devfs_unmount_final(dmp);
1060 if (tmp_ncookies != NULL)
1061 ap->a_ncookies = tmp_ncookies;
1065 de = ap->a_vp->v_data;
1067 oldoff = uio->uio_offset;
1068 TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
1069 KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
1070 if (dd->de_flags & DE_WHITEOUT)
1072 if (dd->de_dirent->d_type == DT_DIR)
1077 if (dp->d_reclen > uio->uio_resid)
1079 dp->d_fileno = de->de_inode;
1080 if (off >= uio->uio_offset) {
1081 error = vfs_read_dirent(ap, dp, off);
1085 off += dp->d_reclen;
1087 sx_xunlock(&dmp->dm_lock);
1088 uio->uio_offset = off;
1091 * Restore ap->a_ncookies if it wasn't originally NULL in the first
1094 if (tmp_ncookies != NULL)
1095 ap->a_ncookies = tmp_ncookies;
1101 devfs_readlink(struct vop_readlink_args *ap)
1103 struct devfs_dirent *de;
1105 de = ap->a_vp->v_data;
1106 return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio));
1110 devfs_reclaim(struct vop_reclaim_args *ap)
1112 struct vnode *vp = ap->a_vp;
1113 struct devfs_dirent *de;
1116 mtx_lock(&devfs_de_interlock);
1119 de->de_vnode = NULL;
1122 mtx_unlock(&devfs_de_interlock);
1124 vnode_destroy_vobject(vp);
1137 dev->si_usecount -= vp->v_usecount;
1145 devfs_remove(struct vop_remove_args *ap)
1147 struct vnode *vp = ap->a_vp;
1148 struct devfs_dirent *dd;
1149 struct devfs_dirent *de;
1150 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
1152 sx_xlock(&dmp->dm_lock);
1153 dd = ap->a_dvp->v_data;
1155 if (de->de_cdp == NULL) {
1156 TAILQ_REMOVE(&dd->de_dlist, de, de_list);
1157 devfs_delete(dmp, de, 1);
1159 de->de_flags |= DE_WHITEOUT;
1161 sx_xunlock(&dmp->dm_lock);
1166 * Revoke is called on a tty when a terminal session ends. The vnode
1167 * is orphaned by setting v_op to deadfs so we need to let go of it
1168 * as well so that we create a new one next time around.
1172 devfs_revoke(struct vop_revoke_args *ap)
1174 struct vnode *vp = ap->a_vp, *vp2;
1176 struct cdev_priv *cdp;
1177 struct devfs_dirent *de;
1180 KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
1193 VOP_UNLOCK(vp,0,curthread);
1196 mtx_lock(&devfs_de_interlock);
1199 for (i = 0; i <= cdp->cdp_maxdirent; i++) {
1200 de = cdp->cdp_dirents[i];
1208 mtx_unlock(&devfs_de_interlock);
1209 if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK,
1223 mtx_unlock(&devfs_de_interlock);
1228 if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) {
1229 TAILQ_REMOVE(&cdevp_list, cdp, cdp_list);
1231 dev_rel(&cdp->cdp_c);
1235 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
1240 devfs_rioctl(struct vop_ioctl_args *ap)
1243 struct devfs_mount *dmp;
1245 dmp = VFSTODEVFS(ap->a_vp->v_mount);
1246 sx_xlock(&dmp->dm_lock);
1247 DEVFS_DMP_HOLD(dmp);
1248 devfs_populate(dmp);
1249 if (DEVFS_DMP_DROP(dmp)) {
1250 sx_xunlock(&dmp->dm_lock);
1251 devfs_unmount_final(dmp);
1254 error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td);
1255 sx_xunlock(&dmp->dm_lock);
1260 devfs_rread(struct vop_read_args *ap)
1263 if (ap->a_vp->v_type != VDIR)
1265 return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL));
1269 devfs_setattr(struct vop_setattr_args *ap)
1271 struct devfs_dirent *de;
1280 if ((vap->va_type != VNON) ||
1281 (vap->va_nlink != VNOVAL) ||
1282 (vap->va_fsid != VNOVAL) ||
1283 (vap->va_fileid != VNOVAL) ||
1284 (vap->va_blocksize != VNOVAL) ||
1285 (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1286 (vap->va_rdev != VNOVAL) ||
1287 ((int)vap->va_bytes != VNOVAL) ||
1288 (vap->va_gen != VNOVAL)) {
1293 if (vp->v_type == VDIR)
1297 if (vap->va_uid == (uid_t)VNOVAL)
1301 if (vap->va_gid == (gid_t)VNOVAL)
1305 if (uid != de->de_uid || gid != de->de_gid) {
1306 if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
1307 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) {
1308 error = priv_check(ap->a_td, PRIV_VFS_CHOWN);
1317 if (vap->va_mode != (mode_t)VNOVAL) {
1318 if (ap->a_cred->cr_uid != de->de_uid) {
1319 error = priv_check(ap->a_td, PRIV_VFS_ADMIN);
1323 de->de_mode = vap->va_mode;
1327 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1328 /* See the comment in ufs_vnops::ufs_setattr(). */
1329 if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)) &&
1330 ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
1331 (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td))))
1333 if (vap->va_atime.tv_sec != VNOVAL) {
1334 if (vp->v_type == VCHR)
1335 vp->v_rdev->si_atime = vap->va_atime;
1337 de->de_atime = vap->va_atime;
1339 if (vap->va_mtime.tv_sec != VNOVAL) {
1340 if (vp->v_type == VCHR)
1341 vp->v_rdev->si_mtime = vap->va_mtime;
1343 de->de_mtime = vap->va_mtime;
1349 if (vp->v_type == VCHR)
1350 vfs_timestamp(&vp->v_rdev->si_ctime);
1352 vfs_timestamp(&de->de_mtime);
1359 devfs_setlabel(struct vop_setlabel_args *ap)
1362 struct devfs_dirent *de;
1367 mac_relabel_vnode(ap->a_cred, vp, ap->a_label);
1368 mac_update_devfs(vp->v_mount, de, vp);
1375 devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
1378 return (vnops.fo_stat(fp, sb, cred, td));
1382 devfs_symlink(struct vop_symlink_args *ap)
1385 struct devfs_dirent *dd;
1386 struct devfs_dirent *de;
1387 struct devfs_mount *dmp;
1390 td = ap->a_cnp->cn_thread;
1391 KASSERT(td == curthread, ("devfs_symlink: td != curthread"));
1393 error = priv_check(td, PRIV_DEVFS_SYMLINK);
1396 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
1397 dd = ap->a_dvp->v_data;
1398 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
1402 de->de_inode = alloc_unr(devfs_inos);
1403 de->de_dirent->d_type = DT_LNK;
1404 i = strlen(ap->a_target) + 1;
1405 de->de_symlink = malloc(i, M_DEVFS, M_WAITOK);
1406 bcopy(ap->a_target, de->de_symlink, i);
1407 sx_xlock(&dmp->dm_lock);
1409 mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de);
1411 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list);
1412 return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td));
1417 devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
1420 int error, ioflag, resid;
1425 error = devfs_fp_check(fp, &dev, &dsw);
1428 KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
1429 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC);
1430 if (ioflag & O_DIRECT)
1431 ioflag |= IO_DIRECT;
1432 if ((flags & FOF_OFFSET) == 0)
1433 uio->uio_offset = fp->f_offset;
1435 resid = uio->uio_resid;
1437 error = dsw->d_write(dev, uio, ioflag);
1438 if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
1439 vfs_timestamp(&dev->si_ctime);
1440 dev->si_mtime = dev->si_ctime;
1445 if ((flags & FOF_OFFSET) == 0)
1446 fp->f_offset = uio->uio_offset;
1447 fp->f_nextoff = uio->uio_offset;
1452 dev2udev(struct cdev *x)
1456 return (x->si_priv->cdp_inode);
1459 static struct fileops devfs_ops_f = {
1460 .fo_read = devfs_read_f,
1461 .fo_write = devfs_write_f,
1462 .fo_ioctl = devfs_ioctl_f,
1463 .fo_poll = devfs_poll_f,
1464 .fo_kqfilter = devfs_kqfilter_f,
1465 .fo_stat = devfs_stat_f,
1466 .fo_close = devfs_close_f,
1467 .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
1470 static struct vop_vector devfs_vnodeops = {
1471 .vop_default = &default_vnodeops,
1473 .vop_access = devfs_access,
1474 .vop_getattr = devfs_getattr,
1475 .vop_ioctl = devfs_rioctl,
1476 .vop_lookup = devfs_lookup,
1477 .vop_mknod = devfs_mknod,
1478 .vop_pathconf = devfs_pathconf,
1479 .vop_read = devfs_rread,
1480 .vop_readdir = devfs_readdir,
1481 .vop_readlink = devfs_readlink,
1482 .vop_reclaim = devfs_reclaim,
1483 .vop_remove = devfs_remove,
1484 .vop_revoke = devfs_revoke,
1485 .vop_setattr = devfs_setattr,
1487 .vop_setlabel = devfs_setlabel,
1489 .vop_symlink = devfs_symlink,
1492 static struct vop_vector devfs_specops = {
1493 .vop_default = &default_vnodeops,
1495 .vop_access = devfs_access,
1496 .vop_bmap = VOP_PANIC,
1497 .vop_close = devfs_close,
1498 .vop_create = VOP_PANIC,
1499 .vop_fsync = devfs_fsync,
1500 .vop_getattr = devfs_getattr,
1501 .vop_lease = VOP_NULL,
1502 .vop_link = VOP_PANIC,
1503 .vop_mkdir = VOP_PANIC,
1504 .vop_mknod = VOP_PANIC,
1505 .vop_open = devfs_open,
1506 .vop_pathconf = devfs_pathconf,
1507 .vop_print = devfs_print,
1508 .vop_read = VOP_PANIC,
1509 .vop_readdir = VOP_PANIC,
1510 .vop_readlink = VOP_PANIC,
1511 .vop_reallocblks = VOP_PANIC,
1512 .vop_reclaim = devfs_reclaim,
1513 .vop_remove = devfs_remove,
1514 .vop_rename = VOP_PANIC,
1515 .vop_revoke = devfs_revoke,
1516 .vop_rmdir = VOP_PANIC,
1517 .vop_setattr = devfs_setattr,
1519 .vop_setlabel = devfs_setlabel,
1521 .vop_strategy = VOP_PANIC,
1522 .vop_symlink = VOP_PANIC,
1523 .vop_write = VOP_PANIC,
1527 * Our calling convention to the device drivers used to be that we passed
1528 * vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_
1529 * flags instead since that's what open(), close() and ioctl() takes and
1530 * we don't really want vnode.h in device drivers.
1531 * We solved the source compatibility by redefining some vnode flags to
1532 * be the same as the fcntl ones and by sending down the bitwise OR of
1533 * the respective fcntl/vnode flags. These CTASSERTS make sure nobody
1534 * pulls the rug out under this.
1536 CTASSERT(O_NONBLOCK == IO_NDELAY);
1537 CTASSERT(O_FSYNC == IO_SYNC);