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