HAMMER 60I/Many: Mirroring
[dragonfly.git] / sys / kern / vfs_default.c
blob8f655b1fc007c59265ad7239f2e8a5e07ca6bc7d
1 /*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed
6 * to Berkeley by John Heidemann of the UCLA Ficus project.
8 * The statvfs->statfs conversion code was contributed to the DragonFly
9 * Project by Joerg Sonnenberger <joerg@bec.de>.
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.
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.
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.53 2008/06/01 19:27:35 dillon Exp $
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>
61 #include <machine/limits.h>
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>
69 static int vop_nolookup (struct vop_old_lookup_args *);
70 static int vop_nostrategy (struct vop_strategy_args *);
73 * This vnode table stores what we want to do if the filesystem doesn't
74 * implement a particular VOP.
76 * If there is no specific entry here, we will return EOPNOTSUPP.
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 = (void *)vop_einval,
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_nresolve = vop_compat_nresolve,
99 .vop_nlookupdotdot = vop_compat_nlookupdotdot,
100 .vop_ncreate = vop_compat_ncreate,
101 .vop_nmkdir = vop_compat_nmkdir,
102 .vop_nmknod = vop_compat_nmknod,
103 .vop_nlink = vop_compat_nlink,
104 .vop_nsymlink = vop_compat_nsymlink,
105 .vop_nwhiteout = vop_compat_nwhiteout,
106 .vop_nremove = vop_compat_nremove,
107 .vop_nrmdir = vop_compat_nrmdir,
108 .vop_nrename = vop_compat_nrename,
109 .vop_mountctl = journal_mountctl
112 VNODEOP_SET(default_vnode_vops);
115 vop_eopnotsupp(struct vop_generic_args *ap)
117 return (EOPNOTSUPP);
121 vop_ebadf(struct vop_generic_args *ap)
123 return (EBADF);
127 vop_enotty(struct vop_generic_args *ap)
129 return (ENOTTY);
133 vop_einval(struct vop_generic_args *ap)
135 return (EINVAL);
139 vop_null(struct vop_generic_args *ap)
141 return (0);
145 vop_defaultop(struct vop_generic_args *ap)
147 return (VOCALL(&default_vnode_vops, ap));
151 vop_panic(struct vop_generic_args *ap)
153 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name);
157 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
158 * XXX STOPGAP FUNCTION
160 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
161 * WILL BE REMOVED. This procedure exists for all VFSs which have not
162 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
163 * vop_old_lookup() and does appropriate translations.
165 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
166 * VFSs will support this VOP and this routine can be removed, since
167 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
168 * API.
170 * A locked ncp is passed in to be resolved. The NCP is resolved by
171 * figuring out the vnode (if any) and calling cache_setvp() to attach the
172 * vnode to the entry. If the entry represents a non-existant node then
173 * cache_setvp() is called with a NULL vnode to resolve the entry into a
174 * negative cache entry. No vnode locks are retained and the
175 * ncp is left locked on return.
177 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
179 * There is a potential directory and vnode interlock. The lock order
180 * requirement is: namecache, governing directory, resolved vnode.
183 vop_compat_nresolve(struct vop_nresolve_args *ap)
185 int error;
186 struct vnode *dvp;
187 struct vnode *vp;
188 struct nchandle *nch;
189 struct namecache *ncp;
190 struct componentname cnp;
192 nch = ap->a_nch; /* locked namecache node */
193 ncp = nch->ncp;
194 dvp = ap->a_dvp;
197 * UFS currently stores all sorts of side effects, including a loop
198 * variable, in the directory inode. That needs to be fixed and the
199 * other VFS's audited before we can switch to LK_SHARED.
201 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
202 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
203 ncp, ncp->nc_name);
204 return(EAGAIN);
207 bzero(&cnp, sizeof(cnp));
208 cnp.cn_nameiop = NAMEI_LOOKUP;
209 cnp.cn_flags = 0;
210 cnp.cn_nameptr = ncp->nc_name;
211 cnp.cn_namelen = ncp->nc_nlen;
212 cnp.cn_cred = ap->a_cred;
213 cnp.cn_td = curthread; /* XXX */
216 * vop_old_lookup() always returns vp locked. dvp may or may not be
217 * left locked depending on CNP_PDIRUNLOCK.
219 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
220 if (error == 0)
221 vn_unlock(vp);
222 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
223 vn_unlock(dvp);
224 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
225 /* was resolved by another process while we were unlocked */
226 if (error == 0)
227 vrele(vp);
228 } else if (error == 0) {
229 KKASSERT(vp != NULL);
230 cache_setvp(nch, vp);
231 vrele(vp);
232 } else if (error == ENOENT) {
233 KKASSERT(vp == NULL);
234 if (cnp.cn_flags & CNP_ISWHITEOUT)
235 ncp->nc_flag |= NCF_WHITEOUT;
236 cache_setvp(nch, NULL);
238 vrele(dvp);
239 return (error);
243 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
244 * struct vnode **a_vpp,
245 * struct ucred *a_cred }
247 * Lookup the vnode representing the parent directory of the specified
248 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
249 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
251 * This function is designed to aid NFS server-side operations and is
252 * used by cache_fromdvp() to create a consistent, connected namecache
253 * topology.
255 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
256 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
257 * permits VFSs will implement the remaining *_n*() calls and finally get
258 * rid of their *_lookup() call.
261 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
263 struct componentname cnp;
264 int error;
267 * UFS currently stores all sorts of side effects, including a loop
268 * variable, in the directory inode. That needs to be fixed and the
269 * other VFS's audited before we can switch to LK_SHARED.
271 *ap->a_vpp = NULL;
272 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE)) != 0)
273 return (error);
274 if (ap->a_dvp->v_type != VDIR) {
275 vput(ap->a_dvp);
276 return (ENOTDIR);
279 bzero(&cnp, sizeof(cnp));
280 cnp.cn_nameiop = NAMEI_LOOKUP;
281 cnp.cn_flags = CNP_ISDOTDOT;
282 cnp.cn_nameptr = "..";
283 cnp.cn_namelen = 2;
284 cnp.cn_cred = ap->a_cred;
285 cnp.cn_td = curthread; /* XXX */
288 * vop_old_lookup() always returns vp locked. dvp may or may not be
289 * left locked depending on CNP_PDIRUNLOCK.
291 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
292 if (error == 0)
293 vn_unlock(*ap->a_vpp);
294 if (cnp.cn_flags & CNP_PDIRUNLOCK)
295 vrele(ap->a_dvp);
296 else
297 vput(ap->a_dvp);
298 return (error);
302 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
303 * struct vnode *a_dvp,
304 * struct vnode **a_vpp,
305 * struct ucred *a_cred,
306 * struct vattr *a_vap }
308 * Create a file as specified by a_vap. Compatibility requires us to issue
309 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
310 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
313 vop_compat_ncreate(struct vop_ncreate_args *ap)
315 struct thread *td = curthread;
316 struct componentname cnp;
317 struct nchandle *nch;
318 struct namecache *ncp;
319 struct vnode *dvp;
320 int error;
323 * Sanity checks, get a locked directory vnode.
325 nch = ap->a_nch; /* locked namecache node */
326 dvp = ap->a_dvp;
327 ncp = nch->ncp;
329 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
330 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
331 ncp, ncp->nc_name);
332 return(EAGAIN);
336 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
337 * caches all information required to create the entry in the
338 * directory inode. We expect a return code of EJUSTRETURN for
339 * the CREATE case. The cnp must simulated a saved-name situation.
341 bzero(&cnp, sizeof(cnp));
342 cnp.cn_nameiop = NAMEI_CREATE;
343 cnp.cn_flags = CNP_LOCKPARENT;
344 cnp.cn_nameptr = ncp->nc_name;
345 cnp.cn_namelen = ncp->nc_nlen;
346 cnp.cn_cred = ap->a_cred;
347 cnp.cn_td = td;
348 *ap->a_vpp = NULL;
350 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
353 * EJUSTRETURN should be returned for this case, which means that
354 * the VFS has setup the directory inode for the create. The dvp we
355 * passed in is expected to remain in a locked state.
357 * If the VOP_OLD_CREATE is successful we are responsible for updating
358 * the cache state of the locked ncp that was passed to us.
360 if (error == EJUSTRETURN) {
361 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
362 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
363 if (error == 0) {
364 cache_setunresolved(nch);
365 cache_setvp(nch, *ap->a_vpp);
367 } else {
368 if (error == 0) {
369 vput(*ap->a_vpp);
370 *ap->a_vpp = NULL;
371 error = EEXIST;
373 KKASSERT(*ap->a_vpp == NULL);
375 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
376 vn_unlock(dvp);
377 vrele(dvp);
378 return (error);
382 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
383 * struct vnode *a_dvp,
384 * struct vnode **a_vpp,
385 * struct ucred *a_cred,
386 * struct vattr *a_vap }
388 * Create a directory as specified by a_vap. Compatibility requires us to
389 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
390 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
393 vop_compat_nmkdir(struct vop_nmkdir_args *ap)
395 struct thread *td = curthread;
396 struct componentname cnp;
397 struct nchandle *nch;
398 struct namecache *ncp;
399 struct vnode *dvp;
400 int error;
403 * Sanity checks, get a locked directory vnode.
405 nch = ap->a_nch; /* locked namecache node */
406 ncp = nch->ncp;
407 dvp = ap->a_dvp;
408 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
409 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
410 ncp, ncp->nc_name);
411 return(EAGAIN);
415 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
416 * caches all information required to create the entry in the
417 * directory inode. We expect a return code of EJUSTRETURN for
418 * the CREATE case. The cnp must simulated a saved-name situation.
420 bzero(&cnp, sizeof(cnp));
421 cnp.cn_nameiop = NAMEI_CREATE;
422 cnp.cn_flags = CNP_LOCKPARENT;
423 cnp.cn_nameptr = ncp->nc_name;
424 cnp.cn_namelen = ncp->nc_nlen;
425 cnp.cn_cred = ap->a_cred;
426 cnp.cn_td = td;
427 *ap->a_vpp = NULL;
429 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
432 * EJUSTRETURN should be returned for this case, which means that
433 * the VFS has setup the directory inode for the create. The dvp we
434 * passed in is expected to remain in a locked state.
436 * If the VOP_OLD_MKDIR is successful we are responsible for updating
437 * the cache state of the locked ncp that was passed to us.
439 if (error == EJUSTRETURN) {
440 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
441 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
442 if (error == 0) {
443 cache_setunresolved(nch);
444 cache_setvp(nch, *ap->a_vpp);
446 } else {
447 if (error == 0) {
448 vput(*ap->a_vpp);
449 *ap->a_vpp = NULL;
450 error = EEXIST;
452 KKASSERT(*ap->a_vpp == NULL);
454 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
455 vn_unlock(dvp);
456 vrele(dvp);
457 return (error);
461 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
462 * struct vnode *a_dvp,
463 * struct vnode **a_vpp,
464 * struct ucred *a_cred,
465 * struct vattr *a_vap }
467 * Create a device or fifo node as specified by a_vap. Compatibility requires
468 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
469 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
472 vop_compat_nmknod(struct vop_nmknod_args *ap)
474 struct thread *td = curthread;
475 struct componentname cnp;
476 struct nchandle *nch;
477 struct namecache *ncp;
478 struct vnode *dvp;
479 int error;
482 * Sanity checks, get a locked directory vnode.
484 nch = ap->a_nch; /* locked namecache node */
485 ncp = nch->ncp;
486 dvp = ap->a_dvp;
488 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
489 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
490 ncp, ncp->nc_name);
491 return(EAGAIN);
495 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
496 * caches all information required to create the entry in the
497 * directory inode. We expect a return code of EJUSTRETURN for
498 * the CREATE case. The cnp must simulated a saved-name situation.
500 bzero(&cnp, sizeof(cnp));
501 cnp.cn_nameiop = NAMEI_CREATE;
502 cnp.cn_flags = CNP_LOCKPARENT;
503 cnp.cn_nameptr = ncp->nc_name;
504 cnp.cn_namelen = ncp->nc_nlen;
505 cnp.cn_cred = ap->a_cred;
506 cnp.cn_td = td;
507 *ap->a_vpp = NULL;
509 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
512 * EJUSTRETURN should be returned for this case, which means that
513 * the VFS has setup the directory inode for the create. The dvp we
514 * passed in is expected to remain in a locked state.
516 * If the VOP_OLD_MKNOD is successful we are responsible for updating
517 * the cache state of the locked ncp that was passed to us.
519 if (error == EJUSTRETURN) {
520 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
521 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
522 if (error == 0) {
523 cache_setunresolved(nch);
524 cache_setvp(nch, *ap->a_vpp);
526 } else {
527 if (error == 0) {
528 vput(*ap->a_vpp);
529 *ap->a_vpp = NULL;
530 error = EEXIST;
532 KKASSERT(*ap->a_vpp == NULL);
534 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
535 vn_unlock(dvp);
536 vrele(dvp);
537 return (error);
541 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
542 * struct vnode *a_dvp,
543 * struct vnode *a_vp,
544 * struct ucred *a_cred }
546 * The passed vp is locked and represents the source. The passed ncp is
547 * locked and represents the target to create.
550 vop_compat_nlink(struct vop_nlink_args *ap)
552 struct thread *td = curthread;
553 struct componentname cnp;
554 struct nchandle *nch;
555 struct namecache *ncp;
556 struct vnode *dvp;
557 struct vnode *tvp;
558 int error;
561 * Sanity checks, get a locked directory vnode.
563 nch = ap->a_nch; /* locked namecache node */
564 ncp = nch->ncp;
565 dvp = ap->a_dvp;
567 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
568 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
569 ncp, ncp->nc_name);
570 return(EAGAIN);
574 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
575 * caches all information required to create the entry in the
576 * directory inode. We expect a return code of EJUSTRETURN for
577 * the CREATE case. The cnp must simulated a saved-name situation.
579 bzero(&cnp, sizeof(cnp));
580 cnp.cn_nameiop = NAMEI_CREATE;
581 cnp.cn_flags = CNP_LOCKPARENT;
582 cnp.cn_nameptr = ncp->nc_name;
583 cnp.cn_namelen = ncp->nc_nlen;
584 cnp.cn_cred = ap->a_cred;
585 cnp.cn_td = td;
587 tvp = NULL;
588 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
591 * EJUSTRETURN should be returned for this case, which means that
592 * the VFS has setup the directory inode for the create. The dvp we
593 * passed in is expected to remain in a locked state.
595 * If the VOP_OLD_LINK is successful we are responsible for updating
596 * the cache state of the locked ncp that was passed to us.
598 if (error == EJUSTRETURN) {
599 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
600 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
601 if (error == 0) {
602 cache_setunresolved(nch);
603 cache_setvp(nch, ap->a_vp);
605 } else {
606 if (error == 0) {
607 vput(tvp);
608 error = EEXIST;
611 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
612 vn_unlock(dvp);
613 vrele(dvp);
614 return (error);
618 vop_compat_nsymlink(struct vop_nsymlink_args *ap)
620 struct thread *td = curthread;
621 struct componentname cnp;
622 struct nchandle *nch;
623 struct namecache *ncp;
624 struct vnode *dvp;
625 struct vnode *vp;
626 int error;
629 * Sanity checks, get a locked directory vnode.
631 *ap->a_vpp = NULL;
632 nch = ap->a_nch; /* locked namecache node */
633 ncp = nch->ncp;
634 dvp = ap->a_dvp;
636 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
637 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
638 ncp, ncp->nc_name);
639 return(EAGAIN);
643 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
644 * caches all information required to create the entry in the
645 * directory inode. We expect a return code of EJUSTRETURN for
646 * the CREATE case. The cnp must simulated a saved-name situation.
648 bzero(&cnp, sizeof(cnp));
649 cnp.cn_nameiop = NAMEI_CREATE;
650 cnp.cn_flags = CNP_LOCKPARENT;
651 cnp.cn_nameptr = ncp->nc_name;
652 cnp.cn_namelen = ncp->nc_nlen;
653 cnp.cn_cred = ap->a_cred;
654 cnp.cn_td = td;
656 vp = NULL;
657 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
660 * EJUSTRETURN should be returned for this case, which means that
661 * the VFS has setup the directory inode for the create. The dvp we
662 * passed in is expected to remain in a locked state.
664 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
665 * the cache state of the locked ncp that was passed to us.
667 if (error == EJUSTRETURN) {
668 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
669 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
670 if (error == 0) {
671 cache_setunresolved(nch);
672 cache_setvp(nch, vp);
673 *ap->a_vpp = vp;
675 } else {
676 if (error == 0) {
677 vput(vp);
678 vp = NULL;
679 error = EEXIST;
681 KKASSERT(vp == NULL);
683 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
684 vn_unlock(dvp);
685 vrele(dvp);
686 return (error);
690 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
691 * struct vnode *a_dvp,
692 * struct ucred *a_cred,
693 * int a_flags }
695 * Issie a whiteout operation (create, lookup, or delete). Compatibility
696 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
697 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
698 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
699 * no lookup is necessary.
702 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
704 struct thread *td = curthread;
705 struct componentname cnp;
706 struct nchandle *nch;
707 struct namecache *ncp;
708 struct vnode *dvp;
709 struct vnode *vp;
710 int error;
713 * Sanity checks, get a locked directory vnode.
715 nch = ap->a_nch; /* locked namecache node */
716 ncp = nch->ncp;
717 dvp = ap->a_dvp;
719 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
720 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
721 ncp, ncp->nc_name);
722 return(EAGAIN);
726 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
727 * caches all information required to create the entry in the
728 * directory inode. We expect a return code of EJUSTRETURN for
729 * the CREATE case. The cnp must simulated a saved-name situation.
731 bzero(&cnp, sizeof(cnp));
732 cnp.cn_nameiop = ap->a_flags;
733 cnp.cn_flags = CNP_LOCKPARENT;
734 cnp.cn_nameptr = ncp->nc_name;
735 cnp.cn_namelen = ncp->nc_nlen;
736 cnp.cn_cred = ap->a_cred;
737 cnp.cn_td = td;
739 vp = NULL;
742 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
743 * The VFS has setup the directory inode for the create. The dvp we
744 * passed in is expected to remain in a locked state.
746 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
747 * the cache state of the locked ncp that was passed to us.
749 switch(ap->a_flags) {
750 case NAMEI_DELETE:
751 cnp.cn_flags |= CNP_DOWHITEOUT;
752 /* fall through */
753 case NAMEI_CREATE:
754 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
755 if (error == EJUSTRETURN) {
756 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
757 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
758 if (error == 0)
759 cache_setunresolved(nch);
760 } else {
761 if (error == 0) {
762 vput(vp);
763 vp = NULL;
764 error = EEXIST;
766 KKASSERT(vp == NULL);
768 break;
769 case NAMEI_LOOKUP:
770 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
771 break;
772 default:
773 error = EINVAL;
774 break;
776 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
777 vn_unlock(dvp);
778 vrele(dvp);
779 return (error);
784 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
785 * struct vnode *a_dvp,
786 * struct ucred *a_cred }
789 vop_compat_nremove(struct vop_nremove_args *ap)
791 struct thread *td = curthread;
792 struct componentname cnp;
793 struct nchandle *nch;
794 struct namecache *ncp;
795 struct vnode *dvp;
796 struct vnode *vp;
797 int error;
800 * Sanity checks, get a locked directory vnode.
802 nch = ap->a_nch; /* locked namecache node */
803 ncp = nch->ncp;
804 dvp = ap->a_dvp;
806 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
807 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
808 ncp, ncp->nc_name);
809 return(EAGAIN);
813 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
814 * caches all information required to delete the entry in the
815 * directory inode. We expect a return code of 0 for the DELETE
816 * case (meaning that a vp has been found). The cnp must simulated
817 * a saved-name situation.
819 bzero(&cnp, sizeof(cnp));
820 cnp.cn_nameiop = NAMEI_DELETE;
821 cnp.cn_flags = CNP_LOCKPARENT;
822 cnp.cn_nameptr = ncp->nc_name;
823 cnp.cn_namelen = ncp->nc_nlen;
824 cnp.cn_cred = ap->a_cred;
825 cnp.cn_td = td;
828 * The vnode must be a directory and must not represent the
829 * current directory.
831 vp = NULL;
832 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
833 if (error == 0 && vp->v_type == VDIR)
834 error = EPERM;
835 if (error == 0) {
836 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
837 error = VOP_OLD_REMOVE(dvp, vp, &cnp);
838 if (error == 0) {
839 cache_setunresolved(nch);
840 cache_setvp(nch, NULL);
841 cache_inval_vp(vp, CINV_DESTROY);
844 if (vp) {
845 if (dvp == vp)
846 vrele(vp);
847 else
848 vput(vp);
850 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
851 vn_unlock(dvp);
852 vrele(dvp);
853 return (error);
857 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
858 * struct vnode *dvp,
859 * struct ucred *a_cred }
862 vop_compat_nrmdir(struct vop_nrmdir_args *ap)
864 struct thread *td = curthread;
865 struct componentname cnp;
866 struct nchandle *nch;
867 struct namecache *ncp;
868 struct vnode *dvp;
869 struct vnode *vp;
870 int error;
873 * Sanity checks, get a locked directory vnode.
875 nch = ap->a_nch; /* locked namecache node */
876 ncp = nch->ncp;
877 dvp = ap->a_dvp;
879 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
880 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
881 ncp, ncp->nc_name);
882 return(EAGAIN);
886 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
887 * caches all information required to delete the entry in the
888 * directory inode. We expect a return code of 0 for the DELETE
889 * case (meaning that a vp has been found). The cnp must simulated
890 * a saved-name situation.
892 bzero(&cnp, sizeof(cnp));
893 cnp.cn_nameiop = NAMEI_DELETE;
894 cnp.cn_flags = CNP_LOCKPARENT;
895 cnp.cn_nameptr = ncp->nc_name;
896 cnp.cn_namelen = ncp->nc_nlen;
897 cnp.cn_cred = ap->a_cred;
898 cnp.cn_td = td;
901 * The vnode must be a directory and must not represent the
902 * current directory.
904 vp = NULL;
905 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
906 if (error == 0 && vp->v_type != VDIR)
907 error = ENOTDIR;
908 if (error == 0 && vp == dvp)
909 error = EINVAL;
910 if (error == 0 && (vp->v_flag & VROOT))
911 error = EBUSY;
912 if (error == 0) {
913 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
914 error = VOP_OLD_RMDIR(dvp, vp, &cnp);
917 * Note that this invalidation will cause any process
918 * currently CD'd into the directory being removed to be
919 * disconnected from the topology and not be able to ".."
920 * back out.
922 if (error == 0) {
923 cache_inval(nch, CINV_DESTROY);
924 cache_inval_vp(vp, CINV_DESTROY);
927 if (vp) {
928 if (dvp == vp)
929 vrele(vp);
930 else
931 vput(vp);
933 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
934 vn_unlock(dvp);
935 vrele(dvp);
936 return (error);
940 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
941 * struct nchandle *a_tnch,
942 * struct ucred *a_cred }
944 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
945 * the source directory and vnode be unlocked and the target directory and
946 * vnode (if it exists) be locked. All arguments will be vrele'd and
947 * the targets will also be unlocked regardless of the return code.
950 vop_compat_nrename(struct vop_nrename_args *ap)
952 struct thread *td = curthread;
953 struct componentname fcnp;
954 struct componentname tcnp;
955 struct nchandle *fnch;
956 struct nchandle *tnch;
957 struct namecache *fncp;
958 struct namecache *tncp;
959 struct vnode *fdvp, *fvp;
960 struct vnode *tdvp, *tvp;
961 int error;
964 * Sanity checks, get referenced vnodes representing the source.
966 fnch = ap->a_fnch; /* locked namecache node */
967 fncp = fnch->ncp;
968 fdvp = ap->a_fdvp;
971 * Temporarily lock the source directory and lookup in DELETE mode to
972 * check permissions. XXX delete permissions should have been
973 * checked by nlookup(), we need to add NLC_DELETE for delete
974 * checking. It is unclear whether VFS's require the directory setup
975 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
976 * since it isn't locked and since UFS always does a relookup of
977 * the source, it is believed that the only side effect that matters
978 * is the permissions check.
980 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) {
981 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
982 fncp, fncp->nc_name);
983 return(EAGAIN);
986 bzero(&fcnp, sizeof(fcnp));
987 fcnp.cn_nameiop = NAMEI_DELETE;
988 fcnp.cn_flags = CNP_LOCKPARENT;
989 fcnp.cn_nameptr = fncp->nc_name;
990 fcnp.cn_namelen = fncp->nc_nlen;
991 fcnp.cn_cred = ap->a_cred;
992 fcnp.cn_td = td;
995 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
996 * fvp.
998 fvp = NULL;
999 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
1000 if (error == 0 && (fvp->v_flag & VROOT)) {
1001 vput(fvp); /* as if vop_old_lookup had failed */
1002 error = EBUSY;
1004 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1005 fcnp.cn_flags |= CNP_PDIRUNLOCK;
1006 vn_unlock(fdvp);
1008 if (error) {
1009 vrele(fdvp);
1010 return (error);
1012 vn_unlock(fvp);
1015 * fdvp and fvp are now referenced and unlocked.
1017 * Get a locked directory vnode for the target and lookup the target
1018 * in CREATE mode so it places the required information in the
1019 * directory inode.
1021 tnch = ap->a_tnch; /* locked namecache node */
1022 tncp = tnch->ncp;
1023 tdvp = ap->a_tdvp;
1024 if (error) {
1025 vrele(fdvp);
1026 vrele(fvp);
1027 return (error);
1029 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) {
1030 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1031 tncp, tncp->nc_name);
1032 vrele(fdvp);
1033 vrele(fvp);
1034 return(EAGAIN);
1038 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1039 * caches all information required to create the entry in the
1040 * target directory inode.
1042 bzero(&tcnp, sizeof(tcnp));
1043 tcnp.cn_nameiop = NAMEI_RENAME;
1044 tcnp.cn_flags = CNP_LOCKPARENT;
1045 tcnp.cn_nameptr = tncp->nc_name;
1046 tcnp.cn_namelen = tncp->nc_nlen;
1047 tcnp.cn_cred = ap->a_cred;
1048 tcnp.cn_td = td;
1050 tvp = NULL;
1051 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
1053 if (error == EJUSTRETURN) {
1055 * Target does not exist. tvp should be NULL.
1057 KKASSERT(tvp == NULL);
1058 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1059 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1060 if (error == 0)
1061 cache_rename(fnch, tnch);
1062 } else if (error == 0) {
1064 * Target exists. VOP_OLD_RENAME should correctly delete the
1065 * target.
1067 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1068 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1069 if (error == 0)
1070 cache_rename(fnch, tnch);
1071 } else {
1072 vrele(fdvp);
1073 vrele(fvp);
1074 if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1075 vrele(tdvp);
1076 else
1077 vput(tdvp);
1079 return (error);
1082 static int
1083 vop_nolookup(struct vop_old_lookup_args *ap)
1086 *ap->a_vpp = NULL;
1087 return (ENOTDIR);
1091 * vop_nostrategy:
1093 * Strategy routine for VFS devices that have none.
1095 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1096 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1097 * Typically B_INVAL is assumed to already be clear prior to a write
1098 * and should not be cleared manually unless you just made the buffer
1099 * invalid. B_ERROR should be cleared either way.
1102 static int
1103 vop_nostrategy (struct vop_strategy_args *ap)
1105 kprintf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
1106 vprint("", ap->a_vp);
1107 ap->a_bio->bio_buf->b_flags |= B_ERROR;
1108 ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1109 biodone(ap->a_bio);
1110 return (EOPNOTSUPP);
1114 vop_stdpathconf(struct vop_pathconf_args *ap)
1117 switch (ap->a_name) {
1118 case _PC_LINK_MAX:
1119 *ap->a_retval = LINK_MAX;
1120 return (0);
1121 case _PC_MAX_CANON:
1122 *ap->a_retval = MAX_CANON;
1123 return (0);
1124 case _PC_MAX_INPUT:
1125 *ap->a_retval = MAX_INPUT;
1126 return (0);
1127 case _PC_PIPE_BUF:
1128 *ap->a_retval = PIPE_BUF;
1129 return (0);
1130 case _PC_CHOWN_RESTRICTED:
1131 *ap->a_retval = 1;
1132 return (0);
1133 case _PC_VDISABLE:
1134 *ap->a_retval = _POSIX_VDISABLE;
1135 return (0);
1136 default:
1137 return (EINVAL);
1139 /* NOTREACHED */
1143 * Standard open.
1145 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
1147 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1150 vop_stdopen(struct vop_open_args *ap)
1152 struct vnode *vp = ap->a_vp;
1153 struct file *fp;
1155 if ((fp = ap->a_fp) != NULL) {
1156 switch(vp->v_type) {
1157 case VFIFO:
1158 fp->f_type = DTYPE_FIFO;
1159 break;
1160 default:
1161 fp->f_type = DTYPE_VNODE;
1162 break;
1164 fp->f_flag = ap->a_mode & FMASK;
1165 fp->f_ops = &vnode_fileops;
1166 fp->f_data = vp;
1167 vref(vp);
1169 if (ap->a_mode & FWRITE)
1170 ++vp->v_writecount;
1171 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX);
1172 ++vp->v_opencount;
1173 return (0);
1177 * Standard close.
1179 * (struct vnode *a_vp, int a_fflag)
1181 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1184 vop_stdclose(struct vop_close_args *ap)
1186 struct vnode *vp = ap->a_vp;
1188 KASSERT(vp->v_opencount > 0,
1189 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x\n",
1190 vp, vp->v_opencount, vp->v_type, *vp->v_ops, vp->v_flag));
1191 if (ap->a_fflag & FWRITE) {
1192 KASSERT(vp->v_writecount > 0,
1193 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1194 vp, vp->v_writecount));
1195 --vp->v_writecount;
1197 --vp->v_opencount;
1198 return (0);
1202 * Return true for select/poll.
1205 vop_nopoll(struct vop_poll_args *ap)
1208 * Return true for read/write. If the user asked for something
1209 * special, return POLLNVAL, so that clients have a way of
1210 * determining reliably whether or not the extended
1211 * functionality is present without hard-coding knowledge
1212 * of specific filesystem implementations.
1214 if (ap->a_events & ~POLLSTANDARD)
1215 return (POLLNVAL);
1217 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1221 * Implement poll for local filesystems that support it.
1224 vop_stdpoll(struct vop_poll_args *ap)
1226 if (ap->a_events & ~POLLSTANDARD)
1227 return (vn_pollrecord(ap->a_vp, ap->a_events));
1228 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1232 * Implement standard getpages and putpages. All filesystems must use
1233 * the buffer cache to back regular files.
1236 vop_stdgetpages(struct vop_getpages_args *ap)
1238 struct mount *mp;
1239 int error;
1241 if ((mp = ap->a_vp->v_mount) != NULL) {
1242 error = vnode_pager_generic_getpages(
1243 ap->a_vp, ap->a_m, ap->a_count,
1244 ap->a_reqpage);
1245 } else {
1246 error = VM_PAGER_BAD;
1248 return (error);
1252 vop_stdputpages(struct vop_putpages_args *ap)
1254 struct mount *mp;
1255 int error;
1257 if ((mp = ap->a_vp->v_mount) != NULL) {
1258 error = vnode_pager_generic_putpages(
1259 ap->a_vp, ap->a_m, ap->a_count,
1260 ap->a_sync, ap->a_rtvals);
1261 } else {
1262 error = VM_PAGER_BAD;
1264 return (error);
1268 * vfs default ops
1269 * used to fill the vfs fucntion table to get reasonable default return values.
1271 int
1272 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
1274 return (0);
1277 int
1278 vfs_stdunmount(struct mount *mp, int mntflags)
1280 return (0);
1283 int
1284 vfs_stdroot(struct mount *mp, struct vnode **vpp)
1286 return (EOPNOTSUPP);
1289 int
1290 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
1292 return (EOPNOTSUPP);
1296 * If the VFS does not implement statvfs, then call statfs and convert
1297 * the values. This code was taken from libc's __cvtstatvfs() function,
1298 * contributed by Joerg Sonnenberger.
1300 int
1301 vfs_stdstatvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
1303 struct statfs *in;
1304 int error;
1306 in = &mp->mnt_stat;
1307 error = VFS_STATFS(mp, in, cred);
1308 if (error == 0) {
1309 bzero(sbp, sizeof(*sbp));
1311 sbp->f_bsize = in->f_bsize;
1312 sbp->f_frsize = in->f_bsize;
1313 sbp->f_blocks = in->f_blocks;
1314 sbp->f_bfree = in->f_bfree;
1315 sbp->f_bavail = in->f_bavail;
1316 sbp->f_files = in->f_files;
1317 sbp->f_ffree = in->f_ffree;
1320 * XXX
1321 * This field counts the number of available inodes to non-root
1322 * users, but this information is not available via statfs.
1323 * Just ignore this issue by returning the total number
1324 * instead.
1326 sbp->f_favail = in->f_ffree;
1329 * XXX
1330 * This field has a different meaning for statfs and statvfs.
1331 * For the former it is the cookie exported for NFS and not
1332 * intended for normal userland use.
1334 sbp->f_fsid = 0;
1336 sbp->f_flag = 0;
1337 if (in->f_flags & MNT_RDONLY)
1338 sbp->f_flag |= ST_RDONLY;
1339 if (in->f_flags & MNT_NOSUID)
1340 sbp->f_flag |= ST_NOSUID;
1341 sbp->f_namemax = 0;
1342 sbp->f_owner = in->f_owner;
1344 * XXX
1345 * statfs contains the type as string, statvfs expects it as
1346 * enumeration.
1348 sbp->f_type = 0;
1350 sbp->f_syncreads = in->f_syncreads;
1351 sbp->f_syncwrites = in->f_syncwrites;
1352 sbp->f_asyncreads = in->f_asyncreads;
1353 sbp->f_asyncwrites = in->f_asyncwrites;
1355 return (error);
1359 vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
1361 return (EOPNOTSUPP);
1364 int
1365 vfs_stdstart(struct mount *mp, int flags)
1367 return (0);
1370 int
1371 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
1372 caddr_t arg, struct ucred *cred)
1374 return (EOPNOTSUPP);
1377 int
1378 vfs_stdsync(struct mount *mp, int waitfor)
1380 return (0);
1384 vfs_stdnosync(struct mount *mp, int waitfor)
1386 return (EOPNOTSUPP);
1389 int
1390 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp)
1392 return (EOPNOTSUPP);
1395 int
1396 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
1398 return (EOPNOTSUPP);
1401 int
1402 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1403 struct ucred **credanonp)
1405 return (EOPNOTSUPP);
1409 vfs_stdinit(struct vfsconf *vfsp)
1411 return (0);
1415 vfs_stduninit(struct vfsconf *vfsp)
1417 return(0);
1421 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname,
1422 caddr_t arg, struct ucred *cred)
1424 return(EOPNOTSUPP);
1427 /* end of vfs default ops */