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