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