xref: /dragonfly/sys/kern/vfs_default.c (revision ce0e08e2)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed
6  * to Berkeley by John Heidemann of the UCLA Ficus project.
7  *
8  * The statvfs->statfs conversion code was contributed to the DragonFly
9  * Project by Joerg Sonnenberger <joerg@bec.de>.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the University of
22  *	California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
40  * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $
41  * $DragonFly: src/sys/kern/vfs_default.c,v 1.55 2008/09/28 04:31:50 dillon Exp $
42  */
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/buf.h>
47 #include <sys/conf.h>
48 #include <sys/fcntl.h>
49 #include <sys/file.h>
50 #include <sys/kernel.h>
51 #include <sys/lock.h>
52 #include <sys/malloc.h>
53 #include <sys/mount.h>
54 #include <sys/unistd.h>
55 #include <sys/vnode.h>
56 #include <sys/namei.h>
57 #include <sys/nlookup.h>
58 #include <sys/poll.h>
59 #include <sys/mountctl.h>
60 
61 #include <machine/limits.h>
62 
63 #include <vm/vm.h>
64 #include <vm/vm_object.h>
65 #include <vm/vm_page.h>
66 #include <vm/vm_pager.h>
67 #include <vm/vnode_pager.h>
68 
69 static int	vop_nolookup (struct vop_old_lookup_args *);
70 static int	vop_nostrategy (struct vop_strategy_args *);
71 
72 /*
73  * This vnode table stores what we want to do if the filesystem doesn't
74  * implement a particular VOP.
75  *
76  * If there is no specific entry here, we will return EOPNOTSUPP.
77  */
78 struct vop_ops default_vnode_vops = {
79 	.vop_default		= vop_eopnotsupp,
80 	.vop_advlock		= (void *)vop_einval,
81 	.vop_fsync		= (void *)vop_null,
82 	.vop_ioctl		= (void *)vop_enotty,
83 	.vop_mmap		= (void *)vop_einval,
84 	.vop_old_lookup		= vop_nolookup,
85 	.vop_open		= vop_stdopen,
86 	.vop_close		= vop_stdclose,
87 	.vop_pathconf		= vop_stdpathconf,
88 	.vop_poll		= vop_nopoll,
89 	.vop_readlink		= (void *)vop_einval,
90 	.vop_reallocblks	= (void *)vop_eopnotsupp,
91 	.vop_revoke		= vop_stdrevoke,
92 	.vop_strategy		= vop_nostrategy,
93 	.vop_getacl		= (void *)vop_eopnotsupp,
94 	.vop_setacl		= (void *)vop_eopnotsupp,
95 	.vop_aclcheck		= (void *)vop_eopnotsupp,
96 	.vop_getextattr		= (void *)vop_eopnotsupp,
97 	.vop_setextattr		= (void *)vop_eopnotsupp,
98 	.vop_nresolve		= vop_compat_nresolve,
99 	.vop_nlookupdotdot	= vop_compat_nlookupdotdot,
100 	.vop_ncreate		= vop_compat_ncreate,
101 	.vop_nmkdir		= vop_compat_nmkdir,
102 	.vop_nmknod		= vop_compat_nmknod,
103 	.vop_nlink		= vop_compat_nlink,
104 	.vop_nsymlink		= vop_compat_nsymlink,
105 	.vop_nwhiteout		= vop_compat_nwhiteout,
106 	.vop_nremove		= vop_compat_nremove,
107 	.vop_nrmdir		= vop_compat_nrmdir,
108 	.vop_nrename		= vop_compat_nrename,
109 	.vop_mountctl		= journal_mountctl
110 };
111 
112 VNODEOP_SET(default_vnode_vops);
113 
114 int
115 vop_eopnotsupp(struct vop_generic_args *ap)
116 {
117 	return (EOPNOTSUPP);
118 }
119 
120 int
121 vop_ebadf(struct vop_generic_args *ap)
122 {
123 	return (EBADF);
124 }
125 
126 int
127 vop_enotty(struct vop_generic_args *ap)
128 {
129 	return (ENOTTY);
130 }
131 
132 int
133 vop_einval(struct vop_generic_args *ap)
134 {
135 	return (EINVAL);
136 }
137 
138 int
139 vop_null(struct vop_generic_args *ap)
140 {
141 	return (0);
142 }
143 
144 int
145 vop_defaultop(struct vop_generic_args *ap)
146 {
147 	return (VOCALL(&default_vnode_vops, ap));
148 }
149 
150 int
151 vop_panic(struct vop_generic_args *ap)
152 {
153 	panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name);
154 }
155 
156 /*
157  * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
158  * XXX STOPGAP FUNCTION
159  *
160  * XXX OLD API ROUTINE!  WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
161  * WILL BE REMOVED.  This procedure exists for all VFSs which have not
162  * yet implemented VOP_NRESOLVE().  It converts VOP_NRESOLVE() into a
163  * vop_old_lookup() and does appropriate translations.
164  *
165  * Resolve a ncp for VFSs which do not support the VOP.  Eventually all
166  * VFSs will support this VOP and this routine can be removed, since
167  * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
168  * API.
169  *
170  * A locked ncp is passed in to be resolved.  The NCP is resolved by
171  * figuring out the vnode (if any) and calling cache_setvp() to attach the
172  * vnode to the entry.  If the entry represents a non-existant node then
173  * cache_setvp() is called with a NULL vnode to resolve the entry into a
174  * negative cache entry.  No vnode locks are retained and the
175  * ncp is left locked on return.
176  *
177  * The ncp will NEVER represent "", "." or "..", or contain any slashes.
178  *
179  * There is a potential directory and vnode interlock.   The lock order
180  * requirement is: namecache, governing directory, resolved vnode.
181  */
182 int
183 vop_compat_nresolve(struct vop_nresolve_args *ap)
184 {
185 	int error;
186 	struct vnode *dvp;
187 	struct vnode *vp;
188 	struct nchandle *nch;
189 	struct namecache *ncp;
190 	struct componentname cnp;
191 
192 	nch = ap->a_nch;	/* locked namecache node */
193 	ncp = nch->ncp;
194 	dvp = ap->a_dvp;
195 
196 	/*
197 	 * UFS currently stores all sorts of side effects, including a loop
198 	 * variable, in the directory inode.  That needs to be fixed and the
199 	 * other VFS's audited before we can switch to LK_SHARED.
200 	 */
201 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
202 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
203 			ncp, ncp->nc_name);
204 		return(EAGAIN);
205 	}
206 
207 	bzero(&cnp, sizeof(cnp));
208 	cnp.cn_nameiop = NAMEI_LOOKUP;
209 	cnp.cn_flags = 0;
210 	cnp.cn_nameptr = ncp->nc_name;
211 	cnp.cn_namelen = ncp->nc_nlen;
212 	cnp.cn_cred = ap->a_cred;
213 	cnp.cn_td = curthread; /* XXX */
214 
215 	/*
216 	 * vop_old_lookup() always returns vp locked.  dvp may or may not be
217 	 * left locked depending on CNP_PDIRUNLOCK.
218 	 */
219 	error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
220 	if (error == 0)
221 		vn_unlock(vp);
222 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
223 		vn_unlock(dvp);
224 	if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
225 		/* was resolved by another process while we were unlocked */
226 		if (error == 0)
227 			vrele(vp);
228 	} else if (error == 0) {
229 		KKASSERT(vp != NULL);
230 		cache_setvp(nch, vp);
231 		vrele(vp);
232 	} else if (error == ENOENT) {
233 		KKASSERT(vp == NULL);
234 		if (cnp.cn_flags & CNP_ISWHITEOUT)
235 			ncp->nc_flag |= NCF_WHITEOUT;
236 		cache_setvp(nch, NULL);
237 	}
238 	vrele(dvp);
239 	return (error);
240 }
241 
242 /*
243  * vop_compat_nlookupdotdot { struct vnode *a_dvp,
244  *			struct vnode **a_vpp,
245  *			struct ucred *a_cred }
246  *
247  * Lookup the vnode representing the parent directory of the specified
248  * directory vnode.  a_dvp should not be locked.  If no error occurs *a_vpp
249  * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
250  *
251  * This function is designed to aid NFS server-side operations and is
252  * used by cache_fromdvp() to create a consistent, connected namecache
253  * topology.
254  *
255  * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
256  * code out from their *_lookup() and create *_nlookupdotdot().  Then as time
257  * permits VFSs will implement the remaining *_n*() calls and finally get
258  * rid of their *_lookup() call.
259  */
260 int
261 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
262 {
263 	struct componentname cnp;
264 	int error;
265 
266 	/*
267 	 * UFS currently stores all sorts of side effects, including a loop
268 	 * variable, in the directory inode.  That needs to be fixed and the
269 	 * other VFS's audited before we can switch to LK_SHARED.
270 	 */
271 	*ap->a_vpp = NULL;
272 	if ((error = vget(ap->a_dvp, LK_EXCLUSIVE)) != 0)
273 		return (error);
274 	if (ap->a_dvp->v_type != VDIR) {
275 		vput(ap->a_dvp);
276 		return (ENOTDIR);
277 	}
278 
279 	bzero(&cnp, sizeof(cnp));
280 	cnp.cn_nameiop = NAMEI_LOOKUP;
281 	cnp.cn_flags = CNP_ISDOTDOT;
282 	cnp.cn_nameptr = "..";
283 	cnp.cn_namelen = 2;
284 	cnp.cn_cred = ap->a_cred;
285 	cnp.cn_td = curthread; /* XXX */
286 
287 	/*
288 	 * vop_old_lookup() always returns vp locked.  dvp may or may not be
289 	 * left locked depending on CNP_PDIRUNLOCK.
290 	 */
291 	error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
292 	if (error == 0)
293 		vn_unlock(*ap->a_vpp);
294 	if (cnp.cn_flags & CNP_PDIRUNLOCK)
295 		vrele(ap->a_dvp);
296 	else
297 		vput(ap->a_dvp);
298 	return (error);
299 }
300 
301 /*
302  * vop_compat_ncreate { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
303  *			struct vnode *a_dvp,
304  *			struct vnode **a_vpp,
305  *			struct ucred *a_cred,
306  *			struct vattr *a_vap }
307  *
308  * Create a file as specified by a_vap.  Compatibility requires us to issue
309  * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
310  * to setup the directory inode's i_offset and i_count (e.g. in UFS).
311  */
312 int
313 vop_compat_ncreate(struct vop_ncreate_args *ap)
314 {
315 	struct thread *td = curthread;
316 	struct componentname cnp;
317 	struct nchandle *nch;
318 	struct namecache *ncp;
319 	struct vnode *dvp;
320 	int error;
321 
322 	/*
323 	 * Sanity checks, get a locked directory vnode.
324 	 */
325 	nch = ap->a_nch;		/* locked namecache node */
326 	dvp = ap->a_dvp;
327 	ncp = nch->ncp;
328 
329 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
330 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
331 			ncp, ncp->nc_name);
332 		return(EAGAIN);
333 	}
334 
335 	/*
336 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
337 	 * caches all information required to create the entry in the
338 	 * directory inode.  We expect a return code of EJUSTRETURN for
339 	 * the CREATE case.  The cnp must simulated a saved-name situation.
340 	 */
341 	bzero(&cnp, sizeof(cnp));
342 	cnp.cn_nameiop = NAMEI_CREATE;
343 	cnp.cn_flags = CNP_LOCKPARENT;
344 	cnp.cn_nameptr = ncp->nc_name;
345 	cnp.cn_namelen = ncp->nc_nlen;
346 	cnp.cn_cred = ap->a_cred;
347 	cnp.cn_td = td;
348 	*ap->a_vpp = NULL;
349 
350 	error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
351 
352 	/*
353 	 * EJUSTRETURN should be returned for this case, which means that
354 	 * the VFS has setup the directory inode for the create.  The dvp we
355 	 * passed in is expected to remain in a locked state.
356 	 *
357 	 * If the VOP_OLD_CREATE is successful we are responsible for updating
358 	 * the cache state of the locked ncp that was passed to us.
359 	 */
360 	if (error == EJUSTRETURN) {
361 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
362 		error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
363 		if (error == 0) {
364 			cache_setunresolved(nch);
365 			cache_setvp(nch, *ap->a_vpp);
366 		}
367 	} else {
368 		if (error == 0) {
369 			vput(*ap->a_vpp);
370 			*ap->a_vpp = NULL;
371 			error = EEXIST;
372 		}
373 		KKASSERT(*ap->a_vpp == NULL);
374 	}
375 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
376 		vn_unlock(dvp);
377 	vrele(dvp);
378 	return (error);
379 }
380 
381 /*
382  * vop_compat_nmkdir { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
383  *			struct vnode *a_dvp,
384  *			struct vnode **a_vpp,
385  *			struct ucred *a_cred,
386  *			struct vattr *a_vap }
387  *
388  * Create a directory as specified by a_vap.  Compatibility requires us to
389  * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
390  * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
391  */
392 int
393 vop_compat_nmkdir(struct vop_nmkdir_args *ap)
394 {
395 	struct thread *td = curthread;
396 	struct componentname cnp;
397 	struct nchandle *nch;
398 	struct namecache *ncp;
399 	struct vnode *dvp;
400 	int error;
401 
402 	/*
403 	 * Sanity checks, get a locked directory vnode.
404 	 */
405 	nch = ap->a_nch;		/* locked namecache node */
406 	ncp = nch->ncp;
407 	dvp = ap->a_dvp;
408 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
409 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
410 			ncp, ncp->nc_name);
411 		return(EAGAIN);
412 	}
413 
414 	/*
415 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
416 	 * caches all information required to create the entry in the
417 	 * directory inode.  We expect a return code of EJUSTRETURN for
418 	 * the CREATE case.  The cnp must simulated a saved-name situation.
419 	 */
420 	bzero(&cnp, sizeof(cnp));
421 	cnp.cn_nameiop = NAMEI_CREATE;
422 	cnp.cn_flags = CNP_LOCKPARENT;
423 	cnp.cn_nameptr = ncp->nc_name;
424 	cnp.cn_namelen = ncp->nc_nlen;
425 	cnp.cn_cred = ap->a_cred;
426 	cnp.cn_td = td;
427 	*ap->a_vpp = NULL;
428 
429 	error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
430 
431 	/*
432 	 * EJUSTRETURN should be returned for this case, which means that
433 	 * the VFS has setup the directory inode for the create.  The dvp we
434 	 * passed in is expected to remain in a locked state.
435 	 *
436 	 * If the VOP_OLD_MKDIR is successful we are responsible for updating
437 	 * the cache state of the locked ncp that was passed to us.
438 	 */
439 	if (error == EJUSTRETURN) {
440 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
441 		error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
442 		if (error == 0) {
443 			cache_setunresolved(nch);
444 			cache_setvp(nch, *ap->a_vpp);
445 		}
446 	} else {
447 		if (error == 0) {
448 			vput(*ap->a_vpp);
449 			*ap->a_vpp = NULL;
450 			error = EEXIST;
451 		}
452 		KKASSERT(*ap->a_vpp == NULL);
453 	}
454 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
455 		vn_unlock(dvp);
456 	vrele(dvp);
457 	return (error);
458 }
459 
460 /*
461  * vop_compat_nmknod { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
462  *			struct vnode *a_dvp,
463  *			struct vnode **a_vpp,
464  *			struct ucred *a_cred,
465  *			struct vattr *a_vap }
466  *
467  * Create a device or fifo node as specified by a_vap.  Compatibility requires
468  * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
469  * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
470  */
471 int
472 vop_compat_nmknod(struct vop_nmknod_args *ap)
473 {
474 	struct thread *td = curthread;
475 	struct componentname cnp;
476 	struct nchandle *nch;
477 	struct namecache *ncp;
478 	struct vnode *dvp;
479 	int error;
480 
481 	/*
482 	 * Sanity checks, get a locked directory vnode.
483 	 */
484 	nch = ap->a_nch;		/* locked namecache node */
485 	ncp = nch->ncp;
486 	dvp = ap->a_dvp;
487 
488 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
489 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
490 			ncp, ncp->nc_name);
491 		return(EAGAIN);
492 	}
493 
494 	/*
495 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
496 	 * caches all information required to create the entry in the
497 	 * directory inode.  We expect a return code of EJUSTRETURN for
498 	 * the CREATE case.  The cnp must simulated a saved-name situation.
499 	 */
500 	bzero(&cnp, sizeof(cnp));
501 	cnp.cn_nameiop = NAMEI_CREATE;
502 	cnp.cn_flags = CNP_LOCKPARENT;
503 	cnp.cn_nameptr = ncp->nc_name;
504 	cnp.cn_namelen = ncp->nc_nlen;
505 	cnp.cn_cred = ap->a_cred;
506 	cnp.cn_td = td;
507 	*ap->a_vpp = NULL;
508 
509 	error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
510 
511 	/*
512 	 * EJUSTRETURN should be returned for this case, which means that
513 	 * the VFS has setup the directory inode for the create.  The dvp we
514 	 * passed in is expected to remain in a locked state.
515 	 *
516 	 * If the VOP_OLD_MKNOD is successful we are responsible for updating
517 	 * the cache state of the locked ncp that was passed to us.
518 	 */
519 	if (error == EJUSTRETURN) {
520 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
521 		error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
522 		if (error == 0) {
523 			cache_setunresolved(nch);
524 			cache_setvp(nch, *ap->a_vpp);
525 		}
526 	} else {
527 		if (error == 0) {
528 			vput(*ap->a_vpp);
529 			*ap->a_vpp = NULL;
530 			error = EEXIST;
531 		}
532 		KKASSERT(*ap->a_vpp == NULL);
533 	}
534 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
535 		vn_unlock(dvp);
536 	vrele(dvp);
537 	return (error);
538 }
539 
540 /*
541  * vop_compat_nlink { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
542  *			struct vnode *a_dvp,
543  *			struct vnode *a_vp,
544  *			struct ucred *a_cred }
545  *
546  * The passed vp is locked and represents the source.  The passed ncp is
547  * locked and represents the target to create.
548  */
549 int
550 vop_compat_nlink(struct vop_nlink_args *ap)
551 {
552 	struct thread *td = curthread;
553 	struct componentname cnp;
554 	struct nchandle *nch;
555 	struct namecache *ncp;
556 	struct vnode *dvp;
557 	struct vnode *tvp;
558 	int error;
559 
560 	/*
561 	 * Sanity checks, get a locked directory vnode.
562 	 */
563 	nch = ap->a_nch;		/* locked namecache node */
564 	ncp = nch->ncp;
565 	dvp = ap->a_dvp;
566 
567 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
568 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
569 			ncp, ncp->nc_name);
570 		return(EAGAIN);
571 	}
572 
573 	/*
574 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
575 	 * caches all information required to create the entry in the
576 	 * directory inode.  We expect a return code of EJUSTRETURN for
577 	 * the CREATE case.  The cnp must simulated a saved-name situation.
578 	 */
579 	bzero(&cnp, sizeof(cnp));
580 	cnp.cn_nameiop = NAMEI_CREATE;
581 	cnp.cn_flags = CNP_LOCKPARENT;
582 	cnp.cn_nameptr = ncp->nc_name;
583 	cnp.cn_namelen = ncp->nc_nlen;
584 	cnp.cn_cred = ap->a_cred;
585 	cnp.cn_td = td;
586 
587 	tvp = NULL;
588 	error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
589 
590 	/*
591 	 * EJUSTRETURN should be returned for this case, which means that
592 	 * the VFS has setup the directory inode for the create.  The dvp we
593 	 * passed in is expected to remain in a locked state.
594 	 *
595 	 * If the VOP_OLD_LINK is successful we are responsible for updating
596 	 * the cache state of the locked ncp that was passed to us.
597 	 */
598 	if (error == EJUSTRETURN) {
599 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
600 		error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
601 		if (error == 0) {
602 			cache_setunresolved(nch);
603 			cache_setvp(nch, ap->a_vp);
604 		}
605 	} else {
606 		if (error == 0) {
607 			vput(tvp);
608 			error = EEXIST;
609 		}
610 	}
611 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
612 		vn_unlock(dvp);
613 	vrele(dvp);
614 	return (error);
615 }
616 
617 int
618 vop_compat_nsymlink(struct vop_nsymlink_args *ap)
619 {
620 	struct thread *td = curthread;
621 	struct componentname cnp;
622 	struct nchandle *nch;
623 	struct namecache *ncp;
624 	struct vnode *dvp;
625 	struct vnode *vp;
626 	int error;
627 
628 	/*
629 	 * Sanity checks, get a locked directory vnode.
630 	 */
631 	*ap->a_vpp = NULL;
632 	nch = ap->a_nch;		/* locked namecache node */
633 	ncp = nch->ncp;
634 	dvp = ap->a_dvp;
635 
636 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
637 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
638 			ncp, ncp->nc_name);
639 		return(EAGAIN);
640 	}
641 
642 	/*
643 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
644 	 * caches all information required to create the entry in the
645 	 * directory inode.  We expect a return code of EJUSTRETURN for
646 	 * the CREATE case.  The cnp must simulated a saved-name situation.
647 	 */
648 	bzero(&cnp, sizeof(cnp));
649 	cnp.cn_nameiop = NAMEI_CREATE;
650 	cnp.cn_flags = CNP_LOCKPARENT;
651 	cnp.cn_nameptr = ncp->nc_name;
652 	cnp.cn_namelen = ncp->nc_nlen;
653 	cnp.cn_cred = ap->a_cred;
654 	cnp.cn_td = td;
655 
656 	vp = NULL;
657 	error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
658 
659 	/*
660 	 * EJUSTRETURN should be returned for this case, which means that
661 	 * the VFS has setup the directory inode for the create.  The dvp we
662 	 * passed in is expected to remain in a locked state.
663 	 *
664 	 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
665 	 * the cache state of the locked ncp that was passed to us.
666 	 */
667 	if (error == EJUSTRETURN) {
668 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
669 		error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
670 		if (error == 0) {
671 			cache_setunresolved(nch);
672 			cache_setvp(nch, vp);
673 			*ap->a_vpp = vp;
674 		}
675 	} else {
676 		if (error == 0) {
677 			vput(vp);
678 			vp = NULL;
679 			error = EEXIST;
680 		}
681 		KKASSERT(vp == NULL);
682 	}
683 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
684 		vn_unlock(dvp);
685 	vrele(dvp);
686 	return (error);
687 }
688 
689 /*
690  * vop_compat_nwhiteout { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
691  *			  struct vnode *a_dvp,
692  *			  struct ucred *a_cred,
693  *			  int a_flags }
694  *
695  * Issie a whiteout operation (create, lookup, or delete).  Compatibility
696  * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
697  * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
698  * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops.  For NAMEI_LOOKUP
699  * no lookup is necessary.
700  */
701 int
702 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
703 {
704 	struct thread *td = curthread;
705 	struct componentname cnp;
706 	struct nchandle *nch;
707 	struct namecache *ncp;
708 	struct vnode *dvp;
709 	struct vnode *vp;
710 	int error;
711 
712 	/*
713 	 * Sanity checks, get a locked directory vnode.
714 	 */
715 	nch = ap->a_nch;		/* locked namecache node */
716 	ncp = nch->ncp;
717 	dvp = ap->a_dvp;
718 
719 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
720 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
721 			ncp, ncp->nc_name);
722 		return(EAGAIN);
723 	}
724 
725 	/*
726 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
727 	 * caches all information required to create the entry in the
728 	 * directory inode.  We expect a return code of EJUSTRETURN for
729 	 * the CREATE case.  The cnp must simulated a saved-name situation.
730 	 */
731 	bzero(&cnp, sizeof(cnp));
732 	cnp.cn_nameiop = ap->a_flags;
733 	cnp.cn_flags = CNP_LOCKPARENT;
734 	cnp.cn_nameptr = ncp->nc_name;
735 	cnp.cn_namelen = ncp->nc_nlen;
736 	cnp.cn_cred = ap->a_cred;
737 	cnp.cn_td = td;
738 
739 	vp = NULL;
740 
741 	/*
742 	 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
743 	 * The VFS has setup the directory inode for the create.  The dvp we
744 	 * passed in is expected to remain in a locked state.
745 	 *
746 	 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
747 	 * the cache state of the locked ncp that was passed to us.
748 	 */
749 	switch(ap->a_flags) {
750 	case NAMEI_DELETE:
751 		cnp.cn_flags |= CNP_DOWHITEOUT;
752 		/* fall through */
753 	case NAMEI_CREATE:
754 		error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
755 		if (error == EJUSTRETURN) {
756 			KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
757 			error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
758 			if (error == 0)
759 				cache_setunresolved(nch);
760 		} else {
761 			if (error == 0) {
762 				vput(vp);
763 				vp = NULL;
764 				error = EEXIST;
765 			}
766 			KKASSERT(vp == NULL);
767 		}
768 		break;
769 	case NAMEI_LOOKUP:
770 		error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
771 		break;
772 	default:
773 		error = EINVAL;
774 		break;
775 	}
776 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
777 		vn_unlock(dvp);
778 	vrele(dvp);
779 	return (error);
780 }
781 
782 
783 /*
784  * vop_compat_nremove { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
785  *			struct vnode *a_dvp,
786  *			struct ucred *a_cred }
787  */
788 int
789 vop_compat_nremove(struct vop_nremove_args *ap)
790 {
791 	struct thread *td = curthread;
792 	struct componentname cnp;
793 	struct nchandle *nch;
794 	struct namecache *ncp;
795 	struct vnode *dvp;
796 	struct vnode *vp;
797 	int error;
798 
799 	/*
800 	 * Sanity checks, get a locked directory vnode.
801 	 */
802 	nch = ap->a_nch;		/* locked namecache node */
803 	ncp = nch->ncp;
804 	dvp = ap->a_dvp;
805 
806 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
807 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
808 			ncp, ncp->nc_name);
809 		return(EAGAIN);
810 	}
811 
812 	/*
813 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
814 	 * caches all information required to delete the entry in the
815 	 * directory inode.  We expect a return code of 0 for the DELETE
816 	 * case (meaning that a vp has been found).  The cnp must simulated
817 	 * a saved-name situation.
818 	 */
819 	bzero(&cnp, sizeof(cnp));
820 	cnp.cn_nameiop = NAMEI_DELETE;
821 	cnp.cn_flags = CNP_LOCKPARENT;
822 	cnp.cn_nameptr = ncp->nc_name;
823 	cnp.cn_namelen = ncp->nc_nlen;
824 	cnp.cn_cred = ap->a_cred;
825 	cnp.cn_td = td;
826 
827 	/*
828 	 * The vnode must be a directory and must not represent the
829 	 * current directory.
830 	 */
831 	vp = NULL;
832 	error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
833 	if (error == 0 && vp->v_type == VDIR)
834 		error = EPERM;
835 	if (error == 0) {
836 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
837 		error = VOP_OLD_REMOVE(dvp, vp, &cnp);
838 		if (error == 0) {
839 			cache_setunresolved(nch);
840 			cache_setvp(nch, NULL);
841 			cache_inval_vp(vp, CINV_DESTROY);
842 		}
843 	}
844 	if (vp) {
845 		if (dvp == vp)
846 			vrele(vp);
847 		else
848 			vput(vp);
849 	}
850 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
851 		vn_unlock(dvp);
852 	vrele(dvp);
853 	return (error);
854 }
855 
856 /*
857  * vop_compat_nrmdir { struct nchandle *a_nch, 	XXX STOPGAP FUNCTION
858  *		       struct vnode *dvp,
859  *		       struct ucred *a_cred }
860  */
861 int
862 vop_compat_nrmdir(struct vop_nrmdir_args *ap)
863 {
864 	struct thread *td = curthread;
865 	struct componentname cnp;
866 	struct nchandle *nch;
867 	struct namecache *ncp;
868 	struct vnode *dvp;
869 	struct vnode *vp;
870 	int error;
871 
872 	/*
873 	 * Sanity checks, get a locked directory vnode.
874 	 */
875 	nch = ap->a_nch;		/* locked namecache node */
876 	ncp = nch->ncp;
877 	dvp = ap->a_dvp;
878 
879 	if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
880 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
881 			ncp, ncp->nc_name);
882 		return(EAGAIN);
883 	}
884 
885 	/*
886 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
887 	 * caches all information required to delete the entry in the
888 	 * directory inode.  We expect a return code of 0 for the DELETE
889 	 * case (meaning that a vp has been found).  The cnp must simulated
890 	 * a saved-name situation.
891 	 */
892 	bzero(&cnp, sizeof(cnp));
893 	cnp.cn_nameiop = NAMEI_DELETE;
894 	cnp.cn_flags = CNP_LOCKPARENT;
895 	cnp.cn_nameptr = ncp->nc_name;
896 	cnp.cn_namelen = ncp->nc_nlen;
897 	cnp.cn_cred = ap->a_cred;
898 	cnp.cn_td = td;
899 
900 	/*
901 	 * The vnode must be a directory and must not represent the
902 	 * current directory.
903 	 */
904 	vp = NULL;
905 	error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
906 	if (error == 0 && vp->v_type != VDIR)
907 		error = ENOTDIR;
908 	if (error == 0 && vp == dvp)
909 		error = EINVAL;
910 	if (error == 0 && (vp->v_flag & VROOT))
911 		error = EBUSY;
912 	if (error == 0) {
913 		KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
914 		error = VOP_OLD_RMDIR(dvp, vp, &cnp);
915 
916 		/*
917 		 * Note that this invalidation will cause any process
918 		 * currently CD'd into the directory being removed to be
919 		 * disconnected from the topology and not be able to ".."
920 		 * back out.
921 		 */
922 		if (error == 0) {
923 			cache_inval(nch, CINV_DESTROY);
924 			cache_inval_vp(vp, CINV_DESTROY);
925 		}
926 	}
927 	if (vp) {
928 		if (dvp == vp)
929 			vrele(vp);
930 		else
931 			vput(vp);
932 	}
933 	if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
934 		vn_unlock(dvp);
935 	vrele(dvp);
936 	return (error);
937 }
938 
939 /*
940  * vop_compat_nrename { struct nchandle *a_fnch, 	XXX STOPGAP FUNCTION
941  *			struct nchandle *a_tnch,
942  *			struct ucred *a_cred }
943  *
944  * This is a fairly difficult procedure.  The old VOP_OLD_RENAME requires that
945  * the source directory and vnode be unlocked and the target directory and
946  * vnode (if it exists) be locked.  All arguments will be vrele'd and
947  * the targets will also be unlocked regardless of the return code.
948  */
949 int
950 vop_compat_nrename(struct vop_nrename_args *ap)
951 {
952 	struct thread *td = curthread;
953 	struct componentname fcnp;
954 	struct componentname tcnp;
955 	struct nchandle *fnch;
956 	struct nchandle *tnch;
957 	struct namecache *fncp;
958 	struct namecache *tncp;
959 	struct vnode *fdvp, *fvp;
960 	struct vnode *tdvp, *tvp;
961 	int error;
962 
963 	/*
964 	 * Sanity checks, get referenced vnodes representing the source.
965 	 */
966 	fnch = ap->a_fnch;		/* locked namecache node */
967 	fncp = fnch->ncp;
968 	fdvp = ap->a_fdvp;
969 
970 	/*
971 	 * Temporarily lock the source directory and lookup in DELETE mode to
972 	 * check permissions.  XXX delete permissions should have been
973 	 * checked by nlookup(), we need to add NLC_DELETE for delete
974 	 * checking.  It is unclear whether VFS's require the directory setup
975 	 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
976 	 * since it isn't locked and since UFS always does a relookup of
977 	 * the source, it is believed that the only side effect that matters
978 	 * is the permissions check.
979 	 */
980 	if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) {
981 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
982 			fncp, fncp->nc_name);
983 		return(EAGAIN);
984 	}
985 
986 	bzero(&fcnp, sizeof(fcnp));
987 	fcnp.cn_nameiop = NAMEI_DELETE;
988 	fcnp.cn_flags = CNP_LOCKPARENT;
989 	fcnp.cn_nameptr = fncp->nc_name;
990 	fcnp.cn_namelen = fncp->nc_nlen;
991 	fcnp.cn_cred = ap->a_cred;
992 	fcnp.cn_td = td;
993 
994 	/*
995 	 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
996 	 * fvp.
997 	 */
998 	fvp = NULL;
999 	error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
1000 	if (error == 0 && (fvp->v_flag & VROOT)) {
1001 		vput(fvp);	/* as if vop_old_lookup had failed */
1002 		error = EBUSY;
1003 	}
1004 	if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1005 		fcnp.cn_flags |= CNP_PDIRUNLOCK;
1006 		vn_unlock(fdvp);
1007 	}
1008 	if (error) {
1009 		vrele(fdvp);
1010 		return (error);
1011 	}
1012 	vn_unlock(fvp);
1013 
1014 	/*
1015 	 * fdvp and fvp are now referenced and unlocked.
1016 	 *
1017 	 * Get a locked directory vnode for the target and lookup the target
1018 	 * in CREATE mode so it places the required information in the
1019 	 * directory inode.
1020 	 */
1021 	tnch = ap->a_tnch;		/* locked namecache node */
1022 	tncp = tnch->ncp;
1023 	tdvp = ap->a_tdvp;
1024 	if (error) {
1025 		vrele(fdvp);
1026 		vrele(fvp);
1027 		return (error);
1028 	}
1029 	if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) {
1030 		kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1031 			tncp, tncp->nc_name);
1032 		vrele(fdvp);
1033 		vrele(fvp);
1034 		return(EAGAIN);
1035 	}
1036 
1037 	/*
1038 	 * Setup the cnp for a traditional vop_old_lookup() call.  The lookup
1039 	 * caches all information required to create the entry in the
1040 	 * target directory inode.
1041 	 */
1042 	bzero(&tcnp, sizeof(tcnp));
1043 	tcnp.cn_nameiop = NAMEI_RENAME;
1044 	tcnp.cn_flags = CNP_LOCKPARENT;
1045 	tcnp.cn_nameptr = tncp->nc_name;
1046 	tcnp.cn_namelen = tncp->nc_nlen;
1047 	tcnp.cn_cred = ap->a_cred;
1048 	tcnp.cn_td = td;
1049 
1050 	tvp = NULL;
1051 	error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
1052 
1053 	if (error == EJUSTRETURN) {
1054 		/*
1055 		 * Target does not exist.  tvp should be NULL.
1056 		 */
1057 		KKASSERT(tvp == NULL);
1058 		KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1059 		error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1060 		if (error == 0)
1061 			cache_rename(fnch, tnch);
1062 	} else if (error == 0) {
1063 		/*
1064 		 * Target exists.  VOP_OLD_RENAME should correctly delete the
1065 		 * target.
1066 		 */
1067 		KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1068 		error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1069 		if (error == 0)
1070 			cache_rename(fnch, tnch);
1071 	} else {
1072 		vrele(fdvp);
1073 		vrele(fvp);
1074 		if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1075 			vrele(tdvp);
1076 		else
1077 			vput(tdvp);
1078 	}
1079 	return (error);
1080 }
1081 
1082 static int
1083 vop_nolookup(struct vop_old_lookup_args *ap)
1084 {
1085 
1086 	*ap->a_vpp = NULL;
1087 	return (ENOTDIR);
1088 }
1089 
1090 /*
1091  *	vop_nostrategy:
1092  *
1093  *	Strategy routine for VFS devices that have none.
1094  *
1095  *	B_ERROR and B_INVAL must be cleared prior to calling any strategy
1096  *	routine.  Typically this is done for a BUF_CMD_READ strategy call.
1097  *	Typically B_INVAL is assumed to already be clear prior to a write
1098  *	and should not be cleared manually unless you just made the buffer
1099  *	invalid.  B_ERROR should be cleared either way.
1100  */
1101 
1102 static int
1103 vop_nostrategy (struct vop_strategy_args *ap)
1104 {
1105 	kprintf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
1106 	vprint("", ap->a_vp);
1107 	ap->a_bio->bio_buf->b_flags |= B_ERROR;
1108 	ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1109 	biodone(ap->a_bio);
1110 	return (EOPNOTSUPP);
1111 }
1112 
1113 int
1114 vop_stdpathconf(struct vop_pathconf_args *ap)
1115 {
1116 	int error = 0;
1117 
1118 	switch (ap->a_name) {
1119 	case _PC_LINK_MAX:
1120 		*ap->a_retval = LINK_MAX;
1121 		break;
1122 	case _PC_NAME_MAX:
1123 		*ap->a_retval = NAME_MAX;
1124 		break;
1125 	case _PC_PATH_MAX:
1126 		*ap->a_retval = PATH_MAX;
1127 		break;
1128 	case _PC_MAX_CANON:
1129 		*ap->a_retval = MAX_CANON;
1130 		break;
1131 	case _PC_MAX_INPUT:
1132 		*ap->a_retval = MAX_INPUT;
1133 		break;
1134 	case _PC_PIPE_BUF:
1135 		*ap->a_retval = PIPE_BUF;
1136 		break;
1137 	case _PC_CHOWN_RESTRICTED:
1138 		*ap->a_retval = 1;
1139 		break;
1140 	case _PC_NO_TRUNC:
1141 		*ap->a_retval = 1;
1142 		break;
1143 	case _PC_VDISABLE:
1144 		*ap->a_retval = _POSIX_VDISABLE;
1145 		break;
1146 	default:
1147 		error = EINVAL;
1148 		break;
1149 	}
1150 	return (error);
1151 }
1152 
1153 /*
1154  * Standard open.
1155  *
1156  * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
1157  *
1158  * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1159  */
1160 int
1161 vop_stdopen(struct vop_open_args *ap)
1162 {
1163 	struct vnode *vp = ap->a_vp;
1164 	struct file *fp;
1165 
1166 	if ((fp = ap->a_fp) != NULL) {
1167 		switch(vp->v_type) {
1168 		case VFIFO:
1169 			fp->f_type = DTYPE_FIFO;
1170 			break;
1171 		default:
1172 			fp->f_type = DTYPE_VNODE;
1173 			break;
1174 		}
1175 		fp->f_flag = ap->a_mode & FMASK;
1176 		fp->f_ops = &vnode_fileops;
1177 		fp->f_data = vp;
1178 		vref(vp);
1179 	}
1180 	if (ap->a_mode & FWRITE)
1181 		++vp->v_writecount;
1182 	KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX);
1183 	++vp->v_opencount;
1184 	return (0);
1185 }
1186 
1187 /*
1188  * Standard close.
1189  *
1190  * (struct vnode *a_vp, int a_fflag)
1191  *
1192  * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE.  same as a_mode in stdopen?
1193  */
1194 int
1195 vop_stdclose(struct vop_close_args *ap)
1196 {
1197 	struct vnode *vp = ap->a_vp;
1198 
1199 	KASSERT(vp->v_opencount > 0,
1200 		("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x\n",
1201 		vp, vp->v_opencount, vp->v_type, *vp->v_ops, vp->v_flag));
1202 	if (ap->a_fflag & FWRITE) {
1203 		KASSERT(vp->v_writecount > 0,
1204 			("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1205 			vp, vp->v_writecount));
1206 		--vp->v_writecount;
1207 	}
1208 	--vp->v_opencount;
1209 	return (0);
1210 }
1211 
1212 /*
1213  * Return true for select/poll.
1214  */
1215 int
1216 vop_nopoll(struct vop_poll_args *ap)
1217 {
1218 	/*
1219 	 * Return true for read/write.  If the user asked for something
1220 	 * special, return POLLNVAL, so that clients have a way of
1221 	 * determining reliably whether or not the extended
1222 	 * functionality is present without hard-coding knowledge
1223 	 * of specific filesystem implementations.
1224 	 */
1225 	if (ap->a_events & ~POLLSTANDARD)
1226 		return (POLLNVAL);
1227 
1228 	return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1229 }
1230 
1231 /*
1232  * Implement poll for local filesystems that support it.
1233  */
1234 int
1235 vop_stdpoll(struct vop_poll_args *ap)
1236 {
1237 	if (ap->a_events & ~POLLSTANDARD)
1238 		return (vn_pollrecord(ap->a_vp, ap->a_events));
1239 	return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1240 }
1241 
1242 /*
1243  * Implement standard getpages and putpages.  All filesystems must use
1244  * the buffer cache to back regular files.
1245  */
1246 int
1247 vop_stdgetpages(struct vop_getpages_args *ap)
1248 {
1249 	struct mount *mp;
1250 	int error;
1251 
1252 	if ((mp = ap->a_vp->v_mount) != NULL) {
1253 		error = vnode_pager_generic_getpages(
1254 				ap->a_vp, ap->a_m, ap->a_count,
1255 				ap->a_reqpage);
1256 	} else {
1257 		error = VM_PAGER_BAD;
1258 	}
1259 	return (error);
1260 }
1261 
1262 int
1263 vop_stdputpages(struct vop_putpages_args *ap)
1264 {
1265 	struct mount *mp;
1266 	int error;
1267 
1268 	if ((mp = ap->a_vp->v_mount) != NULL) {
1269 		error = vnode_pager_generic_putpages(
1270 				ap->a_vp, ap->a_m, ap->a_count,
1271 				ap->a_sync, ap->a_rtvals);
1272 	} else {
1273 		error = VM_PAGER_BAD;
1274 	}
1275 	return (error);
1276 }
1277 
1278 /*
1279  * vfs default ops
1280  * used to fill the vfs fucntion table to get reasonable default return values.
1281  */
1282 int
1283 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
1284 {
1285 	return (0);
1286 }
1287 
1288 int
1289 vfs_stdunmount(struct mount *mp, int mntflags)
1290 {
1291 	return (0);
1292 }
1293 
1294 int
1295 vfs_stdroot(struct mount *mp, struct vnode **vpp)
1296 {
1297 	return (EOPNOTSUPP);
1298 }
1299 
1300 int
1301 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
1302 {
1303 	return (EOPNOTSUPP);
1304 }
1305 
1306 /*
1307  * If the VFS does not implement statvfs, then call statfs and convert
1308  * the values.  This code was taken from libc's __cvtstatvfs() function,
1309  * contributed by Joerg Sonnenberger.
1310  */
1311 int
1312 vfs_stdstatvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
1313 {
1314 	struct statfs *in;
1315 	int error;
1316 
1317 	in = &mp->mnt_stat;
1318 	error = VFS_STATFS(mp, in, cred);
1319 	if (error == 0) {
1320 		bzero(sbp, sizeof(*sbp));
1321 
1322 		sbp->f_bsize = in->f_bsize;
1323 		sbp->f_frsize = in->f_bsize;
1324 		sbp->f_blocks = in->f_blocks;
1325 		sbp->f_bfree = in->f_bfree;
1326 		sbp->f_bavail = in->f_bavail;
1327 		sbp->f_files = in->f_files;
1328 		sbp->f_ffree = in->f_ffree;
1329 
1330 		/*
1331 		 * XXX
1332 		 * This field counts the number of available inodes to non-root
1333 		 * users, but this information is not available via statfs.
1334 		 * Just ignore this issue by returning the total number
1335 		 * instead.
1336 		 */
1337 		sbp->f_favail = in->f_ffree;
1338 
1339 		/*
1340 		 * XXX
1341 		 * This field has a different meaning for statfs and statvfs.
1342 		 * For the former it is the cookie exported for NFS and not
1343 		 * intended for normal userland use.
1344 		 */
1345 		sbp->f_fsid = 0;
1346 
1347 		sbp->f_flag = 0;
1348 		if (in->f_flags & MNT_RDONLY)
1349 			sbp->f_flag |= ST_RDONLY;
1350 		if (in->f_flags & MNT_NOSUID)
1351 			sbp->f_flag |= ST_NOSUID;
1352 		sbp->f_namemax = 0;
1353 		sbp->f_owner = in->f_owner;
1354 		/*
1355 		 * XXX
1356 		 * statfs contains the type as string, statvfs expects it as
1357 		 * enumeration.
1358 		 */
1359 		sbp->f_type = 0;
1360 
1361 		sbp->f_syncreads = in->f_syncreads;
1362 		sbp->f_syncwrites = in->f_syncwrites;
1363 		sbp->f_asyncreads = in->f_asyncreads;
1364 		sbp->f_asyncwrites = in->f_asyncwrites;
1365 	}
1366 	return (error);
1367 }
1368 
1369 int
1370 vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
1371 {
1372 	return (EOPNOTSUPP);
1373 }
1374 
1375 int
1376 vfs_stdstart(struct mount *mp, int flags)
1377 {
1378 	return (0);
1379 }
1380 
1381 int
1382 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
1383 	caddr_t arg, struct ucred *cred)
1384 {
1385 	return (EOPNOTSUPP);
1386 }
1387 
1388 int
1389 vfs_stdsync(struct mount *mp, int waitfor)
1390 {
1391 	return (0);
1392 }
1393 
1394 int
1395 vfs_stdnosync(struct mount *mp, int waitfor)
1396 {
1397 	return (EOPNOTSUPP);
1398 }
1399 
1400 int
1401 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp)
1402 {
1403 	return (EOPNOTSUPP);
1404 }
1405 
1406 int
1407 vfs_stdfhtovp(struct mount *mp, struct vnode *rootvp,
1408 	      struct fid *fhp, struct vnode **vpp)
1409 {
1410 	return (EOPNOTSUPP);
1411 }
1412 
1413 int
1414 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1415 	struct ucred **credanonp)
1416 {
1417 	return (EOPNOTSUPP);
1418 }
1419 
1420 int
1421 vfs_stdinit(struct vfsconf *vfsp)
1422 {
1423 	return (0);
1424 }
1425 
1426 int
1427 vfs_stduninit(struct vfsconf *vfsp)
1428 {
1429 	return(0);
1430 }
1431 
1432 int
1433 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname,
1434 	caddr_t arg, struct ucred *cred)
1435 {
1436 	return(EOPNOTSUPP);
1437 }
1438 
1439 /* end of vfs default ops */
1440