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