xref: /freebsd/sys/fs/devfs/devfs_vnops.c (revision 89f087e8dd48876b8a9821c6f7aac4b74f6aaf9e)
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  *	mknod: hunt down DE_DELETED, compare name, reinstantiate.
41  *	mkdir: want it ?
42  */
43 
44 #include <opt_devfs.h>
45 #include <opt_mac.h>
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/conf.h>
50 #include <sys/dirent.h>
51 #include <sys/fcntl.h>
52 #include <sys/file.h>
53 #include <sys/filedesc.h>
54 #include <sys/filio.h>
55 #include <sys/kernel.h>
56 #include <sys/lock.h>
57 #include <sys/mac.h>
58 #include <sys/malloc.h>
59 #include <sys/mount.h>
60 #include <sys/namei.h>
61 #include <sys/proc.h>
62 #include <sys/stat.h>
63 #include <sys/sx.h>
64 #include <sys/time.h>
65 #include <sys/ttycom.h>
66 #include <sys/unistd.h>
67 #include <sys/vnode.h>
68 
69 #include <fs/devfs/devfs.h>
70 
71 static fo_rdwr_t	devfs_read_f;
72 static fo_rdwr_t	devfs_write_f;
73 static fo_ioctl_t	devfs_ioctl_f;
74 static fo_poll_t	devfs_poll_f;
75 static fo_kqfilter_t	devfs_kqfilter_f;
76 static fo_stat_t	devfs_stat_f;
77 static fo_close_t	devfs_close_f;
78 
79 struct fileops devfs_ops_f = {
80 	.fo_read =	devfs_read_f,
81 	.fo_write =	devfs_write_f,
82 	.fo_ioctl =	devfs_ioctl_f,
83 	.fo_poll =	devfs_poll_f,
84 	.fo_kqfilter =	devfs_kqfilter_f,
85 	.fo_stat =	devfs_stat_f,
86 	.fo_close =	devfs_close_f,
87 	.fo_flags =	DFLAG_PASSABLE | DFLAG_SEEKABLE
88 };
89 
90 static vop_access_t	devfs_access;
91 static vop_advlock_t	devfs_advlock;
92 static vop_close_t	devfs_close;
93 static vop_fsync_t	devfs_fsync;
94 static vop_getattr_t	devfs_getattr;
95 static vop_lookup_t	devfs_lookupx;
96 static vop_mknod_t	devfs_mknod;
97 static vop_open_t	devfs_open;
98 static vop_pathconf_t	devfs_pathconf;
99 static vop_print_t	devfs_print;
100 static vop_readdir_t	devfs_readdir;
101 static vop_readlink_t	devfs_readlink;
102 static vop_reclaim_t	devfs_reclaim;
103 static vop_remove_t	devfs_remove;
104 static vop_revoke_t	devfs_revoke;
105 static vop_ioctl_t	devfs_rioctl;
106 static vop_read_t	devfs_rread;
107 static vop_setattr_t	devfs_setattr;
108 #ifdef MAC
109 static vop_setlabel_t	devfs_setlabel;
110 #endif
111 static vop_symlink_t	devfs_symlink;
112 
113 extern struct vop_vector devfs_vnodeops;
114 
115 static int
116 devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp)
117 {
118 
119 	*devp = fp->f_vnode->v_rdev;
120 	if (*devp != fp->f_data)
121 		return (ENXIO);
122 	KASSERT((*devp)->si_refcount > 0,
123 	    ("devfs: un-referenced struct cdev *(%s)", devtoname(*devp)));
124 	*dswp = dev_refthread(*devp);
125 	if (*dswp == NULL)
126 		return (ENXIO);
127 	return (0);
128 }
129 
130 /*
131  * Construct the fully qualified path name relative to the mountpoint
132  */
133 static char *
134 devfs_fqpn(char *buf, struct vnode *dvp, struct componentname *cnp)
135 {
136 	int i;
137 	struct devfs_dirent *de, *dd;
138 	struct devfs_mount *dmp;
139 
140 	dmp = VFSTODEVFS(dvp->v_mount);
141 	dd = dvp->v_data;
142 	i = SPECNAMELEN;
143 	buf[i] = '\0';
144 	i -= cnp->cn_namelen;
145 	if (i < 0)
146 		 return (NULL);
147 	bcopy(cnp->cn_nameptr, buf + i, cnp->cn_namelen);
148 	de = dd;
149 	while (de != dmp->dm_basedir) {
150 		i--;
151 		if (i < 0)
152 			 return (NULL);
153 		buf[i] = '/';
154 		i -= de->de_dirent->d_namlen;
155 		if (i < 0)
156 			 return (NULL);
157 		bcopy(de->de_dirent->d_name, buf + i,
158 		    de->de_dirent->d_namlen);
159 		de = TAILQ_FIRST(&de->de_dlist);	/* "." */
160 		de = TAILQ_NEXT(de, de_list);		/* ".." */
161 		de = de->de_dir;
162 	}
163 	return (buf + i);
164 }
165 
166 int
167 devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td)
168 {
169 	int error;
170 	struct vnode *vp;
171 	struct cdev *dev;
172 
173 	KASSERT(td == curthread, ("devfs_allocv: td != curthread"));
174 loop:
175 	vp = de->de_vnode;
176 	if (vp != NULL) {
177 		if (vget(vp, LK_EXCLUSIVE, td))
178 			goto loop;
179 		*vpp = vp;
180 		return (0);
181 	}
182 	if (de->de_dirent->d_type == DT_CHR) {
183 		dev = *devfs_itod(de->de_inode);
184 		if (dev == NULL)
185 			return (ENOENT);
186 	} else {
187 		dev = NULL;
188 	}
189 	error = getnewvnode("devfs", mp, &devfs_vnodeops, &vp);
190 	if (error != 0) {
191 		printf("devfs_allocv: failed to allocate new vnode\n");
192 		return (error);
193 	}
194 
195 	if (de->de_dirent->d_type == DT_CHR) {
196 		vp->v_type = VCHR;
197 		VI_LOCK(vp);
198 		dev_lock();
199 		dev->si_refcount++;
200 		vp->v_rdev = dev;
201 		SLIST_INSERT_HEAD(&dev->si_hlist, vp, v_specnext);
202 		dev->si_usecount += vp->v_usecount;
203 		dev_unlock();
204 		VI_UNLOCK(vp);
205 		vp->v_op = &devfs_specops;
206 	} else if (de->de_dirent->d_type == DT_DIR) {
207 		vp->v_type = VDIR;
208 	} else if (de->de_dirent->d_type == DT_LNK) {
209 		vp->v_type = VLNK;
210 	} else {
211 		vp->v_type = VBAD;
212 	}
213 	vp->v_data = de;
214 	de->de_vnode = vp;
215 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
216 #ifdef MAC
217 	mac_associate_vnode_devfs(mp, de, vp);
218 #endif
219 	*vpp = vp;
220 	return (0);
221 }
222 
223 static int
224 devfs_access(ap)
225 	struct vop_access_args /* {
226 		struct vnode *a_vp;
227 		int  a_mode;
228 		struct ucred *a_cred;
229 		struct thread *a_td;
230 	} */ *ap;
231 {
232 	struct vnode *vp = ap->a_vp;
233 	struct devfs_dirent *de;
234 	int error;
235 
236 	de = vp->v_data;
237 	if (vp->v_type == VDIR)
238 		de = de->de_dir;
239 
240 	error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
241 	    ap->a_mode, ap->a_cred, NULL);
242 	if (!error)
243 		return (error);
244 	if (error != EACCES)
245 		return (error);
246 	/* We do, however, allow access to the controlling terminal */
247 	if (!(ap->a_td->td_proc->p_flag & P_CONTROLT))
248 		return (error);
249 	if (ap->a_td->td_proc->p_session->s_ttyvp == de->de_vnode)
250 		return (0);
251 	return (error);
252 }
253 
254 /*
255  * Special device advisory byte-level locks.
256  */
257 /* ARGSUSED */
258 static int
259 devfs_advlock(ap)
260 	struct vop_advlock_args /* {
261 		struct vnode *a_vp;
262 		caddr_t  a_id;
263 		int  a_op;
264 		struct flock *a_fl;
265 		int  a_flags;
266 	} */ *ap;
267 {
268 
269 	return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
270 }
271 
272 /*
273  * Device close routine
274  */
275 /* ARGSUSED */
276 static int
277 devfs_close(ap)
278 	struct vop_close_args /* {
279 		struct vnode *a_vp;
280 		int  a_fflag;
281 		struct ucred *a_cred;
282 		struct thread *a_td;
283 	} */ *ap;
284 {
285 	struct vnode *vp = ap->a_vp, *oldvp;
286 	struct thread *td = ap->a_td;
287 	struct cdev *dev = vp->v_rdev;
288 	struct cdevsw *dsw;
289 	int error;
290 
291 	/*
292 	 * Hack: a tty device that is a controlling terminal
293 	 * has a reference from the session structure.
294 	 * We cannot easily tell that a character device is
295 	 * a controlling terminal, unless it is the closing
296 	 * process' controlling terminal.  In that case,
297 	 * if the reference count is 2 (this last descriptor
298 	 * plus the session), release the reference from the session.
299 	 */
300 
301 	/*
302 	 * This needs to be rewritten to take the vp interlock into
303 	 * consideration.
304 	 */
305 
306 	oldvp = NULL;
307 	sx_xlock(&proctree_lock);
308 	if (td && vp == td->td_proc->p_session->s_ttyvp) {
309 		SESS_LOCK(td->td_proc->p_session);
310 		VI_LOCK(vp);
311 		if (count_dev(dev) == 2 && (vp->v_iflag & VI_XLOCK) == 0) {
312 			td->td_proc->p_session->s_ttyvp = NULL;
313 			oldvp = vp;
314 		}
315 		VI_UNLOCK(vp);
316 		SESS_UNLOCK(td->td_proc->p_session);
317 	}
318 	sx_xunlock(&proctree_lock);
319 	if (oldvp != NULL)
320 		vrele(oldvp);
321 	/*
322 	 * We do not want to really close the device if it
323 	 * is still in use unless we are trying to close it
324 	 * forcibly. Since every use (buffer, vnode, swap, cmap)
325 	 * holds a reference to the vnode, and because we mark
326 	 * any other vnodes that alias this device, when the
327 	 * sum of the reference counts on all the aliased
328 	 * vnodes descends to one, we are on last close.
329 	 */
330 	dsw = dev_refthread(dev);
331 	if (dsw == NULL)
332 		return (ENXIO);
333 	VI_LOCK(vp);
334 	if (vp->v_iflag & VI_XLOCK) {
335 		/* Forced close. */
336 	} else if (dsw->d_flags & D_TRACKCLOSE) {
337 		/* Keep device updated on status. */
338 	} else if (count_dev(dev) > 1) {
339 		VI_UNLOCK(vp);
340 		dev_relthread(dev);
341 		return (0);
342 	}
343 	VI_UNLOCK(vp);
344 	KASSERT(dev->si_refcount > 0,
345 	    ("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
346 	if (!(dsw->d_flags & D_NEEDGIANT)) {
347 		DROP_GIANT();
348 		error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
349 		PICKUP_GIANT();
350 	} else
351 		error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
352 	dev_relthread(dev);
353 	return (error);
354 }
355 
356 static int
357 devfs_close_f(struct file *fp, struct thread *td)
358 {
359 
360 	return (vnops.fo_close(fp, td));
361 }
362 
363 /*
364  * Synch buffers associated with a block device
365  */
366 /* ARGSUSED */
367 static int
368 devfs_fsync(ap)
369 	struct vop_fsync_args /* {
370 		struct vnode *a_vp;
371 		struct ucred *a_cred;
372 		int  a_waitfor;
373 		struct thread *a_td;
374 	} */ *ap;
375 {
376 	if (!vn_isdisk(ap->a_vp, NULL))
377 		return (0);
378 
379 	return (vop_stdfsync(ap));
380 }
381 
382 static int
383 devfs_getattr(ap)
384 	struct vop_getattr_args /* {
385 		struct vnode *a_vp;
386 		struct vattr *a_vap;
387 		struct ucred *a_cred;
388 		struct thread *a_td;
389 	} */ *ap;
390 {
391 	struct vnode *vp = ap->a_vp;
392 	struct vattr *vap = ap->a_vap;
393 	int error = 0;
394 	struct devfs_dirent *de;
395 	struct cdev *dev;
396 
397 	de = vp->v_data;
398 	if (vp->v_type == VDIR)
399 		de = de->de_dir;
400 	bzero((caddr_t) vap, sizeof(*vap));
401 	vattr_null(vap);
402 	vap->va_uid = de->de_uid;
403 	vap->va_gid = de->de_gid;
404 	vap->va_mode = de->de_mode;
405 	if (vp->v_type == VLNK)
406 		vap->va_size = strlen(de->de_symlink);
407 	else if (vp->v_type == VDIR)
408 		vap->va_size = vap->va_bytes = DEV_BSIZE;
409 	else
410 		vap->va_size = 0;
411 	if (vp->v_type != VDIR)
412 		vap->va_bytes = 0;
413 	vap->va_blocksize = DEV_BSIZE;
414 	vap->va_type = vp->v_type;
415 
416 #define fix(aa)							\
417 	do {							\
418 		if ((aa).tv_sec == 0) {				\
419 			(aa).tv_sec = boottime.tv_sec;		\
420 			(aa).tv_nsec = boottime.tv_usec * 1000; \
421 		}						\
422 	} while (0)
423 
424 	if (vp->v_type != VCHR)  {
425 		fix(de->de_atime);
426 		vap->va_atime = de->de_atime;
427 		fix(de->de_mtime);
428 		vap->va_mtime = de->de_mtime;
429 		fix(de->de_ctime);
430 		vap->va_ctime = de->de_ctime;
431 	} else {
432 		dev = vp->v_rdev;
433 		fix(dev->si_atime);
434 		vap->va_atime = dev->si_atime;
435 		fix(dev->si_mtime);
436 		vap->va_mtime = dev->si_mtime;
437 		fix(dev->si_ctime);
438 		vap->va_ctime = dev->si_ctime;
439 		vap->va_rdev = dev->si_udev;
440 	}
441 	vap->va_gen = 0;
442 	vap->va_flags = 0;
443 	vap->va_nlink = de->de_links;
444 	vap->va_fileid = de->de_inode;
445 
446 	return (error);
447 }
448 
449 /*
450  * Device ioctl operation.
451  */
452 /* ARGSUSED */
453 static int
454 devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struct thread *td)
455 {
456 	struct cdev *dev;
457 	struct cdevsw *dsw;
458 	struct vnode *vp;
459 	struct vnode *vpold;
460 	int error;
461 
462 	error = devfs_fp_check(fp, &dev, &dsw);
463 	if (error)
464 		return (error);
465 
466 	if (com == FIODTYPE) {
467 		*(int *)data = dsw->d_flags & D_TYPEMASK;
468 		dev_relthread(dev);
469 		return (0);
470 	}
471 	if (dsw->d_flags & D_NEEDGIANT)
472 		mtx_lock(&Giant);
473 	error = dsw->d_ioctl(dev, com, data, fp->f_flag, td);
474 	if (dsw->d_flags & D_NEEDGIANT)
475 		mtx_unlock(&Giant);
476 	dev_relthread(dev);
477 	if (error == ENOIOCTL)
478 		error = ENOTTY;
479 	if (error == 0 && com == TIOCSCTTY) {
480 		vp = fp->f_vnode;
481 
482 		/* Do nothing if reassigning same control tty */
483 		sx_slock(&proctree_lock);
484 		if (td->td_proc->p_session->s_ttyvp == vp) {
485 			sx_sunlock(&proctree_lock);
486 			return (0);
487 		}
488 
489 		mtx_lock(&Giant);
490 
491 		vpold = td->td_proc->p_session->s_ttyvp;
492 		VREF(vp);
493 		SESS_LOCK(td->td_proc->p_session);
494 		td->td_proc->p_session->s_ttyvp = vp;
495 		SESS_UNLOCK(td->td_proc->p_session);
496 
497 		sx_sunlock(&proctree_lock);
498 
499 		/* Get rid of reference to old control tty */
500 		if (vpold)
501 			vrele(vpold);
502 		mtx_unlock(&Giant);
503 	}
504 	return (error);
505 }
506 
507 
508 /* ARGSUSED */
509 static int
510 devfs_kqfilter_f(struct file *fp, struct knote *kn)
511 {
512 	struct cdev *dev;
513 	struct cdevsw *dsw;
514 	int error;
515 
516 	error = devfs_fp_check(fp, &dev, &dsw);
517 	if (error)
518 		return (error);
519 	if (dsw->d_flags & D_NEEDGIANT)
520 		mtx_lock(&Giant);
521 	error = dsw->d_kqfilter(dev, kn);
522 	if (dsw->d_flags & D_NEEDGIANT)
523 		mtx_unlock(&Giant);
524 	dev_relthread(dev);
525 	return (error);
526 }
527 
528 static int
529 devfs_lookupx(ap)
530 	struct vop_lookup_args /* {
531 		struct vnode * a_dvp;
532 		struct vnode ** a_vpp;
533 		struct componentname * a_cnp;
534 	} */ *ap;
535 {
536 	struct componentname *cnp;
537 	struct vnode *dvp, **vpp;
538 	struct thread *td;
539 	struct devfs_dirent *de, *dd;
540 	struct devfs_dirent **dde;
541 	struct devfs_mount *dmp;
542 	struct cdev *cdev;
543 	int error, flags, nameiop;
544 	char specname[SPECNAMELEN + 1], *pname;
545 
546 	cnp = ap->a_cnp;
547 	vpp = ap->a_vpp;
548 	dvp = ap->a_dvp;
549 	pname = cnp->cn_nameptr;
550 	td = cnp->cn_thread;
551 	flags = cnp->cn_flags;
552 	nameiop = cnp->cn_nameiop;
553 	dmp = VFSTODEVFS(dvp->v_mount);
554 	dd = dvp->v_data;
555 
556 	*vpp = NULLVP;
557 	cnp->cn_flags &= ~PDIRUNLOCK;
558 
559 	if ((flags & ISLASTCN) && nameiop == RENAME)
560 		return (EOPNOTSUPP);
561 
562 	if (dvp->v_type != VDIR)
563 		return (ENOTDIR);
564 
565 	if ((flags & ISDOTDOT) && (dvp->v_vflag & VV_ROOT))
566 		return (EIO);
567 
568 	error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
569 	if (error)
570 		return (error);
571 
572 	if (cnp->cn_namelen == 1 && *pname == '.') {
573 		if ((flags & ISLASTCN) && nameiop != LOOKUP)
574 			return (EINVAL);
575 		*vpp = dvp;
576 		VREF(dvp);
577 		return (0);
578 	}
579 
580 	if (flags & ISDOTDOT) {
581 		if ((flags & ISLASTCN) && nameiop != LOOKUP)
582 			return (EINVAL);
583 		VOP_UNLOCK(dvp, 0, td);
584 		cnp->cn_flags |= PDIRUNLOCK;
585 		de = TAILQ_FIRST(&dd->de_dlist);	/* "." */
586 		de = TAILQ_NEXT(de, de_list);		/* ".." */
587 		de = de->de_dir;
588 		error = devfs_allocv(de, dvp->v_mount, vpp, td);
589 		if (error || ((flags & LOCKPARENT) && (flags & ISLASTCN))) {
590 			vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
591 			cnp->cn_flags &= ~PDIRUNLOCK;
592 		}
593 		return (error);
594 	}
595 
596 	devfs_populate(dmp);
597 	dd = dvp->v_data;
598 	TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
599 		if (cnp->cn_namelen != de->de_dirent->d_namlen)
600 			continue;
601 		if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
602 		    de->de_dirent->d_namlen) != 0)
603 			continue;
604 		if (de->de_flags & DE_WHITEOUT)
605 			goto notfound;
606 		goto found;
607 	}
608 
609 	if (nameiop == DELETE)
610 		goto notfound;
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 		goto notfound;
619 
620 	cdev = NULL;
621 	EVENTHANDLER_INVOKE(dev_clone, pname, strlen(pname), &cdev);
622 	if (cdev == NULL)
623 		goto notfound;
624 
625 	devfs_populate(dmp);
626 
627 	dde = devfs_itode(dmp, cdev->si_inode);
628 
629 	if (dde == NULL || *dde == NULL || *dde == DE_DELETED)
630 		goto notfound;
631 
632 	if ((*dde)->de_flags & DE_WHITEOUT)
633 		goto notfound;
634 
635 	de = *dde;
636 	goto found;
637 
638 notfound:
639 
640 	if ((nameiop == CREATE || nameiop == RENAME) &&
641 	    (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
642 		cnp->cn_flags |= SAVENAME;
643 		if (!(flags & LOCKPARENT)) {
644 			VOP_UNLOCK(dvp, 0, td);
645 			cnp->cn_flags |= PDIRUNLOCK;
646 		}
647 		return (EJUSTRETURN);
648 	}
649 	return (ENOENT);
650 
651 
652 found:
653 
654 	if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
655 		error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
656 		if (error)
657 			return (error);
658 		if (*vpp == dvp) {
659 			VREF(dvp);
660 			*vpp = dvp;
661 			return (0);
662 		}
663 		error = devfs_allocv(de, dvp->v_mount, vpp, td);
664 		if (error)
665 			return (error);
666 		if (!(flags & LOCKPARENT)) {
667 			VOP_UNLOCK(dvp, 0, td);
668 			cnp->cn_flags |= PDIRUNLOCK;
669 		}
670 		return (0);
671 	}
672 	error = devfs_allocv(de, dvp->v_mount, vpp, td);
673 	if (error)
674 		return (error);
675 	if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) {
676 		VOP_UNLOCK(dvp, 0, td);
677 		cnp->cn_flags |= PDIRUNLOCK;
678 	}
679 	return (0);
680 }
681 
682 static int
683 devfs_lookup(struct vop_lookup_args *ap)
684 {
685 	int j;
686 	struct devfs_mount *dmp;
687 
688 	dmp = VFSTODEVFS(ap->a_dvp->v_mount);
689 	lockmgr(&dmp->dm_lock, LK_SHARED, 0, curthread);
690 	j = devfs_lookupx(ap);
691 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
692 	return (j);
693 }
694 
695 static int
696 devfs_mknod(struct vop_mknod_args *ap)
697 	/*
698 	struct vop_mknod_args {
699 		struct vnodeop_desc *a_desc;
700 		struct vnode *a_dvp;
701 		struct vnode **a_vpp;
702 		struct componentname *a_cnp;
703 		struct vattr *a_vap;
704 	}; */
705 {
706 	struct componentname *cnp;
707 	struct vnode *dvp, **vpp;
708 	struct thread *td;
709 	struct devfs_dirent *dd, *de;
710 	struct devfs_mount *dmp;
711 	int error;
712 
713 	dvp = ap->a_dvp;
714 	dmp = VFSTODEVFS(dvp->v_mount);
715 	lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curthread);
716 
717 	cnp = ap->a_cnp;
718 	vpp = ap->a_vpp;
719 	td = cnp->cn_thread;
720 	dd = dvp->v_data;
721 
722 	error = ENOENT;
723 	TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
724 		if (cnp->cn_namelen != de->de_dirent->d_namlen)
725 			continue;
726 		if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
727 		    de->de_dirent->d_namlen) != 0)
728 			continue;
729 		if (de->de_flags & DE_WHITEOUT)
730 			break;
731 		goto notfound;
732 	}
733 	if (de == NULL)
734 		goto notfound;
735 	de->de_flags &= ~DE_WHITEOUT;
736 	error = devfs_allocv(de, dvp->v_mount, vpp, td);
737 notfound:
738 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
739 	return (error);
740 }
741 
742 /*
743  * Open a special file.
744  */
745 /* ARGSUSED */
746 static int
747 devfs_open(ap)
748 	struct vop_open_args /* {
749 		struct vnode *a_vp;
750 		int  a_mode;
751 		struct ucred *a_cred;
752 		struct thread *a_td;
753 		int a_fdidx;
754 	} */ *ap;
755 {
756 	struct thread *td = ap->a_td;
757 	struct vnode *vp = ap->a_vp;
758 	struct cdev *dev = vp->v_rdev;
759 	struct file *fp;
760 	int error;
761 	struct cdevsw *dsw;
762 
763 	if (vp->v_type == VBLK)
764 		return (ENXIO);
765 
766 	if (dev == NULL)
767 		return (ENXIO);
768 
769 	/* Make this field valid before any I/O in d_open. */
770 	if (dev->si_iosize_max == 0)
771 		dev->si_iosize_max = DFLTPHYS;
772 
773 	if (vn_isdisk(vp, NULL) &&
774 	    ap->a_cred != FSCRED && (ap->a_mode & FWRITE)) {
775 		/*
776 		* When running in very secure mode, do not allow
777 		* opens for writing of any disks.
778 		* XXX: should be in geom_dev.c, but we lack the cred there.
779 		*/
780 		error = securelevel_ge(td->td_ucred, 2);
781 		if (error)
782 			return (error);
783 	}
784 
785 	dsw = dev_refthread(dev);
786 	if (dsw == NULL)
787 		return (ENXIO);
788 
789 	/* XXX: Special casing of ttys for deadfs.  Probably redundant. */
790 	if (dsw->d_flags & D_TTY)
791 		vp->v_vflag |= VV_ISTTY;
792 
793 	VOP_UNLOCK(vp, 0, td);
794 
795 	if(!(dsw->d_flags & D_NEEDGIANT)) {
796 		DROP_GIANT();
797 		if (dsw->d_fdopen != NULL)
798 			error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx);
799 		else
800 			error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
801 		PICKUP_GIANT();
802 	} else if (dsw->d_fdopen != NULL)
803 		error = dsw->d_fdopen(dev, ap->a_mode, td, ap->a_fdidx);
804 	else
805 		error = dsw->d_open(dev, ap->a_mode, S_IFCHR, td);
806 
807 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
808 
809 	dev_relthread(dev);
810 
811 	if (error)
812 		return (error);
813 
814 	if (ap->a_fdidx >= 0) {
815 		/*
816 		 * This is a pretty disgustingly long chain, but I am not
817 		 * sure there is any better way.  Passing the fdidx into
818 		 * VOP_OPEN() offers us more information than just passing
819 		 * the file *.
820 		 */
821 		fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx];
822 		if (fp->f_ops == &badfileops) {
823 #if 0
824 			printf("devfs_open(%s)\n", devtoname(dev));
825 #endif
826 			fp->f_ops = &devfs_ops_f;
827 			fp->f_data = dev;
828 		}
829 	}
830 
831 	return (error);
832 }
833 
834 static int
835 devfs_pathconf(ap)
836 	struct vop_pathconf_args /* {
837 		struct vnode *a_vp;
838 		int a_name;
839 		int *a_retval;
840 	} */ *ap;
841 {
842 
843 	switch (ap->a_name) {
844 	case _PC_NAME_MAX:
845 		*ap->a_retval = NAME_MAX;
846 		return (0);
847 	case _PC_PATH_MAX:
848 		*ap->a_retval = PATH_MAX;
849 		return (0);
850 	case _PC_MAC_PRESENT:
851 #ifdef MAC
852 		/*
853 		 * If MAC is enabled, devfs automatically supports
854 		 * trivial non-persistant label storage.
855 		 */
856 		*ap->a_retval = 1;
857 #else
858 		*ap->a_retval = 0;
859 #endif
860 		return (0);
861 	default:
862 		return (vop_stdpathconf(ap));
863 	}
864 	/* NOTREACHED */
865 }
866 
867 /* ARGSUSED */
868 static int
869 devfs_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
870 {
871 	struct cdev *dev;
872 	struct cdevsw *dsw;
873 	int error;
874 
875 	error = devfs_fp_check(fp, &dev, &dsw);
876 	if (error)
877 		return (error);
878 	if (dsw->d_flags & D_NEEDGIANT)
879 		mtx_lock(&Giant);
880 	error = dsw->d_poll(dev, events, td);
881 	if (dsw->d_flags & D_NEEDGIANT)
882 		mtx_unlock(&Giant);
883 	dev_relthread(dev);
884 	return(error);
885 }
886 
887 /*
888  * Print out the contents of a special device vnode.
889  */
890 static int
891 devfs_print(ap)
892 	struct vop_print_args /* {
893 		struct vnode *a_vp;
894 	} */ *ap;
895 {
896 
897 	printf("\tdev %s\n", devtoname(ap->a_vp->v_rdev));
898 	return (0);
899 }
900 
901 /*
902  * Vnode op for read
903  */
904 /* ARGSUSED */
905 static int
906 devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
907 {
908 	struct cdev *dev;
909 	int ioflag, error, resid;
910 	struct cdevsw *dsw;
911 
912 	error = devfs_fp_check(fp, &dev, &dsw);
913 	if (error)
914 		return (error);
915 	resid = uio->uio_resid;
916 	ioflag = 0;
917 	if (fp->f_flag & FNONBLOCK)
918 		ioflag |= IO_NDELAY;
919 	if (fp->f_flag & O_DIRECT)
920 		ioflag |= IO_DIRECT;
921 
922 	if ((flags & FOF_OFFSET) == 0)
923 		uio->uio_offset = fp->f_offset;
924 
925 	if (dsw->d_flags & D_NEEDGIANT)
926 		mtx_lock(&Giant);
927 	error = dsw->d_read(dev, uio, ioflag);
928 	if (dsw->d_flags & D_NEEDGIANT)
929 		mtx_unlock(&Giant);
930 	dev_relthread(dev);
931 	if (uio->uio_resid != resid || (error == 0 && resid != 0))
932 		vfs_timestamp(&dev->si_atime);
933 
934 	if ((flags & FOF_OFFSET) == 0)
935 		fp->f_offset = uio->uio_offset;
936 	fp->f_nextoff = uio->uio_offset;
937 	return (error);
938 }
939 
940 static int
941 devfs_readdir(ap)
942 	struct vop_readdir_args /* {
943 		struct vnode *a_vp;
944 		struct uio *a_uio;
945 		struct ucred *a_cred;
946 		int *a_eofflag;
947 		int *a_ncookies;
948 		u_long **a_cookies;
949 	} */ *ap;
950 {
951 	int error;
952 	struct uio *uio;
953 	struct dirent *dp;
954 	struct devfs_dirent *dd;
955 	struct devfs_dirent *de;
956 	struct devfs_mount *dmp;
957 	off_t off, oldoff;
958 	int ncookies = 0;
959 	u_long *cookiebuf, *cookiep;
960 	struct dirent *dps, *dpe;
961 
962 	if (ap->a_vp->v_type != VDIR)
963 		return (ENOTDIR);
964 
965 	uio = ap->a_uio;
966 	if (uio->uio_offset < 0)
967 		return (EINVAL);
968 
969 	dmp = VFSTODEVFS(ap->a_vp->v_mount);
970 	lockmgr(&dmp->dm_lock, LK_SHARED, 0, curthread);
971 	devfs_populate(dmp);
972 	error = 0;
973 	de = ap->a_vp->v_data;
974 	off = 0;
975 	oldoff = uio->uio_offset;
976 	TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
977 		if (dd->de_flags & DE_WHITEOUT)
978 			continue;
979 		if (dd->de_dirent->d_type == DT_DIR)
980 			de = dd->de_dir;
981 		else
982 			de = dd;
983 		dp = dd->de_dirent;
984 		if (dp->d_reclen > uio->uio_resid)
985 			break;
986 		dp->d_fileno = de->de_inode;
987 		if (off >= uio->uio_offset) {
988 			ncookies++;
989 			error = uiomove(dp, dp->d_reclen, uio);
990 			if (error)
991 				break;
992 		}
993 		off += dp->d_reclen;
994 	}
995 	if( !error && ap->a_ncookies != NULL && ap->a_cookies != NULL ) {
996 		MALLOC(cookiebuf, u_long *, ncookies * sizeof(u_long),
997 		       M_TEMP, M_WAITOK);
998 		cookiep = cookiebuf;
999 		dps = (struct dirent *)((char *)uio->uio_iov->iov_base -
1000 		    (uio->uio_offset - oldoff));
1001 		dpe = (struct dirent *) uio->uio_iov->iov_base;
1002 		for( dp = dps;
1003 			dp < dpe;
1004 			dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
1005 				oldoff += dp->d_reclen;
1006 				*cookiep++ = (u_long) oldoff;
1007 		}
1008 		*ap->a_ncookies = ncookies;
1009 		*ap->a_cookies = cookiebuf;
1010 	}
1011 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
1012 	uio->uio_offset = off;
1013 	return (error);
1014 }
1015 
1016 static int
1017 devfs_readlink(ap)
1018 	struct vop_readlink_args /* {
1019 		struct vnode *a_vp;
1020 		struct uio *a_uio;
1021 		struct ucred *a_cead;
1022 	} */ *ap;
1023 {
1024 	int error;
1025 	struct devfs_dirent *de;
1026 
1027 	de = ap->a_vp->v_data;
1028 	error = uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio);
1029 	return (error);
1030 }
1031 
1032 static int
1033 devfs_reclaim(ap)
1034 	struct vop_reclaim_args /* {
1035 		struct vnode *a_vp;
1036 	} */ *ap;
1037 {
1038 	struct vnode *vp = ap->a_vp;
1039 	struct devfs_dirent *de;
1040 	int i;
1041 
1042 	de = vp->v_data;
1043 	if (de != NULL)
1044 		de->de_vnode = NULL;
1045 	vp->v_data = NULL;
1046 	if (vp->v_rdev != NULL) {
1047 		i = vcount(vp);
1048 		if ((vp->v_rdev->si_flags & SI_CHEAPCLONE) && i == 0 &&
1049 		    (vp->v_rdev->si_flags & SI_NAMED))
1050 			destroy_dev(vp->v_rdev);
1051 	}
1052 	return (0);
1053 }
1054 
1055 static int
1056 devfs_remove(ap)
1057 	struct vop_remove_args /* {
1058 		struct vnode *a_dvp;
1059 		struct vnode *a_vp;
1060 		struct componentname *a_cnp;
1061 	} */ *ap;
1062 {
1063 	struct vnode *vp = ap->a_vp;
1064 	struct devfs_dirent *dd;
1065 	struct devfs_dirent *de;
1066 	struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
1067 
1068 	lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curthread);
1069 	dd = ap->a_dvp->v_data;
1070 	de = vp->v_data;
1071 	if (de->de_dirent->d_type == DT_LNK) {
1072 		TAILQ_REMOVE(&dd->de_dlist, de, de_list);
1073 		if (de->de_vnode)
1074 			de->de_vnode->v_data = NULL;
1075 #ifdef MAC
1076 		mac_destroy_devfsdirent(de);
1077 #endif
1078 		FREE(de, M_DEVFS);
1079 	} else {
1080 		de->de_flags |= DE_WHITEOUT;
1081 	}
1082 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
1083 	return (0);
1084 }
1085 
1086 /*
1087  * Revoke is called on a tty when a terminal session ends.  The vnode
1088  * is orphaned by setting v_op to deadfs so we need to let go of it
1089  * as well so that we create a new one next time around.
1090  */
1091 static int
1092 devfs_revoke(ap)
1093 	struct vop_revoke_args /* {
1094 		struct vnode *a_vp;
1095 		int a_flags;
1096 	} */ *ap;
1097 {
1098 	struct vnode *vp = ap->a_vp;
1099 	struct vnode *vq;
1100 	struct devfs_dirent *de;
1101 	struct cdev *dev;
1102 
1103 	KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
1104 	de = vp->v_data;
1105 	de->de_vnode = NULL;
1106 
1107 	VI_LOCK(vp);
1108 	/*
1109 	 * If a vgone (or vclean) is already in progress,
1110 	 * wait until it is done and return.
1111 	 */
1112 	if (vp->v_iflag & VI_XLOCK) {
1113 		vp->v_iflag |= VI_XWANT;
1114 		msleep(vp, VI_MTX(vp), PINOD | PDROP, "vop_revokeall", 0);
1115 		return (0);
1116 	}
1117 	VI_UNLOCK(vp);
1118 	dev = vp->v_rdev;
1119 	for (;;) {
1120 		dev_lock();
1121 		vq = SLIST_FIRST(&dev->si_hlist);
1122 		dev_unlock();
1123 		if (vq == NULL)
1124 			break;
1125 		vgone(vq);
1126 	}
1127 	return (0);
1128 }
1129 
1130 static int
1131 devfs_rioctl(ap)
1132 	struct vop_ioctl_args /* {
1133 		struct vnode *a_vp;
1134 		u_long  a_command;
1135 		caddr_t  a_data;
1136 		int  a_fflag;
1137 		struct ucred *a_cred;
1138 		struct thread *a_td;
1139 	} */ *ap;
1140 {
1141 	int error;
1142 	struct devfs_mount *dmp;
1143 
1144 	dmp = VFSTODEVFS(ap->a_vp->v_mount);
1145 	lockmgr(&dmp->dm_lock, LK_SHARED, 0, curthread);
1146 	devfs_populate(dmp);
1147 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
1148 	error = devfs_rules_ioctl(ap->a_vp->v_mount, ap->a_command, ap->a_data,
1149 	    ap->a_td);
1150 	return (error);
1151 }
1152 
1153 static int
1154 devfs_rread(ap)
1155 	struct vop_read_args /* {
1156 		struct vnode *a_vp;
1157 		struct uio *a_uio;
1158 		int a_ioflag;
1159 		struct ucred *a_cred;
1160 	} */ *ap;
1161 {
1162 
1163 	if (ap->a_vp->v_type != VDIR)
1164 		return (EINVAL);
1165 	return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL));
1166 }
1167 
1168 static int
1169 devfs_setattr(ap)
1170 	struct vop_setattr_args /* {
1171 		struct vnode *a_vp;
1172 		struct vattr *a_vap;
1173 		struct ucred *a_cred;
1174 		struct proc *a_p;
1175 	} */ *ap;
1176 {
1177 	struct devfs_dirent *de;
1178 	struct vattr *vap;
1179 	struct vnode *vp;
1180 	int c, error;
1181 	uid_t uid;
1182 	gid_t gid;
1183 
1184 	vap = ap->a_vap;
1185 	vp = ap->a_vp;
1186 	if ((vap->va_type != VNON) ||
1187 	    (vap->va_nlink != VNOVAL) ||
1188 	    (vap->va_fsid != VNOVAL) ||
1189 	    (vap->va_fileid != VNOVAL) ||
1190 	    (vap->va_blocksize != VNOVAL) ||
1191 	    (vap->va_flags != VNOVAL && vap->va_flags != 0) ||
1192 	    (vap->va_rdev != VNOVAL) ||
1193 	    ((int)vap->va_bytes != VNOVAL) ||
1194 	    (vap->va_gen != VNOVAL)) {
1195 		return (EINVAL);
1196 	}
1197 
1198 	de = vp->v_data;
1199 	if (vp->v_type == VDIR)
1200 		de = de->de_dir;
1201 
1202 	error = c = 0;
1203 	if (vap->va_uid == (uid_t)VNOVAL)
1204 		uid = de->de_uid;
1205 	else
1206 		uid = vap->va_uid;
1207 	if (vap->va_gid == (gid_t)VNOVAL)
1208 		gid = de->de_gid;
1209 	else
1210 		gid = vap->va_gid;
1211 	if (uid != de->de_uid || gid != de->de_gid) {
1212 		if (((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
1213 		    (gid != de->de_gid && !groupmember(gid, ap->a_cred))) &&
1214 		    (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)) != 0)
1215 			return (error);
1216 		de->de_uid = uid;
1217 		de->de_gid = gid;
1218 		c = 1;
1219 	}
1220 
1221 	if (vap->va_mode != (mode_t)VNOVAL) {
1222 		if ((ap->a_cred->cr_uid != de->de_uid) &&
1223 		    (error = suser_cred(ap->a_td->td_ucred, SUSER_ALLOWJAIL)))
1224 			return (error);
1225 		de->de_mode = vap->va_mode;
1226 		c = 1;
1227 	}
1228 
1229 	if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
1230 		/* See the comment in ufs_vnops::ufs_setattr(). */
1231 		if ((error = VOP_ACCESS(vp, VADMIN, ap->a_cred, ap->a_td)) &&
1232 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
1233 		    (error = VOP_ACCESS(vp, VWRITE, ap->a_cred, ap->a_td))))
1234 			return (error);
1235 		if (vap->va_atime.tv_sec != VNOVAL) {
1236 			if (vp->v_type == VCHR)
1237 				vp->v_rdev->si_atime = vap->va_atime;
1238 			else
1239 				de->de_atime = vap->va_atime;
1240 		}
1241 		if (vap->va_mtime.tv_sec != VNOVAL) {
1242 			if (vp->v_type == VCHR)
1243 				vp->v_rdev->si_mtime = vap->va_mtime;
1244 			else
1245 				de->de_mtime = vap->va_mtime;
1246 		}
1247 		c = 1;
1248 	}
1249 
1250 	if (c) {
1251 		if (vp->v_type == VCHR)
1252 			vfs_timestamp(&vp->v_rdev->si_ctime);
1253 		else
1254 			vfs_timestamp(&de->de_mtime);
1255 	}
1256 	return (0);
1257 }
1258 
1259 #ifdef MAC
1260 static int
1261 devfs_setlabel(ap)
1262 	struct vop_setlabel_args /* {
1263 		struct vnode *a_vp;
1264 		struct mac *a_label;
1265 		struct ucred *a_cred;
1266 		struct thread *a_td;
1267 	} */ *ap;
1268 {
1269 	struct vnode *vp;
1270 	struct devfs_dirent *de;
1271 
1272 	vp = ap->a_vp;
1273 	de = vp->v_data;
1274 
1275 	mac_relabel_vnode(ap->a_cred, vp, ap->a_label);
1276 	mac_update_devfsdirent(vp->v_mount, de, vp);
1277 
1278 	return (0);
1279 }
1280 #endif
1281 
1282 static int
1283 devfs_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
1284 {
1285 
1286 	return (vnops.fo_stat(fp, sb, cred, td));
1287 }
1288 
1289 static int
1290 devfs_symlink(ap)
1291 	struct vop_symlink_args /* {
1292 		struct vnode *a_dvp;
1293 		struct vnode **a_vpp;
1294 		struct componentname *a_cnp;
1295 		struct vattr *a_vap;
1296 		char *a_target;
1297 	} */ *ap;
1298 {
1299 	int i, error;
1300 	struct devfs_dirent *dd;
1301 	struct devfs_dirent *de;
1302 	struct devfs_mount *dmp;
1303 	struct thread *td;
1304 
1305 	td = ap->a_cnp->cn_thread;
1306 	KASSERT(td == curthread, ("devfs_symlink: td != curthread"));
1307 	error = suser(td);
1308 	if (error)
1309 		return(error);
1310 	dmp = VFSTODEVFS(ap->a_dvp->v_mount);
1311 	dd = ap->a_dvp->v_data;
1312 	de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
1313 	de->de_uid = 0;
1314 	de->de_gid = 0;
1315 	de->de_mode = 0755;
1316 	de->de_inode = dmp->dm_inode++;
1317 	de->de_dirent->d_type = DT_LNK;
1318 	i = strlen(ap->a_target) + 1;
1319 	MALLOC(de->de_symlink, char *, i, M_DEVFS, M_WAITOK);
1320 	bcopy(ap->a_target, de->de_symlink, i);
1321 	lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, td);
1322 #ifdef MAC
1323 	mac_create_devfs_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de);
1324 #endif
1325 	TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list);
1326 	devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td);
1327 	lockmgr(&dmp->dm_lock, LK_RELEASE, 0, td);
1328 	return (0);
1329 }
1330 
1331 /*
1332  * Vnode op for write
1333  */
1334 /* ARGSUSED */
1335 static int
1336 devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
1337 {
1338 	struct cdev *dev;
1339 	struct vnode *vp;
1340 	int error, ioflag, resid;
1341 	struct cdevsw *dsw;
1342 
1343 	error = devfs_fp_check(fp, &dev, &dsw);
1344 	if (error)
1345 		return (error);
1346 	KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
1347 	vp = fp->f_vnode;
1348 	ioflag = IO_UNIT;
1349 	if (fp->f_flag & FNONBLOCK)
1350 		ioflag |= IO_NDELAY;
1351 	if (fp->f_flag & O_DIRECT)
1352 		ioflag |= IO_DIRECT;
1353 	if ((fp->f_flag & O_FSYNC) ||
1354 	    (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
1355 		ioflag |= IO_SYNC;
1356 	if ((flags & FOF_OFFSET) == 0)
1357 		uio->uio_offset = fp->f_offset;
1358 
1359 	resid = uio->uio_resid;
1360 
1361 	if (dsw->d_flags & D_NEEDGIANT)
1362 		mtx_lock(&Giant);
1363 	error = dsw->d_write(dev, uio, ioflag);
1364 	if (dsw->d_flags & D_NEEDGIANT)
1365 		mtx_unlock(&Giant);
1366 	dev_relthread(dev);
1367 	if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
1368 		vfs_timestamp(&dev->si_ctime);
1369 		dev->si_mtime = dev->si_ctime;
1370 	}
1371 
1372 	if ((flags & FOF_OFFSET) == 0)
1373 		fp->f_offset = uio->uio_offset;
1374 	fp->f_nextoff = uio->uio_offset;
1375 	return (error);
1376 }
1377 
1378 static struct vop_vector devfs_vnodeops = {
1379 	.vop_default =		&default_vnodeops,
1380 	.vop_access =		devfs_access,
1381 	.vop_getattr =		devfs_getattr,
1382 	.vop_ioctl =		devfs_rioctl,
1383 	.vop_lookup =		devfs_lookup,
1384 	.vop_mknod =		devfs_mknod,
1385 	.vop_pathconf =		devfs_pathconf,
1386 	.vop_read =		devfs_rread,
1387 	.vop_readdir =		devfs_readdir,
1388 	.vop_readlink =		devfs_readlink,
1389 	.vop_reclaim =		devfs_reclaim,
1390 	.vop_remove =		devfs_remove,
1391 	.vop_revoke =		devfs_revoke,
1392 	.vop_setattr =		devfs_setattr,
1393 #ifdef MAC
1394 	.vop_setlabel =		devfs_setlabel,
1395 #endif
1396 	.vop_symlink =		devfs_symlink,
1397 };
1398 
1399 struct vop_vector devfs_specops = {
1400 	.vop_default =		&default_vnodeops,
1401 	.vop_access =		devfs_access,
1402 	.vop_advlock =		devfs_advlock,
1403 	.vop_bmap =		VOP_PANIC,
1404 	.vop_close =		devfs_close,
1405 	.vop_create =		VOP_PANIC,
1406 	.vop_fsync =		devfs_fsync,
1407 	.vop_getattr =		devfs_getattr,
1408 	.vop_lease =		VOP_NULL,
1409 	.vop_link =		VOP_PANIC,
1410 	.vop_mkdir =		VOP_PANIC,
1411 	.vop_mknod =		VOP_PANIC,
1412 	.vop_open =		devfs_open,
1413 	.vop_pathconf =		devfs_pathconf,
1414 	.vop_print =		devfs_print,
1415 	.vop_readdir =		VOP_PANIC,
1416 	.vop_readlink =		VOP_PANIC,
1417 	.vop_reallocblks =	VOP_PANIC,
1418 	.vop_reclaim =		devfs_reclaim,
1419 	.vop_remove =		devfs_remove,
1420 	.vop_rename =		VOP_PANIC,
1421 	.vop_revoke =		devfs_revoke,
1422 	.vop_rmdir =		VOP_PANIC,
1423 	.vop_setattr =		devfs_setattr,
1424 #ifdef MAC
1425 	.vop_setlabel =		devfs_setlabel,
1426 #endif
1427 	.vop_strategy =		VOP_PANIC,
1428 	.vop_symlink =		VOP_PANIC,
1429 };
1430