Merge from vendor branch GCC:
[dragonfly.git] / sys / kern / vfs_default.c
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 */