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