xref: /freebsd/sys/fs/devfs/devfs_vnops.c (revision f6c0136c7fb87ab8277221a306291e386fe944fb)
1 /*-
2  * Copyright (c) 2000-2004
3  *	Poul-Henning Kamp.  All rights reserved.
4  * Copyright (c) 1989, 1992-1993, 1995
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software donated to Berkeley by
8  * Jan-Simon Pendry.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *	@(#)kernfs_vnops.c	8.15 (Berkeley) 5/21/95
32  * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43
33  *
34  * $FreeBSD$
35  */
36 
37 /*
38  * TODO:
39  *	remove empty directories
40  *	mkdir: want it ?
41  */
42 
43 #include "opt_mac.h"
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/conf.h>
48 #include <sys/dirent.h>
49 #include <sys/fcntl.h>
50 #include <sys/file.h>
51 #include <sys/filedesc.h>
52 #include <sys/filio.h>
53 #include <sys/kernel.h>
54 #include <sys/lock.h>
55 #include <sys/malloc.h>
56 #include <sys/mount.h>
57 #include <sys/namei.h>
58 #include <sys/priv.h>
59 #include <sys/proc.h>
60 #include <sys/stat.h>
61 #include <sys/sx.h>
62 #include <sys/time.h>
63 #include <sys/ttycom.h>
64 #include <sys/unistd.h>
65 #include <sys/vnode.h>
66 
67 static struct vop_vector devfs_vnodeops;
68 static struct vop_vector devfs_specops;
69 static struct fileops devfs_ops_f;
70 
71 #include <fs/devfs/devfs.h>
72 #include <fs/devfs/devfs_int.h>
73 
74 #include <security/mac/mac_framework.h>
75 
76 struct mtx	devfs_de_interlock;
77 MTX_SYSINIT(devfs_de_interlock, &devfs_de_interlock, "devfs interlock", MTX_DEF);
78 
79 static int
80 devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp)
81 {
82 
83 	*dswp = devvn_refthread(fp->f_vnode, devp);
84 	if (*devp != fp->f_data) {
85 		if (*dswp != NULL)
86 			dev_relthread(*devp);
87 		return (ENXIO);
88 	}
89 	KASSERT((*devp)->si_refcount > 0,
90 	    ("devfs: un-referenced struct cdev *(%s)", devtoname(*devp)));
91 	if (*dswp == NULL)
92 		return (ENXIO);
93 	return (0);
94 }
95 
96 /*
97  * Construct the fully qualified path name relative to the mountpoint
98  */
99 static char *
100 devfs_fqpn(char *buf, struct vnode *dvp, struct componentname *cnp)
101 {
102 	int i;
103 	struct devfs_dirent *de, *dd;
104 	struct devfs_mount *dmp;
105 
106 	dmp = VFSTODEVFS(dvp->v_mount);
107 	dd = dvp->v_data;
108 	i = SPECNAMELEN;
109 	buf[i] = '\0';
110 	i -= cnp->cn_namelen;
111 	if (i < 0)
112 		 return (NULL);
113 	bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen);
114 	de = dd;
115 	while (de != dmp->dm_rootdir) {
116 		i--;
117 		if (i < 0)
118 			 return (NULL);
119 		buf[i] = '/';
120 		i -= de->de_dirent->d_namlen;
121 		if (i < 0)
122 			 return (NULL);
123 		bcopy(de->de_dirent->d_name, buf + i,
124 		    de->de_dirent->d_namlen);
125 		de = TAILQ_FIRST(&de->de_dlist);	/* "." */
126 		de = TAILQ_NEXT(de, de_list);		/* ".." */
127 		de = de->de_dir;
128 	}
129 	return (buf + i);
130 }
131 
132 static int
133 devfs_allocv_drop_refs(int drop_dm_lock, struct devfs_mount *dmp,
134 	struct devfs_dirent *de)
135 {
136 	int not_found;
137 
138 	not_found = 0;
139 	if (de->de_flags & DE_DOOMED)
140 		not_found = 1;
141 	if (DEVFS_DE_DROP(de)) {
142 		KASSERT(not_found == 1, ("DEVFS de dropped but not doomed"));
143 		devfs_dirent_free(de);
144 	}
145 	if (DEVFS_DMP_DROP(dmp)) {
146 		KASSERT(not_found == 1,
147 			("DEVFS mount struct freed before dirent"));
148 		not_found = 2;
149 		sx_xunlock(&dmp->dm_lock);
150 		devfs_unmount_final(dmp);
151 	}
152 	if (not_found == 1 || (drop_dm_lock && not_found != 2))
153 		sx_unlock(&dmp->dm_lock);
154 	return (not_found);
155 }
156 
157 static void
158 devfs_insmntque_dtr(struct vnode *vp, void *arg)
159 {
160 	struct devfs_dirent *de;
161 
162 	de = (struct devfs_dirent *)arg;
163 	mtx_lock(&devfs_de_interlock);
164 	vp->v_data = NULL;
165 	de->de_vnode = NULL;
166 	mtx_unlock(&devfs_de_interlock);
167 	vgone(vp);
168 	vput(vp);
169 }
170 
171 /*
172  * devfs_allocv shall be entered with dmp->dm_lock held, and it drops
173  * it on return.
174  */
175 int
176 devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td)
177 {
178 	int error;
179 	struct vnode *vp;
180 	struct cdev *dev;
181 	struct devfs_mount *dmp;
182 
183 	KASSERT(td == curthread, ("devfs_allocv: td != curthread"));
184 	dmp = VFSTODEVFS(mp);
185 	if (de->de_flags & DE_DOOMED) {
186 		sx_xunlock(&dmp->dm_lock);
187 		return (ENOENT);
188 	}
189  loop:
190 	DEVFS_DE_HOLD(de);
191 	DEVFS_DMP_HOLD(dmp);
192 	mtx_lock(&devfs_de_interlock);
193 	vp = de->de_vnode;
194 	if (vp != NULL) {
195 		VI_LOCK(vp);
196 		mtx_unlock(&devfs_de_interlock);
197 		sx_xunlock(&dmp->dm_lock);
198 		error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
199 		sx_xlock(&dmp->dm_lock);
200 		if (devfs_allocv_drop_refs(0, dmp, de)) {
201 			if (error == 0)
202 				vput(vp);
203 			return (ENOENT);
204 		}
205 		else if (error)
206 			goto loop;
207 		sx_xunlock(&dmp->dm_lock);
208 		*vpp = vp;
209 		return (0);
210 	}
211 	mtx_unlock(&devfs_de_interlock);
212 	if (de->de_dirent->d_type == DT_CHR) {
213 		if (!(de->de_cdp->cdp_flags & CDP_ACTIVE)) {
214 			devfs_allocv_drop_refs(1, dmp, de);
215 			return (ENOENT);
216 		}
217 		dev = &de->de_cdp->cdp_c;
218 	} else {
219 		dev = NULL;
220 	}
221 	error = getnewvnode("devfs", mp, &devfs_vnodeops, &vp);
222 	if (error != 0) {
223 		devfs_allocv_drop_refs(1, dmp, de);
224 		printf("devfs_allocv: failed to allocate new vnode\n");
225 		return (error);
226 	}
227 
228 	if (de->de_dirent->d_type == DT_CHR) {
229 		vp->v_type = VCHR;
230 		VI_LOCK(vp);
231 		dev_lock();
232 		dev_refl(dev);
233 		vp->v_rdev = dev;
234 		KASSERT(vp->v_usecount == 1,
235 		    ("%s %d (%d)\n", __func__, __LINE__, vp->v_usecount));
236 		dev->si_usecount += vp->v_usecount;
237 		dev_unlock();
238 		VI_UNLOCK(vp);
239 		vp->v_op = &devfs_specops;
240 	} else if (de->de_dirent->d_type == DT_DIR) {
241 		vp->v_type = VDIR;
242 	} else if (de->de_dirent->d_type == DT_LNK) {
243 		vp->v_type = VLNK;
244 	} else {
245 		vp->v_type = VBAD;
246 	}
247 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
248 	mtx_lock(&devfs_de_interlock);
249 	vp->v_data = de;
250 	de->de_vnode = vp;
251 	mtx_unlock(&devfs_de_interlock);
252 	error = insmntque1(vp, mp, devfs_insmntque_dtr, de);
253 	if (error != 0) {
254 		(void) devfs_allocv_drop_refs(1, dmp, de);
255 		return (error);
256 	}
257 	if (devfs_allocv_drop_refs(0, dmp, de)) {
258 		vput(vp);
259 		return (ENOENT);
260 	}
261 #ifdef MAC
262 	mac_associate_vnode_devfs(mp, de, vp);
263 #endif
264 	sx_xunlock(&dmp->dm_lock);
265 	*vpp = vp;
266 	return (0);
267 }
268 
269 static int
270 devfs_access(struct vop_access_args *ap)
271 {
272 	struct vnode *vp = ap->a_vp;
273 	struct devfs_dirent *de;
274 	int error;
275 
276 	de = vp->v_data;
277 	if (vp->v_type == VDIR)
278 		de = de->de_dir;
279 
280 	error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
281 	    ap->a_mode, ap->a_cred, NULL);
282 	if (!error)
283 		return (error);
284 	if (error != EACCES)
285 		return (error);
286 	/* We do, however, allow access to the controlling terminal */
287 	if (!(ap->a_td->td_proc->p_flag & P_CONTROLT))
288 		return (error);
289 	if (ap->a_td->td_proc->p_session->s_ttyvp == de->de_vnode)
290 		return (0);
291 	return (error);
292 }
293 
294 /* ARGSUSED */
295 static int
296 devfs_advlock(struct vop_advlock_args *ap)
297 {
298 
299 	return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
300 }
301 
302 /* ARGSUSED */
303 static int
304 devfs_close(struct vop_close_args *ap)
305 {
306 	struct vnode *vp = ap->a_vp, *oldvp;
307 	struct thread *td = ap->a_td;
308 	struct cdev *dev = vp->v_rdev;
309 	struct cdevsw *dsw;
310 	int vp_locked, error;
311 
312 	/*
313 	 * Hack: a tty device that is a controlling terminal
314 	 * has a reference from the session structure.
315 	 * We cannot easily tell that a character device is
316 	 * a controlling terminal, unless it is the closing
317 	 * process' controlling terminal.  In that case,
318 	 * if the reference count is 2 (this last descriptor
319 	 * plus the session), release the reference from the session.
320 	 */
321 	oldvp = NULL;
322 	sx_xlock(&proctree_lock);
323 	if (td && vp == td->td_proc->p_session->s_ttyvp) {
324 		SESS_LOCK(td->td_proc->p_session);
325 		VI_LOCK(vp);
326 		if (count_dev(dev) == 2 && (vp->v_iflag & VI_DOOMED) == 0) {
327 			td->td_proc->p_session->s_ttyvp = NULL;
328 			oldvp = vp;
329 		}
330 		VI_UNLOCK(vp);
331 		SESS_UNLOCK(td->td_proc->p_session);
332 	}
333 	sx_xunlock(&proctree_lock);
334 	if (oldvp != NULL)
335 		vrele(oldvp);
336 	/*
337 	 * We do not want to really close the device if it
338 	 * is still in use unless we are trying to close it
339 	 * forcibly. Since every use (buffer, vnode, swap, cmap)
340 	 * holds a reference to the vnode, and because we mark
341 	 * any other vnodes that alias this device, when the
342 	 * sum of the reference counts on all the aliased
343 	 * vnodes descends to one, we are on last close.
344 	 */
345 	dsw = dev_refthread(dev);
346 	if (dsw == NULL)
347 		return (ENXIO);
348 	VI_LOCK(vp);
349 	if (vp->v_iflag & VI_DOOMED) {
350 		/* Forced close. */
351 	} else if (dsw->d_flags & D_TRACKCLOSE) {
352 		/* Keep device updated on status. */
353 	} else if (count_dev(dev) > 1) {
354 		VI_UNLOCK(vp);
355 		dev_relthread(dev);
356 		return (0);
357 	}
358 	vholdl(vp);
359 	VI_UNLOCK(vp);
360 	vp_locked = VOP_ISLOCKED(vp, td);
361 	VOP_UNLOCK(vp, 0, td);
362 	KASSERT(dev->si_refcount > 0,
363 	    ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
364 	if (!(dsw->d_flags & D_NEEDGIANT)) {
365 		DROP_GIANT();
366 		error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
367 		PICKUP_GIANT();
368 	} else {
369 		error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
370 	}
371 	dev_relthread(dev);
372 	vn_lock(vp, vp_locked | LK_RETRY, td);
373 	vdrop(vp);
374 	return (error);
375 }
376 
377 static int
378 devfs_close_f(struct file *fp, struct thread *td)
379 {
380 
381 	return (vnops.fo_close(fp, td));
382 }
383 
384 /* ARGSUSED */
385 static int
386 devfs_fsync(struct vop_fsync_args *ap)
387 {
388 	if (!vn_isdisk(ap->a_vp, NULL))
389 		return (0);
390 
391 	return (vop_stdfsync(ap));
392 }
393 
394 static int
395 devfs_getattr(struct vop_getattr_args *ap)
396 {
397 	struct vnode *vp = ap->a_vp;
398 	struct vattr *vap = ap->a_vap;
399 	int error = 0;
400 	struct devfs_dirent *de;
401 	struct cdev *dev;
402 
403 	de = vp->v_data;
404 	KASSERT(de != NULL, ("Null dirent in devfs_getattr vp=%p", vp));
405 	if (vp->v_type == VDIR) {
406 		de = de->de_dir;
407 		KASSERT(de != NULL,
408 		    ("Null dir dirent in devfs_getattr vp=%p", vp));
409 	}
410 	bzero((caddr_t) vap, sizeof(*vap));
411 	vattr_null(vap);
412 	vap->va_uid = de->de_uid;
413 	vap->va_gid = de->de_gid;
414 	vap->va_mode = de->de_mode;
415 	if (vp->v_type == VLNK)
416 		vap->va_size = strlen(de->de_symlink);
417 	else if (vp->v_type == VDIR)
418 		vap->va_size = vap->va_bytes = DEV_BSIZE;
419 	else
420 		vap->va_size = 0;
421 	if (vp->v_type != VDIR)
422 		vap->va_bytes = 0;
423 	vap->va_blocksize = DEV_BSIZE;
424 	vap->va_type = vp->v_type;
425 
426 #define fix(aa)							\
427 	do {							\
428 		if ((aa).tv_sec == 0) {				\
429 			(aa).tv_sec = boottime.tv_sec;		\
430 			(aa).tv_nsec = boottime.tv_usec * 1000; \
431 		}						\
432 	} while (0)
433 
434 	if (vp->v_type != VCHR)  {
435 		fix(de->de_atime);
436 		vap->va_atime = de->de_atime;
437 		fix(de->de_mtime);
438 		vap->va_mtime = de->de_mtime;
439 		fix(de->de_ctime);
440 		vap->va_ctime = de->de_ctime;
441 	} else {
442 		dev = vp->v_rdev;
443 		fix(dev->si_atime);
444 		vap->va_atime = dev->si_atime;
445 		fix(dev->si_mtime);
446 		vap->va_mtime = dev->si_mtime;
447 		fix(dev->si_ctime);
448 		vap->va_ctime = dev->si_ctime;
449 
450 		vap->va_rdev = dev->si_priv->cdp_inode;
451 	}
452 	vap->va_gen = 0;
453 	vap->va_flags = 0;
454 	vap->va_nlink = de->de_links;
455 	vap->va_fileid = de->de_inode;
456 
457 	return (error);
458 }
459 
460 /* ARGSUSED */
461 static int
462 devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td)
463 {
464 	struct cdev *dev;
465 	struct cdevsw *dsw;
466 	struct vnode *vp;
467 	struct vnode *vpold;
468 	int error, i;
469 	const char *p;
470 	struct fiodgname_arg *fgn;
471 
472 	error = devfs_fp_check(fp, &dev, &dsw);
473 	if (error)
474 		return (error);
475 
476 	if (com == FIODTYPE) {
477 		*(int *)data = dsw->d_flags & D_TYPEMASK;
478 		dev_relthread(dev);
479 		return (0);
480 	} else if (com == FIODGNAME) {
481 		fgn = data;
482 		p = devtoname(dev);
483 		i = strlen(p) + 1;
484 		if (i > fgn->len)
485 			error = EINVAL;
486 		else
487 			error = copyout(p, fgn->buf, i);
488 		dev_relthread(dev);
489 		return (error);
490 	}
491 	error = dsw->d_ioctl(dev, com, data, fp->f_flag, td);
492 	dev_relthread(dev);
493 	if (error == ENOIOCTL)
494 		error = ENOTTY;
495 	if (error == 0 && com == TIOCSCTTY) {
496 		vp = fp->f_vnode;
497 
498 		/* Do nothing if reassigning same control tty */
499 		sx_slock(&proctree_lock);
500 		if (td->td_proc->p_session->s_ttyvp == vp) {
501 			sx_sunlock(&proctree_lock);
502 			return (0);
503 		}
504 
505 		mtx_lock(&Giant);
506 
507 		vpold = td->td_proc->p_session->s_ttyvp;
508 		VREF(vp);
509 		SESS_LOCK(td->td_proc->p_session);
510 		td->td_proc->p_session->s_ttyvp = vp;
511 		SESS_UNLOCK(td->td_proc->p_session);
512 
513 		sx_sunlock(&proctree_lock);
514 
515 		/* Get rid of reference to old control tty */
516 		if (vpold)
517 			vrele(vpold);
518 		mtx_unlock(&Giant);
519 	}
520 	return (error);
521 }
522 
523 /* ARGSUSED */
524 static int
525 devfs_kqfilter_f(struct file *fp, struct knote *kn)
526 {
527 	struct cdev *dev;
528 	struct cdevsw *dsw;
529 	int error;
530 
531 	error = devfs_fp_check(fp, &dev, &dsw);
532 	if (error)
533 		return (error);
534 	error = dsw->d_kqfilter(dev, kn);
535 	dev_relthread(dev);
536 	return (error);
537 }
538 
539 static int
540 devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
541 {
542 	struct componentname *cnp;
543 	struct vnode *dvp, **vpp;
544 	struct thread *td;
545 	struct devfs_dirent *de, *dd;
546 	struct devfs_dirent **dde;
547 	struct devfs_mount *dmp;
548 	struct cdev *cdev;
549 	int error, flags, nameiop;
550 	char specname[SPECNAMELEN + 1], *pname;
551 
552 	cnp = ap->a_cnp;
553 	vpp = ap->a_vpp;
554 	dvp = ap->a_dvp;
555 	pname = cnp->cn_nameptr;
556 	td = cnp->cn_thread;
557 	flags = cnp->cn_flags;
558 	nameiop = cnp->cn_nameiop;
559 	dmp = VFSTODEVFS(dvp->v_mount);
560 	dd = dvp->v_data;
561 	*vpp = NULLVP;
562 
563 	if ((flags & ISLASTCN) && nameiop == RENAME)
564 		return (EOPNOTSUPP);
565 
566 	if (dvp->v_type != VDIR)
567 		return (ENOTDIR);
568 
569 	if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT))
570 		return (EIO);
571 
572 	error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
573 	if (error)
574 		return (error);
575 
576 	if (cnp->cn_namelen == 1 && *pname == '.') {
577 		if ((flags & ISLASTCN) && nameiop != LOOKUP)
578 			return (EINVAL);
579 		*vpp = dvp;
580 		VREF(dvp);
581 		return (0);
582 	}
583 
584 	if (flags & ISDOTDOT) {
585 		if ((flags & ISLASTCN) && nameiop != LOOKUP)
586 			return (EINVAL);
587 		VOP_UNLOCK(dvp, 0, td);
588 		de = TAILQ_FIRST(&dd->de_dlist);	/* "." */
589 		de = TAILQ_NEXT(de, de_list);		/* ".." */
590 		de = de->de_dir;
591 		error = devfs_allocv(de, dvp->v_mount, vpp, td);
592 		*dm_unlock = 0;
593 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
594 		return (error);
595 	}
596 
597 	DEVFS_DMP_HOLD(dmp);
598 	devfs_populate(dmp);
599 	if (DEVFS_DMP_DROP(dmp)) {
600 		*dm_unlock = 0;
601 		sx_xunlock(&dmp->dm_lock);
602 		devfs_unmount_final(dmp);
603 		return (ENOENT);
604 	}
605 	dd = dvp->v_data;
606 	de = devfs_find(dd, cnp->cn_nameptr, cnp->cn_namelen);
607 	while (de == NULL) {	/* While(...) so we can use break */
608 
609 		if (nameiop == DELETE)
610 			return (ENOENT);
611 
612 		/*
613 		 * OK, we didn't have an entry for the name we were asked for
614 		 * so we try to see if anybody can create it on demand.
615 		 */
616 		pname = devfs_fqpn(specname, dvp, cnp);
617 		if (pname == NULL)
618 			break;
619 
620 		cdev = NULL;
621 		EVENTHANDLER_INVOKE(dev_clone,
622 		    td->td_ucred, pname, strlen(pname), &cdev);
623 		if (cdev == NULL)
624 			break;
625 
626 		DEVFS_DMP_HOLD(dmp);
627 		devfs_populate(dmp);
628 		if (DEVFS_DMP_DROP(dmp)) {
629 			*dm_unlock = 0;
630 			sx_xunlock(&dmp->dm_lock);
631 			devfs_unmount_final(dmp);
632 			return (ENOENT);
633 		}
634 
635 		dev_lock();
636 		dde = &cdev->si_priv->cdp_dirents[dmp->dm_idx];
637 		if (dde != NULL && *dde != NULL)
638 			de = *dde;
639 		dev_unlock();
640 		dev_rel(cdev);
641 		break;
642 	}
643 
644 	if (de == NULL || de->de_flags & DE_WHITEOUT) {
645 		if ((nameiop == CREATE || nameiop == RENAME) &&
646 		    (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
647 			cnp->cn_flags |= SAVENAME;
648 			return (EJUSTRETURN);
649 		}
650 		return (ENOENT);
651 	}
652 
653 	if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
654 		error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
655 		if (error)
656 			return (error);
657 		if (*vpp == dvp) {
658 			VREF(dvp);
659 			*vpp = dvp;
660 			return (0);
661 		}
662 	}
663 	error = devfs_allocv(de, dvp->v_mount, vpp, td);
664 	*dm_unlock = 0;
665 	return (error);
666 }
667 
668 static int
669 devfs_lookup(struct vop_lookup_args *ap)
670 {
671 	int j;
672 	struct devfs_mount *dmp;
673 	int dm_unlock;
674 
675 	dmp = VFSTODEVFS(ap->a_dvp->v_mount);
676 	dm_unlock = 1;
677 	sx_xlock(&dmp->dm_lock);
678 	j = devfs_lookupx(ap, &dm_unlock);
679 	if (dm_unlock == 1)
680 		sx_xunlock(&dmp->dm_lock);
681 	return (j);
682 }
683 
684 static int
685 devfs_mknod(struct vop_mknod_args *ap)
686 {
687 	struct componentname *cnp;
688 	struct vnode *dvp, **vpp;
689 	struct thread *td;
690 	struct devfs_dirent *dd, *de;
691 	struct devfs_mount *dmp;
692 	int error;
693 
694 	/*
695 	 * The only type of node we should be creating here is a
696 	 * character device, for anything else return EOPNOTSUPP.
697 	 */
698 	if (ap->a_vap->va_type != VCHR)
699 		return (EOPNOTSUPP);
700 	dvp = ap->a_dvp;
701 	dmp = VFSTODEVFS(dvp->v_mount);
702 
703 	cnp = ap->a_cnp;
704 	vpp = ap->a_vpp;
705 	td = cnp->cn_thread;
706 	dd = dvp->v_data;
707 
708 	error = ENOENT;
709 	sx_xlock(&dmp->dm_lock);
710 	TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
711 		if (cnp->cn_namelen != de->de_dirent->d_namlen)
712 			continue;
713 		if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
714 		    de->de_dirent->d_namlen) != 0)
715 			continue;
716 		if (de->de_flags & DE_WHITEOUT)
717 			break;
718 		goto notfound;
719 	}
720 	if (de == NULL)
721 		goto notfound;
722 	de->de_flags &= ~DE_WHITEOUT;
723 	error = devfs_allocv(de, dvp->v_mount, vpp, td);
724 	return (error);
725 notfound:
726 	sx_xunlock(&dmp->dm_lock);
727 	return (error);
728 }
729 
730 /* ARGSUSED */
731 static int
732 devfs_open(struct vop_open_args *ap)
733 {
734 	struct thread *td = ap->a_td;
735 	struct vnode *vp = ap->a_vp;
736 	struct cdev *dev = vp->v_rdev;
737 	struct file *fp;
738 	int error;
739 	struct cdevsw *dsw;
740 
741 	if (vp->v_type == VBLK)
742 		return (ENXIO);
743 
744 	if (dev == NULL)
745 		return (ENXIO);
746 
747 	/* Make this field valid before any I/O in d_open. */
748 	if (dev->si_iosize_max == 0)
749 		dev->si_iosize_max = DFLTPHYS;
750 
751 	dsw = dev_refthread(dev);
752 	if (dsw == NULL)
753 		return (ENXIO);
754 
755 	/* XXX: Special casing of ttys for deadfs.  Probably redundant. */
756 	if (dsw->d_flags & D_TTY)
757 		vp->v_vflag |= VV_ISTTY;
758 
759 	VOP_UNLOCK(vp, 0, td);
760 
761 	if(!(dsw->d_flags & D_NEEDGIANT)) {
762 		DROP_GIANT();
763 		if (dsw->d_fdopen != NULL)
764 			error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx);
765 		else
766 			error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
767 		PICKUP_GIANT();
768 	} else {
769 		if (dsw->d_fdopen != NULL)
770 			error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx);
771 		else
772 			error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
773 	}
774 
775 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
776 
777 	dev_relthread(dev);
778 
779 	if (error)
780 		return (error);
781 
782 #if 0	/* /dev/console */
783 	KASSERT(ap->a_fdidx >= 0,
784 	     ("Could not vnode bypass device on fd %d", ap->a_fdidx));
785 #else
786 	if(ap->a_fdidx < 0)
787 		return (error);
788 #endif
789 	/*
790 	 * This is a pretty disgustingly long chain, but I am not
791 	 * sure there is any better way.  Passing the fdidx into
792 	 * VOP_OPEN() offers us more information than just passing
793 	 * the file *.
794 	 */
795 	fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx];
796 	KASSERT(fp->f_ops == &badfileops,
797 	     ("Could not vnode bypass device on fdops %p", fp->f_ops));
798 	fp->f_ops = &devfs_ops_f;
799 	fp->f_data = dev;
800 	return (error);
801 }
802 
803 static int
804 devfs_pathconf(struct vop_pathconf_args *ap)
805 {
806 
807 	switch (ap->a_name) {
808 	case _PC_MAC_PRESENT:
809 #ifdef MAC
810 		/*
811 		 * If MAC is enabled, devfs automatically supports
812 		 * trivial non-persistant label storage.
813 		 */
814 		*ap->a_retval = 1;
815 #else
816 		*ap->a_retval = 0;
817 #endif
818 		return (0);
819 	default:
820 		return (vop_stdpathconf(ap));
821 	}
822 	/* NOTREACHED */
823 }
824 
825 /* ARGSUSED */
826 static int
827 devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
828 {
829 	struct cdev *dev;
830 	struct cdevsw *dsw;
831 	int error;
832 
833 	error = devfs_fp_check(fp, &dev, &dsw);
834 	if (error)
835 		return (error);
836 	error = dsw->d_poll(dev, events, td);
837 	dev_relthread(dev);
838 	return(error);
839 }
840 
841 /*
842  * Print out the contents of a special device vnode.
843  */
844 static int
845 devfs_print(struct vop_print_args *ap)
846 {
847 
848 	printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev));
849 	return (0);
850 }
851 
852 /* ARGSUSED */
853 static int
854 devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
855 {
856 	struct cdev *dev;
857 	int ioflag, error, resid;
858 	struct cdevsw *dsw;
859 
860 	error = devfs_fp_check(fp, &dev, &dsw);
861 	if (error)
862 		return (error);
863 	resid = uio->uio_resid;
864 	ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT);
865 	if (ioflag & O_DIRECT)
866 		ioflag |= IO_DIRECT;
867 
868 	if ((flags & FOF_OFFSET) == 0)
869 		uio->uio_offset = fp->f_offset;
870 
871 	error = dsw->d_read(dev, uio, ioflag);
872 	if (uio->uio_resid != resid || (error == 0 && resid != 0))
873 		vfs_timestamp(&dev->si_atime);
874 	dev_relthread(dev);
875 
876 	if ((flags & FOF_OFFSET) == 0)
877 		fp->f_offset = uio->uio_offset;
878 	fp->f_nextoff = uio->uio_offset;
879 	return (error);
880 }
881 
882 static int
883 devfs_readdir(struct vop_readdir_args *ap)
884 {
885 	int error;
886 	struct uio *uio;
887 	struct dirent *dp;
888 	struct devfs_dirent *dd;
889 	struct devfs_dirent *de;
890 	struct devfs_mount *dmp;
891 	off_t off, oldoff;
892 	int *tmp_ncookies = NULL;
893 
894 	if (ap->a_vp->v_type != VDIR)
895 		return (ENOTDIR);
896 
897 	uio = ap->a_uio;
898 	if (uio->uio_offset < 0)
899 		return (EINVAL);
900 
901 	/*
902 	 * XXX: This is a temporary hack to get around this filesystem not
903 	 * supporting cookies. We store the location of the ncookies pointer
904 	 * in a temporary variable before calling vfs_subr.c:vfs_read_dirent()
905 	 * and set the number of cookies to 0. We then set the pointer to
906 	 * NULL so that vfs_read_dirent doesn't try to call realloc() on
907 	 * ap->a_cookies. Later in this function, we restore the ap->a_ncookies
908 	 * pointer to its original location before returning to the caller.
909 	 */
910 	if (ap->a_ncookies != NULL) {
911 		tmp_ncookies = ap->a_ncookies;
912 		*ap->a_ncookies = 0;
913 		ap->a_ncookies = NULL;
914 	}
915 
916 	dmp = VFSTODEVFS(ap->a_vp->v_mount);
917 	sx_xlock(&dmp->dm_lock);
918 	DEVFS_DMP_HOLD(dmp);
919 	devfs_populate(dmp);
920 	if (DEVFS_DMP_DROP(dmp)) {
921 		sx_xunlock(&dmp->dm_lock);
922 		devfs_unmount_final(dmp);
923 		if (tmp_ncookies != NULL)
924 			ap->a_ncookies = tmp_ncookies;
925 		return (EIO);
926 	}
927 	error = 0;
928 	de = ap->a_vp->v_data;
929 	off = 0;
930 	oldoff = uio->uio_offset;
931 	TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
932 		KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
933 		if (dd->de_flags & DE_WHITEOUT)
934 			continue;
935 		if (dd->de_dirent->d_type == DT_DIR)
936 			de = dd->de_dir;
937 		else
938 			de = dd;
939 		dp = dd->de_dirent;
940 		if (dp->d_reclen > uio->uio_resid)
941 			break;
942 		dp->d_fileno = de->de_inode;
943 		if (off >= uio->uio_offset) {
944 			error = vfs_read_dirent(ap, dp, off);
945 			if (error)
946 				break;
947 		}
948 		off += dp->d_reclen;
949 	}
950 	sx_xunlock(&dmp->dm_lock);
951 	uio->uio_offset = off;
952 
953 	/*
954 	 * Restore ap->a_ncookies if it wasn't originally NULL in the first
955 	 * place.
956 	 */
957 	if (tmp_ncookies != NULL)
958 		ap->a_ncookies = tmp_ncookies;
959 
960 	return (error);
961 }
962 
963 static int
964 devfs_readlink(struct vop_readlink_args *ap)
965 {
966 	struct devfs_dirent *de;
967 
968 	de = ap->a_vp->v_data;
969 	return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio));
970 }
971 
972 static int
973 devfs_reclaim(struct vop_reclaim_args *ap)
974 {
975 	struct vnode *vp = ap->a_vp;
976 	struct devfs_dirent *de;
977 	struct cdev *dev;
978 
979 	mtx_lock(&devfs_de_interlock);
980 	de = vp->v_data;
981 	if (de != NULL) {
982 		de->de_vnode = NULL;
983 		vp->v_data = NULL;
984 	}
985 	mtx_unlock(&devfs_de_interlock);
986 
987 	vnode_destroy_vobject(vp);
988 
989 	dev_lock();
990 	dev = vp->v_rdev;
991 	vp->v_rdev = NULL;
992 
993 	if (dev == NULL) {
994 		dev_unlock();
995 		return (0);
996 	}
997 
998 	dev->si_usecount -= vp->v_usecount;
999 	dev_unlock();
1000 	dev_rel(dev);
1001 	return (0);
1002 }
1003 
1004 static int
1005 devfs_remove(struct vop_remove_args *ap)
1006 {
1007 	struct vnode *vp = ap->a_vp;
1008 	struct devfs_dirent *dd;
1009 	struct devfs_dirent *de;
1010 	struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
1011 
1012 	sx_xlock(&dmp->dm_lock);
1013 	dd = ap->a_dvp->v_data;
1014 	de = vp->v_data;
1015 	if (de->de_cdp == NULL) {
1016 		TAILQ_REMOVE(&dd->de_dlist, de, de_list);
1017 		devfs_delete(dmp, de, 1);
1018 	} else {
1019 		de->de_flags |= DE_WHITEOUT;
1020 	}
1021 	sx_xunlock(&dmp->dm_lock);
1022 	return (0);
1023 }
1024 
1025 /*
1026  * Revoke is called on a tty when a terminal session ends.  The vnode
1027  * is orphaned by setting v_op to deadfs so we need to let go of it
1028  * as well so that we create a new one next time around.
1029  *
1030  */
1031 static int
1032 devfs_revoke(struct vop_revoke_args *ap)
1033 {
1034 	struct vnode *vp = ap->a_vp, *vp2;
1035 	struct cdev *dev;
1036 	struct cdev_priv *cdp;
1037 	struct devfs_dirent *de;
1038 	int i;
1039 
1040 	KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
1041 
1042 	dev = vp->v_rdev;
1043 	cdp = dev->si_priv;
1044 
1045 	dev_lock();
1046 	cdp->cdp_inuse++;
1047 	dev_unlock();
1048 
1049 	vhold(vp);
1050 	vgone(vp);
1051 	vdrop(vp);
1052 
1053 	VOP_UNLOCK(vp,0,curthread);
1054  loop:
1055 	for (;;) {
1056 		mtx_lock(&devfs_de_interlock);
1057 		dev_lock();
1058 		vp2 = NULL;
1059 		for (i = 0; i <= cdp->cdp_maxdirent; i++) {
1060 			de = cdp->cdp_dirents[i];
1061 			if (de == NULL)
1062 				continue;
1063 
1064 			vp2 = de->de_vnode;
1065 			if (vp2 != NULL) {
1066 				dev_unlock();
1067 				VI_LOCK(vp2);
1068 				mtx_unlock(&devfs_de_interlock);
1069 				if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK,
1070 				    curthread))
1071 					goto loop;
1072 				vhold(vp2);
1073 				vgone(vp2);
1074 				vdrop(vp2);
1075 				vput(vp2);
1076 				break;
1077 			}
1078 		}
1079 		if (vp2 != NULL) {
1080 			continue;
1081 		}
1082 		dev_unlock();
1083 		mtx_unlock(&devfs_de_interlock);
1084 		break;
1085 	}
1086 	dev_lock();
1087 	cdp->cdp_inuse--;
1088 	if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) {
1089 		TAILQ_REMOVE(&cdevp_list, cdp, cdp_list);
1090 		dev_unlock();
1091 		dev_rel(&cdp->cdp_c);
1092 	} else
1093 		dev_unlock();
1094 
1095 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
1096 	return (0);
1097 }
1098 
1099 static int
1100 devfs_rioctl(struct vop_ioctl_args *ap)
1101 {
1102 	int error;
1103 	struct devfs_mount *dmp;
1104 
1105 	dmp = VFSTODEVFS(ap->a_vp->v_mount);
1106 	sx_xlock(&dmp->dm_lock);
1107 	DEVFS_DMP_HOLD(dmp);
1108 	devfs_populate(dmp);
1109 	if (DEVFS_DMP_DROP(dmp)) {
1110 		sx_xunlock(&dmp->dm_lock);
1111 		devfs_unmount_final(dmp);
1112 		return (ENOENT);
1113 	}
1114 	error = devfs_rules_ioctl(dmp, ap->a_command, ap->a_data, ap->a_td);
1115 	sx_xunlock(&dmp->dm_lock);
1116 	return (error);
1117 }
1118 
1119 static int
1120 devfs_rread(struct vop_read_args *ap)
1121 {
1122 
1123 	if (ap->a_vp->v_type != VDIR)
1124 		return (EINVAL);
1125 	return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL));
1126 }
1127 
1128 static int
1129 devfs_setattr(struct vop_setattr_args *ap)
1130 {
1131 	struct devfs_dirent *de;
1132 	struct vattr *vap;
1133 	struct vnode *vp;
1134 	int c, error;
1135 	uid_t uid;
1136 	gid_t gid;
1137 
1138 	vap = ap->a_vap;
1139 	vp = ap->a_vp;
1140 	if ((vap->va_type != VNON) ||
1141 	    (vap->va_nlink != VNOVAL) ||
1142 	    (vap->va_fsid != VNOVAL) ||
1143 	    (vap->va_fileid != VNOVAL) ||
1144 	    (vap->va_blocksize != VNOVAL) ||
1145 	    (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1146 	    (vap->va_rdev != VNOVAL) ||
1147 	    ((int)vap->va_bytes != VNOVAL) ||
1148 	    (vap->va_gen != VNOVAL)) {
1149 		return (EINVAL);
1150 	}
1151 
1152 	de = vp->v_data;
1153 	if (vp->v_type == VDIR)
1154 		de = de->de_dir;
1155 
1156 	error = c = 0;
1157 	if (vap->va_uid == (uid_t)VNOVAL)
1158 		uid = de->de_uid;
1159 	else
1160 		uid = vap->va_uid;
1161 	if (vap->va_gid == (gid_t)VNOVAL)
1162 		gid = de->de_gid;
1163 	else
1164 		gid = vap->va_gid;
1165 	if (uid != de->de_uid || gid != de->de_gid) {
1166 		if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
1167 		    (gid != de->de_gid && !groupmember(gid, ap->a_cred))) {
1168 			error = priv_check_cred(ap->a_td->td_ucred,
1169 			    PRIV_VFS_CHOWN, SUSER_ALLOWJAIL);
1170 			if (error)
1171 				return (error);
1172 		}
1173 		de->de_uid = uid;
1174 		de->de_gid = gid;
1175 		c = 1;
1176 	}
1177 
1178 	if (vap->va_mode != (mode_t)VNOVAL) {
1179 		if (ap->a_cred->cr_uid != de->de_uid) {
1180 			error = priv_check_cred(ap->a_td->td_ucred,
1181 			    PRIV_VFS_ADMIN, SUSER_ALLOWJAIL);
1182 			if (error)
1183 				return (error);
1184 		}
1185 		de->de_mode = vap->va_mode;
1186 		c = 1;
1187 	}
1188 
1189 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1190 		/* See the comment in ufs_vnops::ufs_setattr(). */
1191 		if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)) &&
1192 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
1193 		    (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td))))
1194 			return (error);
1195 		if (vap->va_atime.tv_sec != VNOVAL) {
1196 			if (vp->v_type == VCHR)
1197 				vp->v_rdev->si_atime = vap->va_atime;
1198 			else
1199 				de->de_atime = vap->va_atime;
1200 		}
1201 		if (vap->va_mtime.tv_sec != VNOVAL) {
1202 			if (vp->v_type == VCHR)
1203 				vp->v_rdev->si_mtime = vap->va_mtime;
1204 			else
1205 				de->de_mtime = vap->va_mtime;
1206 		}
1207 		c = 1;
1208 	}
1209 
1210 	if (c) {
1211 		if (vp->v_type == VCHR)
1212 			vfs_timestamp(&vp->v_rdev->si_ctime);
1213 		else
1214 			vfs_timestamp(&de->de_mtime);
1215 	}
1216 	return (0);
1217 }
1218 
1219 #ifdef MAC
1220 static int
1221 devfs_setlabel(struct vop_setlabel_args *ap)
1222 {
1223 	struct vnode *vp;
1224 	struct devfs_dirent *de;
1225 
1226 	vp = ap->a_vp;
1227 	de = vp->v_data;
1228 
1229 	mac_relabel_vnode(ap->a_cred, vp, ap->a_label);
1230 	mac_update_devfsdirent(vp->v_mount, de, vp);
1231 
1232 	return (0);
1233 }
1234 #endif
1235 
1236 static int
1237 devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
1238 {
1239 
1240 	return (vnops.fo_stat(fp, sb, cred, td));
1241 }
1242 
1243 static int
1244 devfs_symlink(struct vop_symlink_args *ap)
1245 {
1246 	int i, error;
1247 	struct devfs_dirent *dd;
1248 	struct devfs_dirent *de;
1249 	struct devfs_mount *dmp;
1250 	struct thread *td;
1251 
1252 	td = ap->a_cnp->cn_thread;
1253 	KASSERT(td == curthread, ("devfs_symlink: td != curthread"));
1254 
1255 	error = priv_check(td, PRIV_DEVFS_SYMLINK);
1256 	if (error)
1257 		return(error);
1258 	dmp = VFSTODEVFS(ap->a_dvp->v_mount);
1259 	dd = ap->a_dvp->v_data;
1260 	de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
1261 	de->de_uid = 0;
1262 	de->de_gid = 0;
1263 	de->de_mode = 0755;
1264 	de->de_inode = alloc_unr(devfs_inos);
1265 	de->de_dirent->d_type = DT_LNK;
1266 	i = strlen(ap->a_target) + 1;
1267 	de->de_symlink = malloc(i, M_DEVFS, M_WAITOK);
1268 	bcopy(ap->a_target, de->de_symlink, i);
1269 	sx_xlock(&dmp->dm_lock);
1270 #ifdef MAC
1271 	mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de);
1272 #endif
1273 	TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list);
1274 	return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td));
1275 }
1276 
1277 /* ARGSUSED */
1278 static int
1279 devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
1280 {
1281 	struct cdev *dev;
1282 	int error, ioflag, resid;
1283 	struct cdevsw *dsw;
1284 
1285 	error = devfs_fp_check(fp, &dev, &dsw);
1286 	if (error)
1287 		return (error);
1288 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
1289 	ioflag = fp->f_flag & (O_NONBLOCK | O_DIRECT | O_FSYNC);
1290 	if (ioflag & O_DIRECT)
1291 		ioflag |= IO_DIRECT;
1292 	if ((flags & FOF_OFFSET) == 0)
1293 		uio->uio_offset = fp->f_offset;
1294 
1295 	resid = uio->uio_resid;
1296 
1297 	error = dsw->d_write(dev, uio, ioflag);
1298 	if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
1299 		vfs_timestamp(&dev->si_ctime);
1300 		dev->si_mtime = dev->si_ctime;
1301 	}
1302 	dev_relthread(dev);
1303 
1304 	if ((flags & FOF_OFFSET) == 0)
1305 		fp->f_offset = uio->uio_offset;
1306 	fp->f_nextoff = uio->uio_offset;
1307 	return (error);
1308 }
1309 
1310 dev_t
1311 dev2udev(struct cdev *x)
1312 {
1313 	if (x == NULL)
1314 		return (NODEV);
1315 	return (x->si_priv->cdp_inode);
1316 }
1317 
1318 static struct fileops devfs_ops_f = {
1319 	.fo_read =	devfs_read_f,
1320 	.fo_write =	devfs_write_f,
1321 	.fo_ioctl =	devfs_ioctl_f,
1322 	.fo_poll =	devfs_poll_f,
1323 	.fo_kqfilter =	devfs_kqfilter_f,
1324 	.fo_stat =	devfs_stat_f,
1325 	.fo_close =	devfs_close_f,
1326 	.fo_flags =	DFLAG_PASSABLE | DFLAG_SEEKABLE
1327 };
1328 
1329 static struct vop_vector devfs_vnodeops = {
1330 	.vop_default =		&default_vnodeops,
1331 
1332 	.vop_access =		devfs_access,
1333 	.vop_getattr =		devfs_getattr,
1334 	.vop_ioctl =		devfs_rioctl,
1335 	.vop_lookup =		devfs_lookup,
1336 	.vop_mknod =		devfs_mknod,
1337 	.vop_pathconf =		devfs_pathconf,
1338 	.vop_read =		devfs_rread,
1339 	.vop_readdir =		devfs_readdir,
1340 	.vop_readlink =		devfs_readlink,
1341 	.vop_reclaim =		devfs_reclaim,
1342 	.vop_remove =		devfs_remove,
1343 	.vop_revoke =		devfs_revoke,
1344 	.vop_setattr =		devfs_setattr,
1345 #ifdef MAC
1346 	.vop_setlabel =		devfs_setlabel,
1347 #endif
1348 	.vop_symlink =		devfs_symlink,
1349 };
1350 
1351 static struct vop_vector devfs_specops = {
1352 	.vop_default =		&default_vnodeops,
1353 
1354 	.vop_access =		devfs_access,
1355 	.vop_advlock =		devfs_advlock,
1356 	.vop_bmap =		VOP_PANIC,
1357 	.vop_close =		devfs_close,
1358 	.vop_create =		VOP_PANIC,
1359 	.vop_fsync =		devfs_fsync,
1360 	.vop_getattr =		devfs_getattr,
1361 	.vop_lease =		VOP_NULL,
1362 	.vop_link =		VOP_PANIC,
1363 	.vop_mkdir =		VOP_PANIC,
1364 	.vop_mknod =		VOP_PANIC,
1365 	.vop_open =		devfs_open,
1366 	.vop_pathconf =		devfs_pathconf,
1367 	.vop_print =		devfs_print,
1368 	.vop_read =		VOP_PANIC,
1369 	.vop_readdir =		VOP_PANIC,
1370 	.vop_readlink =		VOP_PANIC,
1371 	.vop_reallocblks =	VOP_PANIC,
1372 	.vop_reclaim =		devfs_reclaim,
1373 	.vop_remove =		devfs_remove,
1374 	.vop_rename =		VOP_PANIC,
1375 	.vop_revoke =		devfs_revoke,
1376 	.vop_rmdir =		VOP_PANIC,
1377 	.vop_setattr =		devfs_setattr,
1378 #ifdef MAC
1379 	.vop_setlabel =		devfs_setlabel,
1380 #endif
1381 	.vop_strategy =		VOP_PANIC,
1382 	.vop_symlink =		VOP_PANIC,
1383 	.vop_write =		VOP_PANIC,
1384 };
1385 
1386 /*
1387  * Our calling convention to the device drivers used to be that we passed
1388  * vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_
1389  * flags instead since that's what open(), close() and ioctl() takes and
1390  * we don't really want vnode.h in device drivers.
1391  * We solved the source compatibility by redefining some vnode flags to
1392  * be the same as the fcntl ones and by sending down the bitwise OR of
1393  * the respective fcntl/vnode flags.  These CTASSERTS make sure nobody
1394  * pulls the rug out under this.
1395  */
1396 CTASSERT(O_NONBLOCK == IO_NDELAY);
1397 CTASSERT(O_FSYNC == IO_SYNC);
1398