Lines Matching +full:de +full:- +full:be

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2000-2004
5 * Poul-Henning Kamp. All rights reserved.
6 * Copyright (c) 1989, 1992-1993, 1995
10 * Jan-Simon Pendry.
18 * may be used to endorse or promote products derived from this software
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
80 static MALLOC_DEFINE(M_CDEVPDATA, "DEVFSP", "Metainfo for cdev-fp data");
106 if (tsp->tv_sec != ts) { in devfs_timestamp()
107 tsp->tv_sec = ts; in devfs_timestamp()
108 tsp->tv_nsec = 0; in devfs_timestamp()
117 *dswp = devvn_refthread(fp->f_vnode, devp, ref); in devfs_fp_check()
118 if (*dswp == NULL || *devp != fp->f_data) { in devfs_fp_check()
123 KASSERT((*devp)->si_refcount > 0, in devfs_fp_check()
124 ("devfs: un-referenced struct cdev *(%s)", devtoname(*devp))); in devfs_fp_check()
127 curthread->td_fpop = fp; in devfs_fp_check()
138 fp = curthread->td_fpop; in devfs_get_cdevpriv()
141 p = fp->f_cdevpriv; in devfs_get_cdevpriv()
144 *datap = p->cdpd_data; in devfs_get_cdevpriv()
158 fp = curthread->td_fpop; in devfs_set_cdevpriv()
161 cdp = cdev2priv((struct cdev *)fp->f_data); in devfs_set_cdevpriv()
163 p->cdpd_data = priv; in devfs_set_cdevpriv()
164 p->cdpd_dtr = priv_dtr; in devfs_set_cdevpriv()
165 p->cdpd_fp = fp; in devfs_set_cdevpriv()
167 if (fp->f_cdevpriv == NULL) { in devfs_set_cdevpriv()
168 LIST_INSERT_HEAD(&cdp->cdp_fdpriv, p, cdpd_list); in devfs_set_cdevpriv()
169 fp->f_cdevpriv = p; in devfs_set_cdevpriv()
191 LIST_FOREACH(p, &cdp->cdp_fdpriv, cdpd_list) { in devfs_foreach_cdevpriv()
192 error = cb(p->cdpd_data, arg); in devfs_foreach_cdevpriv()
205 KASSERT(p->cdpd_fp->f_cdevpriv == p, in devfs_destroy_cdevpriv()
206 ("devfs_destoy_cdevpriv %p != %p", p->cdpd_fp->f_cdevpriv, p)); in devfs_destroy_cdevpriv()
207 p->cdpd_fp->f_cdevpriv = NULL; in devfs_destroy_cdevpriv()
210 (p->cdpd_dtr)(p->cdpd_data); in devfs_destroy_cdevpriv()
220 if ((p = fp->f_cdevpriv) == NULL) { in devfs_fpdrop()
232 fp = curthread->td_fpop; in devfs_clear_cdevpriv()
241 struct devfs_dirent *de; in devfs_usecount_add() local
246 VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp); in devfs_usecount_add()
251 de = vp->v_data; in devfs_usecount_add()
252 dev = vp->v_rdev; in devfs_usecount_add()
253 MPASS(de != NULL); in devfs_usecount_add()
255 dev->si_usecount++; in devfs_usecount_add()
256 de->de_usecount++; in devfs_usecount_add()
265 struct devfs_dirent *de; in devfs_usecount_subl() local
270 VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp); in devfs_usecount_subl()
272 de = vp->v_data; in devfs_usecount_subl()
273 dev = vp->v_rdev; in devfs_usecount_subl()
274 if (de == NULL) in devfs_usecount_subl()
277 MPASS(de->de_usecount == 0); in devfs_usecount_subl()
280 if (dev->si_usecount < de->de_usecount) in devfs_usecount_subl()
283 __func__, dev, dev->si_usecount, de->de_usecount); in devfs_usecount_subl()
285 dev->si_usecount -= de->de_usecount; in devfs_usecount_subl()
286 de->de_usecount = 0; in devfs_usecount_subl()
288 if (de->de_usecount == 0) in devfs_usecount_subl()
291 dev->si_usecount--; in devfs_usecount_subl()
292 de->de_usecount--; in devfs_usecount_subl()
311 VNPASS(vp->v_type == VCHR, vp); in devfs_usecountl()
314 return (vp->v_rdev->si_usecount); in devfs_usecountl()
322 VNPASS(vp->v_type == VCHR, vp); in devfs_usecount()
348 * On success devfs_populate_vp() returns with dmp->dm_lock held.
353 struct devfs_dirent *de; in devfs_populate_vp() local
359 dmp = VFSTODEVFS(vp->v_mount); in devfs_populate_vp()
361 sx_xlock(&dmp->dm_lock); in devfs_populate_vp()
367 sx_xlock(&dmp->dm_lock); in devfs_populate_vp()
374 sx_xunlock(&dmp->dm_lock); in devfs_populate_vp()
376 sx_xlock(&dmp->dm_lock); in devfs_populate_vp()
378 sx_xunlock(&dmp->dm_lock); in devfs_populate_vp()
384 sx_xunlock(&dmp->dm_lock); in devfs_populate_vp()
387 de = vp->v_data; in devfs_populate_vp()
388 KASSERT(de != NULL, in devfs_populate_vp()
389 ("devfs_populate_vp: vp->v_data == NULL but vnode not doomed")); in devfs_populate_vp()
390 if ((de->de_flags & DE_DOOMED) != 0) { in devfs_populate_vp()
391 sx_xunlock(&dmp->dm_lock); in devfs_populate_vp()
401 struct vnode *vp = ap->a_vp; in devfs_vptocnp()
402 struct vnode **dvp = ap->a_vpp; in devfs_vptocnp()
404 char *buf = ap->a_buf; in devfs_vptocnp()
405 size_t *buflen = ap->a_buflen; in devfs_vptocnp()
406 struct devfs_dirent *dd, *de; in devfs_vptocnp() local
409 dmp = VFSTODEVFS(vp->v_mount); in devfs_vptocnp()
415 if (vp->v_type != VCHR && vp->v_type != VDIR) { in devfs_vptocnp()
420 dd = vp->v_data; in devfs_vptocnp()
421 if (vp->v_type == VDIR && dd == dmp->dm_rootdir) { in devfs_vptocnp()
428 i -= dd->de_dirent->d_namlen; in devfs_vptocnp()
433 bcopy(dd->de_dirent->d_name, buf + i, dd->de_dirent->d_namlen); in devfs_vptocnp()
435 de = devfs_parent_dirent(dd); in devfs_vptocnp()
436 if (de == NULL) { in devfs_vptocnp()
441 *dvp = de->de_vnode; in devfs_vptocnp()
454 sx_xunlock(&dmp->dm_lock); in devfs_vptocnp()
467 struct devfs_dirent *de; in devfs_fqpn() local
469 sx_assert(&dmp->dm_lock, SA_LOCKED); in devfs_fqpn()
474 i -= cnp->cn_namelen; in devfs_fqpn()
478 bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen); in devfs_fqpn()
479 de = dd; in devfs_fqpn()
480 while (de != dmp->dm_rootdir) { in devfs_fqpn()
482 i--; in devfs_fqpn()
487 i -= de->de_dirent->d_namlen; in devfs_fqpn()
490 bcopy(de->de_dirent->d_name, buf + i, in devfs_fqpn()
491 de->de_dirent->d_namlen); in devfs_fqpn()
492 de = devfs_parent_dirent(de); in devfs_fqpn()
493 if (de == NULL) in devfs_fqpn()
501 struct devfs_dirent *de) in devfs_allocv_drop_refs() argument
506 if (de->de_flags & DE_DOOMED) in devfs_allocv_drop_refs()
508 if (DEVFS_DE_DROP(de)) { in devfs_allocv_drop_refs()
509 KASSERT(not_found == 1, ("DEVFS de dropped but not doomed")); in devfs_allocv_drop_refs()
510 devfs_dirent_free(de); in devfs_allocv_drop_refs()
516 sx_xunlock(&dmp->dm_lock); in devfs_allocv_drop_refs()
520 sx_unlock(&dmp->dm_lock); in devfs_allocv_drop_refs()
525 * devfs_allocv shall be entered with dmp->dm_lock held, and it drops
529 devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode, in devfs_allocv() argument
540 if (de->de_flags & DE_DOOMED) { in devfs_allocv()
541 sx_xunlock(&dmp->dm_lock); in devfs_allocv()
545 DEVFS_DE_HOLD(de); in devfs_allocv()
548 vp = de->de_vnode; in devfs_allocv()
552 sx_xunlock(&dmp->dm_lock); in devfs_allocv()
554 sx_xlock(&dmp->dm_lock); in devfs_allocv()
555 if (devfs_allocv_drop_refs(0, dmp, de)) { in devfs_allocv()
560 if (de->de_vnode == vp) { in devfs_allocv()
561 de->de_vnode = NULL; in devfs_allocv()
562 vp->v_data = NULL; in devfs_allocv()
568 sx_xunlock(&dmp->dm_lock); in devfs_allocv()
573 if (de->de_dirent->d_type == DT_CHR) { in devfs_allocv()
574 if (!(de->de_cdp->cdp_flags & CDP_ACTIVE)) { in devfs_allocv()
575 devfs_allocv_drop_refs(1, dmp, de); in devfs_allocv()
578 dev = &de->de_cdp->cdp_c; in devfs_allocv()
584 devfs_allocv_drop_refs(1, dmp, de); in devfs_allocv()
589 if (de->de_dirent->d_type == DT_CHR) { in devfs_allocv()
590 vp->v_type = VCHR; in devfs_allocv()
594 /* XXX: v_rdev should be protect by vnode lock */ in devfs_allocv()
595 vp->v_rdev = dev; in devfs_allocv()
596 VNPASS(vp->v_usecount == 1, vp); in devfs_allocv()
598 dsw = dev->si_devsw; in devfs_allocv()
599 if (dsw != NULL && (dsw->d_flags & D_TTY) != 0) in devfs_allocv()
600 vp->v_vflag |= VV_ISTTY; in devfs_allocv()
603 if ((dev->si_flags & SI_ETERNAL) != 0) in devfs_allocv()
604 vp->v_vflag |= VV_ETERNALDEV; in devfs_allocv()
605 vp->v_op = &devfs_specops; in devfs_allocv()
606 } else if (de->de_dirent->d_type == DT_DIR) { in devfs_allocv()
607 vp->v_type = VDIR; in devfs_allocv()
608 } else if (de->de_dirent->d_type == DT_LNK) { in devfs_allocv()
609 vp->v_type = VLNK; in devfs_allocv()
611 vp->v_type = VBAD; in devfs_allocv()
616 vp->v_data = de; in devfs_allocv()
617 de->de_vnode = vp; in devfs_allocv()
622 vp->v_data = NULL; in devfs_allocv()
623 de->de_vnode = NULL; in devfs_allocv()
627 (void) devfs_allocv_drop_refs(1, dmp, de); in devfs_allocv()
630 if (devfs_allocv_drop_refs(0, dmp, de)) { in devfs_allocv()
636 mac_devfs_vnode_associate(mp, de, vp); in devfs_allocv()
638 sx_xunlock(&dmp->dm_lock); in devfs_allocv()
647 struct vnode *vp = ap->a_vp; in devfs_access()
648 struct devfs_dirent *de; in devfs_access() local
652 de = vp->v_data; in devfs_access()
653 if (vp->v_type == VDIR) in devfs_access()
654 de = de->de_dir; in devfs_access()
656 error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid, in devfs_access()
657 ap->a_accmode, ap->a_cred); in devfs_access()
662 p = ap->a_td->td_proc; in devfs_access()
665 if (!(p->p_flag & P_CONTROLT)) { in devfs_access()
669 if (p->p_session->s_ttydp == de->de_cdp) in devfs_access()
676 "devfs-only flag reuse failed");
681 struct vnode *vp = ap->a_vp, *oldvp; in devfs_close()
682 struct thread *td = ap->a_td; in devfs_close()
684 struct cdev *dev = vp->v_rdev; in devfs_close()
686 struct devfs_dirent *de = vp->v_data; in devfs_close() local
693 if (vp->v_data == NULL) in devfs_close()
705 if (de->de_usecount == 2 && td != NULL) { in devfs_close()
706 p = td->td_proc; in devfs_close()
708 if (vp == p->p_session->s_ttyvp) { in devfs_close()
712 if (vp == p->p_session->s_ttyvp) { in devfs_close()
713 SESS_LOCK(p->p_session); in devfs_close()
717 p->p_session->s_ttyvp = NULL; in devfs_close()
718 p->p_session->s_ttydp = NULL; in devfs_close()
723 SESS_UNLOCK(p->p_session); in devfs_close()
753 } else if (dsw->d_flags & D_TRACKCLOSE) { in devfs_close()
764 KASSERT(dev->si_refcount > 0, in devfs_close()
765 ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev))); in devfs_close()
766 error = dsw->d_close(dev, ap->a_fflag | dflags, S_IFCHR, td); in devfs_close()
780 * NB: td may be NULL if this descriptor is closed due to in devfs_close_f()
783 fpop = curthread->td_fpop; in devfs_close_f()
784 curthread->td_fpop = fp; in devfs_close_f()
786 curthread->td_fpop = fpop; in devfs_close_f()
789 * The f_cdevpriv cannot be assigned non-NULL value while we in devfs_close_f()
792 if (fp->f_cdevpriv != NULL) in devfs_close_f()
800 struct vnode *vp = ap->a_vp; in devfs_getattr()
801 struct vattr *vap = ap->a_vap; in devfs_getattr()
802 struct devfs_dirent *de; in devfs_getattr() local
812 dmp = VFSTODEVFS(vp->v_mount); in devfs_getattr()
813 sx_xunlock(&dmp->dm_lock); in devfs_getattr()
815 de = vp->v_data; in devfs_getattr()
816 KASSERT(de != NULL, ("Null dirent in devfs_getattr vp=%p", vp)); in devfs_getattr()
817 if (vp->v_type == VDIR) { in devfs_getattr()
818 de = de->de_dir; in devfs_getattr()
819 KASSERT(de != NULL, in devfs_getattr()
822 vap->va_uid = de->de_uid; in devfs_getattr()
823 vap->va_gid = de->de_gid; in devfs_getattr()
824 vap->va_mode = de->de_mode; in devfs_getattr()
825 if (vp->v_type == VLNK) in devfs_getattr()
826 vap->va_size = strlen(de->de_symlink); in devfs_getattr()
827 else if (vp->v_type == VDIR) in devfs_getattr()
828 vap->va_size = vap->va_bytes = DEV_BSIZE; in devfs_getattr()
830 vap->va_size = 0; in devfs_getattr()
831 if (vp->v_type != VDIR) in devfs_getattr()
832 vap->va_bytes = 0; in devfs_getattr()
833 vap->va_blocksize = DEV_BSIZE; in devfs_getattr()
834 vap->va_type = vp->v_type; in devfs_getattr()
845 if (vp->v_type != VCHR) { in devfs_getattr()
846 fix(de->de_atime); in devfs_getattr()
847 vap->va_atime = de->de_atime; in devfs_getattr()
848 fix(de->de_mtime); in devfs_getattr()
849 vap->va_mtime = de->de_mtime; in devfs_getattr()
850 fix(de->de_ctime); in devfs_getattr()
851 vap->va_ctime = de->de_ctime; in devfs_getattr()
853 dev = vp->v_rdev; in devfs_getattr()
854 fix(dev->si_atime); in devfs_getattr()
855 vap->va_atime = dev->si_atime; in devfs_getattr()
856 fix(dev->si_mtime); in devfs_getattr()
857 vap->va_mtime = dev->si_mtime; in devfs_getattr()
858 fix(dev->si_ctime); in devfs_getattr()
859 vap->va_ctime = dev->si_ctime; in devfs_getattr()
861 vap->va_rdev = cdev2priv(dev)->cdp_inode; in devfs_getattr()
863 vap->va_gen = 0; in devfs_getattr()
864 vap->va_flags = 0; in devfs_getattr()
865 vap->va_filerev = 0; in devfs_getattr()
866 vap->va_nlink = de->de_links; in devfs_getattr()
867 vap->va_fileid = de->de_inode; in devfs_getattr()
879 fpop = td->td_fpop; in devfs_ioctl_f()
880 td->td_fpop = fp; in devfs_ioctl_f()
882 td->td_fpop = fpop; in devfs_ioctl_f()
899 return (fgnup->fgn.buf); in fiodgname_buf_get_ptr()
902 return ((void *)(uintptr_t)fgnup->fgn32.buf); in fiodgname_buf_get_ptr()
922 vp = ap->a_vp; in devfs_ioctl()
923 com = ap->a_command; in devfs_ioctl()
924 td = ap->a_td; in devfs_ioctl()
929 KASSERT(dev->si_refcount > 0, in devfs_ioctl()
930 ("devfs: un-referenced struct cdev *(%s)", devtoname(dev))); in devfs_ioctl()
934 *(int *)ap->a_data = dsw->d_flags & D_TYPEMASK; in devfs_ioctl()
941 fgn = ap->a_data; in devfs_ioctl()
944 if (i > fgn->len) in devfs_ioctl()
950 error = dsw->d_ioctl(dev, com, ap->a_data, ap->a_fflag, td); in devfs_ioctl()
966 sess = td->td_proc->p_session; in devfs_ioctl()
967 if (sess->s_ttyvp == vp || sess->s_ttyp == NULL) { in devfs_ioctl()
974 vpold = sess->s_ttyvp; in devfs_ioctl()
975 sess->s_ttyvp = vp; in devfs_ioctl()
976 sess->s_ttydp = cdev2priv(dev); in devfs_ioctl()
999 fpop = td->td_fpop; in devfs_kqfilter_f()
1003 error = dsw->d_kqfilter(dev, kn); in devfs_kqfilter_f()
1004 td->td_fpop = fpop; in devfs_kqfilter_f()
1010 devfs_prison_check(struct devfs_dirent *de, struct thread *td) in devfs_prison_check() argument
1017 cdp = de->de_cdp; in devfs_prison_check()
1020 dcr = cdp->cdp_c.si_cred; in devfs_prison_check()
1024 error = prison_check(td->td_ucred, dcr); in devfs_prison_check()
1028 p = td->td_proc; in devfs_prison_check()
1030 if (!(p->p_flag & P_CONTROLT)) { in devfs_prison_check()
1034 if (p->p_session->s_ttydp == cdp) in devfs_prison_check()
1046 struct devfs_dirent *de, *dd; in devfs_lookupx() local
1055 cnp = ap->a_cnp; in devfs_lookupx()
1056 vpp = ap->a_vpp; in devfs_lookupx()
1057 dvp = ap->a_dvp; in devfs_lookupx()
1058 pname = cnp->cn_nameptr; in devfs_lookupx()
1059 flags = cnp->cn_flags; in devfs_lookupx()
1060 nameiop = cnp->cn_nameiop; in devfs_lookupx()
1061 mp = dvp->v_mount; in devfs_lookupx()
1063 dd = dvp->v_data; in devfs_lookupx()
1069 if (dvp->v_type != VDIR) in devfs_lookupx()
1072 if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT)) in devfs_lookupx()
1079 if (cnp->cn_namelen == 1 && *pname == '.') { in devfs_lookupx()
1090 de = devfs_parent_dirent(dd); in devfs_lookupx()
1091 if (de == NULL) in devfs_lookupx()
1095 error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, in devfs_lookupx()
1102 dd = dvp->v_data; in devfs_lookupx()
1103 de = devfs_find(dd, cnp->cn_nameptr, cnp->cn_namelen, 0); in devfs_lookupx()
1104 while (de == NULL) { /* While(...) so we can use break */ in devfs_lookupx()
1119 sx_xunlock(&dmp->dm_lock); in devfs_lookupx()
1121 td->td_ucred, pname, strlen(pname), &cdev); in devfs_lookupx()
1124 sx_xlock(&dmp->dm_lock); in devfs_lookupx()
1127 sx_xlock(&dmp->dm_lock); in devfs_lookupx()
1129 sx_xunlock(&dmp->dm_lock); in devfs_lookupx()
1132 sx_xunlock(&dmp->dm_lock); in devfs_lookupx()
1138 sx_xunlock(&dmp->dm_lock); in devfs_lookupx()
1149 dde = &cdev2priv(cdev)->cdp_dirents[dmp->dm_idx]; in devfs_lookupx()
1151 de = *dde; in devfs_lookupx()
1157 if (de == NULL || de->de_flags & DE_WHITEOUT) { in devfs_lookupx()
1165 if (devfs_prison_check(de, td)) in devfs_lookupx()
1168 if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) { in devfs_lookupx()
1169 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); in devfs_lookupx()
1178 error = devfs_allocv(de, mp, cnp->cn_lkflags & LK_TYPE_MASK, vpp); in devfs_lookupx()
1190 if (devfs_populate_vp(ap->a_dvp) != 0) in devfs_lookup()
1193 dmp = VFSTODEVFS(ap->a_dvp->v_mount); in devfs_lookup()
1197 sx_xunlock(&dmp->dm_lock); in devfs_lookup()
1206 struct devfs_dirent *dd, *de; in devfs_mknod() local
1211 * The only type of node we should be creating here is a in devfs_mknod()
1214 if (ap->a_vap->va_type != VCHR) in devfs_mknod()
1216 dvp = ap->a_dvp; in devfs_mknod()
1217 dmp = VFSTODEVFS(dvp->v_mount); in devfs_mknod()
1219 cnp = ap->a_cnp; in devfs_mknod()
1220 vpp = ap->a_vpp; in devfs_mknod()
1221 dd = dvp->v_data; in devfs_mknod()
1224 sx_xlock(&dmp->dm_lock); in devfs_mknod()
1225 TAILQ_FOREACH(de, &dd->de_dlist, de_list) { in devfs_mknod()
1226 if (cnp->cn_namelen != de->de_dirent->d_namlen) in devfs_mknod()
1228 if (de->de_dirent->d_type == DT_CHR && in devfs_mknod()
1229 (de->de_cdp->cdp_flags & CDP_ACTIVE) == 0) in devfs_mknod()
1231 if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name, in devfs_mknod()
1232 de->de_dirent->d_namlen) != 0) in devfs_mknod()
1234 if (de->de_flags & DE_WHITEOUT) in devfs_mknod()
1238 if (de == NULL) in devfs_mknod()
1240 de->de_flags &= ~DE_WHITEOUT; in devfs_mknod()
1241 error = devfs_allocv(de, dvp->v_mount, LK_EXCLUSIVE, vpp); in devfs_mknod()
1244 sx_xunlock(&dmp->dm_lock); in devfs_mknod()
1252 struct thread *td = ap->a_td; in devfs_open()
1253 struct vnode *vp = ap->a_vp; in devfs_open()
1254 struct cdev *dev = vp->v_rdev; in devfs_open()
1255 struct file *fp = ap->a_fp; in devfs_open()
1260 if (vp->v_type == VBLK) in devfs_open()
1267 if (dev->si_iosize_max == 0) in devfs_open()
1268 dev->si_iosize_max = DFLTPHYS; in devfs_open()
1273 if (fp == NULL && dsw->d_fdopen != NULL) { in devfs_open()
1278 if (vp->v_type == VCHR) in devfs_open()
1284 fpop = td->td_fpop; in devfs_open()
1285 td->td_fpop = fp; in devfs_open()
1287 fp->f_data = dev; in devfs_open()
1288 fp->f_vnode = vp; in devfs_open()
1290 if (dsw->d_fdopen != NULL) in devfs_open()
1291 error = dsw->d_fdopen(dev, ap->a_mode, td, fp); in devfs_open()
1293 error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td); in devfs_open()
1297 td->td_fpop = fpop; in devfs_open()
1300 if (error != 0 && vp->v_type == VCHR) in devfs_open()
1316 if (fp->f_ops == &badfileops) in devfs_open()
1317 finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f); in devfs_open()
1325 switch (ap->a_name) { in devfs_pathconf()
1327 *ap->a_retval = 64; in devfs_pathconf()
1330 *ap->a_retval = NAME_MAX; in devfs_pathconf()
1333 *ap->a_retval = INT_MAX; in devfs_pathconf()
1336 *ap->a_retval = MAXPATHLEN; in devfs_pathconf()
1339 if (ap->a_vp->v_vflag & VV_ISTTY) { in devfs_pathconf()
1340 *ap->a_retval = MAX_CANON; in devfs_pathconf()
1345 if (ap->a_vp->v_vflag & VV_ISTTY) { in devfs_pathconf()
1346 *ap->a_retval = MAX_INPUT; in devfs_pathconf()
1351 if (ap->a_vp->v_vflag & VV_ISTTY) { in devfs_pathconf()
1352 *ap->a_retval = _POSIX_VDISABLE; in devfs_pathconf()
1360 * trivial non-persistent label storage. in devfs_pathconf()
1362 *ap->a_retval = 1; in devfs_pathconf()
1364 *ap->a_retval = 0; in devfs_pathconf()
1368 *ap->a_retval = 1; in devfs_pathconf()
1385 fpop = td->td_fpop; in devfs_poll_f()
1391 error = dsw->d_poll(dev, events, td); in devfs_poll_f()
1392 td->td_fpop = fpop; in devfs_poll_f()
1404 printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev)); in devfs_print()
1418 if (uio->uio_resid > DEVFS_IOSIZE_MAX) in devfs_read_f()
1420 fpop = td->td_fpop; in devfs_read_f()
1426 resid = uio->uio_resid; in devfs_read_f()
1427 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT); in devfs_read_f()
1432 error = dsw->d_read(dev, uio, ioflag); in devfs_read_f()
1433 if (uio->uio_resid != resid || (error == 0 && resid != 0)) in devfs_read_f()
1434 devfs_timestamp(&dev->si_atime); in devfs_read_f()
1435 td->td_fpop = fpop; in devfs_read_f()
1449 struct devfs_dirent *de; in devfs_readdir() local
1454 if (ap->a_vp->v_type != VDIR) in devfs_readdir()
1457 uio = ap->a_uio; in devfs_readdir()
1458 if (uio->uio_offset < 0) in devfs_readdir()
1467 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies in devfs_readdir()
1470 if (ap->a_ncookies != NULL) { in devfs_readdir()
1471 tmp_ncookies = ap->a_ncookies; in devfs_readdir()
1472 *ap->a_ncookies = 0; in devfs_readdir()
1473 ap->a_ncookies = NULL; in devfs_readdir()
1476 dmp = VFSTODEVFS(ap->a_vp->v_mount); in devfs_readdir()
1477 if (devfs_populate_vp(ap->a_vp) != 0) { in devfs_readdir()
1479 ap->a_ncookies = tmp_ncookies; in devfs_readdir()
1483 de = ap->a_vp->v_data; in devfs_readdir()
1485 TAILQ_FOREACH(dd, &de->de_dlist, de_list) { in devfs_readdir()
1486 KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__)); in devfs_readdir()
1487 if (dd->de_flags & (DE_COVERED | DE_WHITEOUT)) in devfs_readdir()
1489 if (devfs_prison_check(dd, uio->uio_td)) in devfs_readdir()
1491 if (dd->de_dirent->d_type == DT_DIR) in devfs_readdir()
1492 de = dd->de_dir; in devfs_readdir()
1494 de = dd; in devfs_readdir()
1495 dp = dd->de_dirent; in devfs_readdir()
1496 MPASS(dp->d_reclen == GENERIC_DIRSIZ(dp)); in devfs_readdir()
1497 if (dp->d_reclen > uio->uio_resid) in devfs_readdir()
1499 dp->d_fileno = de->de_inode; in devfs_readdir()
1501 dp->d_off = off + dp->d_reclen; in devfs_readdir()
1502 if (off >= uio->uio_offset) { in devfs_readdir()
1507 off += dp->d_reclen; in devfs_readdir()
1509 sx_xunlock(&dmp->dm_lock); in devfs_readdir()
1510 uio->uio_offset = off; in devfs_readdir()
1513 * Restore ap->a_ncookies if it wasn't originally NULL in the first in devfs_readdir()
1517 ap->a_ncookies = tmp_ncookies; in devfs_readdir()
1525 struct devfs_dirent *de; in devfs_readlink() local
1527 de = ap->a_vp->v_data; in devfs_readlink()
1528 return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio)); in devfs_readlink()
1534 struct devfs_dirent *de; in devfs_reclaiml() local
1537 de = vp->v_data; in devfs_reclaiml()
1538 if (de != NULL) { in devfs_reclaiml()
1539 MPASS(de->de_usecount == 0); in devfs_reclaiml()
1540 de->de_vnode = NULL; in devfs_reclaiml()
1541 vp->v_data = NULL; in devfs_reclaiml()
1550 vp = ap->a_vp; in devfs_reclaim()
1563 vp = ap->a_vp; in devfs_reclaim_vchr()
1564 MPASS(vp->v_type == VCHR); in devfs_reclaim_vchr()
1572 dev = vp->v_rdev; in devfs_reclaim_vchr()
1573 vp->v_rdev = NULL; in devfs_reclaim_vchr()
1584 struct vnode *dvp = ap->a_dvp; in devfs_remove()
1585 struct vnode *vp = ap->a_vp; in devfs_remove()
1587 struct devfs_dirent *de, *de_covered; in devfs_remove() local
1588 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount); in devfs_remove()
1593 sx_xlock(&dmp->dm_lock); in devfs_remove()
1594 dd = ap->a_dvp->v_data; in devfs_remove()
1595 de = vp->v_data; in devfs_remove()
1596 if (de->de_cdp == NULL) { in devfs_remove()
1597 TAILQ_REMOVE(&dd->de_dlist, de, de_list); in devfs_remove()
1598 if (de->de_dirent->d_type == DT_LNK) { in devfs_remove()
1599 de_covered = devfs_find(dd, de->de_dirent->d_name, in devfs_remove()
1600 de->de_dirent->d_namlen, 0); in devfs_remove()
1602 de_covered->de_flags &= ~DE_COVERED; in devfs_remove()
1608 devfs_delete(dmp, de, 0); in devfs_remove()
1609 sx_xunlock(&dmp->dm_lock); in devfs_remove()
1614 de->de_flags |= DE_WHITEOUT; in devfs_remove()
1615 sx_xunlock(&dmp->dm_lock); in devfs_remove()
1629 struct vnode *vp = ap->a_vp, *vp2; in devfs_revoke()
1632 struct devfs_dirent *de; in devfs_revoke() local
1636 KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL")); in devfs_revoke()
1638 dev = vp->v_rdev; in devfs_revoke()
1642 cdp->cdp_inuse++; in devfs_revoke()
1655 for (i = 0; i <= cdp->cdp_maxdirent; i++) { in devfs_revoke()
1656 de = cdp->cdp_dirents[i]; in devfs_revoke()
1657 if (de == NULL) in devfs_revoke()
1660 vp2 = de->de_vnode; in devfs_revoke()
1682 cdp->cdp_inuse--; in devfs_revoke()
1683 if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) { in devfs_revoke()
1684 KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) != 0, in devfs_revoke()
1686 __func__, cdp, dev->si_name)); in devfs_revoke()
1687 cdp->cdp_flags &= ~CDP_ON_ACTIVE_LIST; in devfs_revoke()
1690 dev_rel(&cdp->cdp_c); in devfs_revoke()
1705 vp = ap->a_vp; in devfs_rioctl()
1711 dmp = VFSTODEVFS(vp->v_mount); in devfs_rioctl()
1712 sx_xlock(&dmp->dm_lock); in devfs_rioctl()
1717 sx_xunlock(&dmp->dm_lock); in devfs_rioctl()
1721 error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td); in devfs_rioctl()
1722 sx_xunlock(&dmp->dm_lock); in devfs_rioctl()
1730 if (ap->a_vp->v_type != VDIR) in devfs_rread()
1732 return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL)); in devfs_rread()
1738 struct devfs_dirent *de; in devfs_setattr() local
1746 vap = ap->a_vap; in devfs_setattr()
1747 vp = ap->a_vp; in devfs_setattr()
1749 if ((vap->va_type != VNON) || in devfs_setattr()
1750 (vap->va_nlink != VNOVAL) || in devfs_setattr()
1751 (vap->va_fsid != VNOVAL) || in devfs_setattr()
1752 (vap->va_fileid != VNOVAL) || in devfs_setattr()
1753 (vap->va_blocksize != VNOVAL) || in devfs_setattr()
1754 (vap->va_flags != VNOVAL && vap->va_flags != 0) || in devfs_setattr()
1755 (vap->va_rdev != VNOVAL) || in devfs_setattr()
1756 ((int)vap->va_bytes != VNOVAL) || in devfs_setattr()
1757 (vap->va_gen != VNOVAL)) { in devfs_setattr()
1765 de = vp->v_data; in devfs_setattr()
1766 if (vp->v_type == VDIR) in devfs_setattr()
1767 de = de->de_dir; in devfs_setattr()
1770 if (vap->va_uid == (uid_t)VNOVAL) in devfs_setattr()
1771 uid = de->de_uid; in devfs_setattr()
1773 uid = vap->va_uid; in devfs_setattr()
1774 if (vap->va_gid == (gid_t)VNOVAL) in devfs_setattr()
1775 gid = de->de_gid; in devfs_setattr()
1777 gid = vap->va_gid; in devfs_setattr()
1778 if (uid != de->de_uid || gid != de->de_gid) { in devfs_setattr()
1779 if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || in devfs_setattr()
1780 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) { in devfs_setattr()
1785 de->de_uid = uid; in devfs_setattr()
1786 de->de_gid = gid; in devfs_setattr()
1790 if (vap->va_mode != (mode_t)VNOVAL) { in devfs_setattr()
1791 if (ap->a_cred->cr_uid != de->de_uid) { in devfs_setattr()
1796 de->de_mode = vap->va_mode; in devfs_setattr()
1800 if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { in devfs_setattr()
1801 error = vn_utimes_perm(vp, vap, ap->a_cred, td); in devfs_setattr()
1804 if (vap->va_atime.tv_sec != VNOVAL) { in devfs_setattr()
1805 if (vp->v_type == VCHR) in devfs_setattr()
1806 vp->v_rdev->si_atime = vap->va_atime; in devfs_setattr()
1808 de->de_atime = vap->va_atime; in devfs_setattr()
1810 if (vap->va_mtime.tv_sec != VNOVAL) { in devfs_setattr()
1811 if (vp->v_type == VCHR) in devfs_setattr()
1812 vp->v_rdev->si_mtime = vap->va_mtime; in devfs_setattr()
1814 de->de_mtime = vap->va_mtime; in devfs_setattr()
1820 if (vp->v_type == VCHR) in devfs_setattr()
1821 vfs_timestamp(&vp->v_rdev->si_ctime); in devfs_setattr()
1823 vfs_timestamp(&de->de_mtime); in devfs_setattr()
1827 sx_xunlock(&VFSTODEVFS(vp->v_mount)->dm_lock); in devfs_setattr()
1836 struct devfs_dirent *de; in devfs_setlabel() local
1838 vp = ap->a_vp; in devfs_setlabel()
1839 de = vp->v_data; in devfs_setlabel()
1841 mac_vnode_relabel(ap->a_cred, vp, ap->a_label); in devfs_setlabel()
1842 mac_devfs_update(vp->v_mount, de, vp); in devfs_setlabel()
1860 struct devfs_dirent *de, *de_covered, *de_dotdot; in devfs_symlink() local
1866 dmp = VFSTODEVFS(ap->a_dvp->v_mount); in devfs_symlink()
1867 if (devfs_populate_vp(ap->a_dvp) != 0) in devfs_symlink()
1870 dd = ap->a_dvp->v_data; in devfs_symlink()
1871 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen); in devfs_symlink()
1872 de->de_flags = DE_USER; in devfs_symlink()
1873 de->de_uid = 0; in devfs_symlink()
1874 de->de_gid = 0; in devfs_symlink()
1875 de->de_mode = 0755; in devfs_symlink()
1876 de->de_inode = alloc_unr(devfs_inos); in devfs_symlink()
1877 de->de_dir = dd; in devfs_symlink()
1878 de->de_dirent->d_type = DT_LNK; in devfs_symlink()
1879 i = strlen(ap->a_target) + 1; in devfs_symlink()
1880 de->de_symlink = malloc(i, M_DEVFS, M_WAITOK); in devfs_symlink()
1881 bcopy(ap->a_target, de->de_symlink, i); in devfs_symlink()
1883 mac_devfs_create_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); in devfs_symlink()
1885 de_covered = devfs_find(dd, de->de_dirent->d_name, in devfs_symlink()
1886 de->de_dirent->d_namlen, 0); in devfs_symlink()
1888 if ((de_covered->de_flags & DE_USER) != 0) { in devfs_symlink()
1889 devfs_delete(dmp, de, DEVFS_DEL_NORECURSE); in devfs_symlink()
1890 sx_xunlock(&dmp->dm_lock); in devfs_symlink()
1893 KASSERT((de_covered->de_flags & DE_COVERED) == 0, in devfs_symlink()
1895 de_covered->de_flags |= DE_COVERED; in devfs_symlink()
1898 de_dotdot = TAILQ_FIRST(&dd->de_dlist); /* "." */ in devfs_symlink()
1900 TAILQ_INSERT_AFTER(&dd->de_dlist, de_dotdot, de, de_list); in devfs_symlink()
1902 devfs_rules_apply(dmp, de); in devfs_symlink()
1904 return (devfs_allocv(de, ap->a_dvp->v_mount, LK_EXCLUSIVE, ap->a_vpp)); in devfs_symlink()
1924 if (uio->uio_resid > DEVFS_IOSIZE_MAX) in devfs_write_f()
1926 fpop = td->td_fpop; in devfs_write_f()
1932 KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); in devfs_write_f()
1933 ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC); in devfs_write_f()
1938 resid = uio->uio_resid; in devfs_write_f()
1940 error = dsw->d_write(dev, uio, ioflag); in devfs_write_f()
1941 if (uio->uio_resid != resid || (error == 0 && resid != 0)) { in devfs_write_f()
1942 devfs_timestamp(&dev->si_ctime); in devfs_write_f()
1943 dev->si_mtime = dev->si_ctime; in devfs_write_f()
1945 td->td_fpop = fpop; in devfs_write_f()
1966 vp = fp->f_vnode; in devfs_mmap_f()
1972 mp = vp->v_mount; in devfs_mmap_f()
1973 if (mp != NULL && (mp->mnt_flag & MNT_NOEXEC) != 0) { in devfs_mmap_f()
1979 if ((fp->f_flag & FREAD) != 0) in devfs_mmap_f()
1998 if ((fp->f_flag & FWRITE) != 0) in devfs_mmap_f()
2005 fpop = td->td_fpop; in devfs_mmap_f()
2012 td->td_fpop = fpop; in devfs_mmap_f()
2029 return (cdev2priv(x)->cdp_inode); in dev2udev()
2035 if (fp2->f_type != DTYPE_VNODE || fp2->f_ops != &devfs_ops_f) in devfs_cmp_f()
2037 return (kcmp_cmp((uintptr_t)fp1->f_data, (uintptr_t)fp2->f_data)); in devfs_cmp_f()
2059 /* Vops for non-CHR vnodes in /dev. */
2131 * Our calling convention to the device drivers used to be that we passed
2136 * be the same as the fcntl ones and by sending down the bitwise OR of