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