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
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
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 $
43 #include <sys/param.h>
44 #include <sys/systm.h>
47 #include <sys/fcntl.h>
49 #include <sys/kernel.h>
51 #include <sys/malloc.h>
52 #include <sys/mount.h>
53 #include <sys/unistd.h>
54 #include <sys/vnode.h>
55 #include <sys/namei.h>
56 #include <sys/nlookup.h>
57 #include <sys/mountctl.h>
58 #include <sys/vfs_quota.h>
60 #include <machine/limits.h>
63 #include <vm/vm_object.h>
64 #include <vm/vm_page.h>
65 #include <vm/vm_pager.h>
66 #include <vm/vnode_pager.h>
68 static int vop_nolookup (struct vop_old_lookup_args *);
69 static int vop_nostrategy (struct vop_strategy_args *);
72 * This vnode table stores what we want to do if the filesystem doesn't
73 * implement a particular VOP.
75 * If there is no specific entry here, we will return EOPNOTSUPP.
77 struct vop_ops default_vnode_vops = {
78 .vop_default = vop_eopnotsupp,
79 .vop_advlock = (void *)vop_einval,
80 .vop_fsync = (void *)vop_null,
81 .vop_ioctl = (void *)vop_enotty,
82 .vop_mmap = (void *)vop_einval,
83 .vop_old_lookup = vop_nolookup,
84 .vop_open = vop_stdopen,
85 .vop_close = vop_stdclose,
86 .vop_pathconf = vop_stdpathconf,
87 .vop_readlink = (void *)vop_einval,
88 .vop_reallocblks = (void *)vop_eopnotsupp,
89 .vop_strategy = vop_nostrategy,
90 .vop_getacl = (void *)vop_eopnotsupp,
91 .vop_setacl = (void *)vop_eopnotsupp,
92 .vop_aclcheck = (void *)vop_eopnotsupp,
93 .vop_getextattr = (void *)vop_eopnotsupp,
94 .vop_setextattr = (void *)vop_eopnotsupp,
95 .vop_markatime = vop_stdmarkatime,
96 .vop_nresolve = vop_compat_nresolve,
97 .vop_nlookupdotdot = vop_compat_nlookupdotdot,
98 .vop_ncreate = vop_compat_ncreate,
99 .vop_nmkdir = vop_compat_nmkdir,
100 .vop_nmknod = vop_compat_nmknod,
101 .vop_nlink = vop_compat_nlink,
102 .vop_nsymlink = vop_compat_nsymlink,
103 .vop_nwhiteout = vop_compat_nwhiteout,
104 .vop_nremove = vop_compat_nremove,
105 .vop_nrmdir = vop_compat_nrmdir,
106 .vop_nrename = vop_compat_nrename,
107 .vop_mountctl = vop_stdmountctl
110 VNODEOP_SET(default_vnode_vops);
113 vop_eopnotsupp(struct vop_generic_args *ap)
119 vop_ebadf(struct vop_generic_args *ap)
125 vop_enotty(struct vop_generic_args *ap)
131 vop_einval(struct vop_generic_args *ap)
137 vop_stdmarkatime(struct vop_markatime_args *ap)
143 vop_null(struct vop_generic_args *ap)
149 vop_defaultop(struct vop_generic_args *ap)
151 return (VOCALL(&default_vnode_vops, ap));
155 vop_panic(struct vop_generic_args *ap)
157 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name);
161 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
162 * XXX STOPGAP FUNCTION
164 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
165 * WILL BE REMOVED. This procedure exists for all VFSs which have not
166 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
167 * vop_old_lookup() and does appropriate translations.
169 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
170 * VFSs will support this VOP and this routine can be removed, since
171 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
174 * A locked ncp is passed in to be resolved. The NCP is resolved by
175 * figuring out the vnode (if any) and calling cache_setvp() to attach the
176 * vnode to the entry. If the entry represents a non-existant node then
177 * cache_setvp() is called with a NULL vnode to resolve the entry into a
178 * negative cache entry. No vnode locks are retained and the
179 * ncp is left locked on return.
181 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
183 * There is a potential directory and vnode interlock. The lock order
184 * requirement is: namecache, governing directory, resolved vnode.
187 vop_compat_nresolve(struct vop_nresolve_args *ap)
192 struct nchandle *nch;
193 struct namecache *ncp;
194 struct componentname cnp;
196 nch = ap->a_nch; /* locked namecache node */
201 * UFS currently stores all sorts of side effects, including a loop
202 * variable, in the directory inode. That needs to be fixed and the
203 * other VFS's audited before we can switch to LK_SHARED.
205 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
206 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
211 bzero(&cnp, sizeof(cnp));
212 cnp.cn_nameiop = NAMEI_LOOKUP;
214 cnp.cn_nameptr = ncp->nc_name;
215 cnp.cn_namelen = ncp->nc_nlen;
216 cnp.cn_cred = ap->a_cred;
217 cnp.cn_td = curthread; /* XXX */
220 * vop_old_lookup() always returns vp locked. dvp may or may not be
221 * left locked depending on CNP_PDIRUNLOCK.
223 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
226 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
228 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
229 /* was resolved by another process while we were unlocked */
232 } else if (error == 0) {
233 KKASSERT(vp != NULL);
234 cache_setvp(nch, vp);
236 } else if (error == ENOENT) {
237 KKASSERT(vp == NULL);
238 if (cnp.cn_flags & CNP_ISWHITEOUT)
239 ncp->nc_flag |= NCF_WHITEOUT;
240 cache_setvp(nch, NULL);
247 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
248 * struct vnode **a_vpp,
249 * struct ucred *a_cred }
251 * Lookup the vnode representing the parent directory of the specified
252 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
253 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
255 * This function is designed to aid NFS server-side operations and is
256 * used by cache_fromdvp() to create a consistent, connected namecache
259 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
260 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
261 * permits VFSs will implement the remaining *_n*() calls and finally get
262 * rid of their *_lookup() call.
265 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
267 struct componentname cnp;
271 * UFS currently stores all sorts of side effects, including a loop
272 * variable, in the directory inode. That needs to be fixed and the
273 * other VFS's audited before we can switch to LK_SHARED.
276 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE)) != 0)
278 if (ap->a_dvp->v_type != VDIR) {
283 bzero(&cnp, sizeof(cnp));
284 cnp.cn_nameiop = NAMEI_LOOKUP;
285 cnp.cn_flags = CNP_ISDOTDOT;
286 cnp.cn_nameptr = "..";
288 cnp.cn_cred = ap->a_cred;
289 cnp.cn_td = curthread; /* XXX */
292 * vop_old_lookup() always returns vp locked. dvp may or may not be
293 * left locked depending on CNP_PDIRUNLOCK.
295 * (*vpp) will be returned locked if no error occured, which is the
298 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
299 if (cnp.cn_flags & CNP_PDIRUNLOCK)
307 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
308 * struct vnode *a_dvp,
309 * struct vnode **a_vpp,
310 * struct ucred *a_cred,
311 * struct vattr *a_vap }
313 * Create a file as specified by a_vap. Compatibility requires us to issue
314 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
315 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
318 vop_compat_ncreate(struct vop_ncreate_args *ap)
320 struct thread *td = curthread;
321 struct componentname cnp;
322 struct nchandle *nch;
323 struct namecache *ncp;
328 * Sanity checks, get a locked directory vnode.
330 nch = ap->a_nch; /* locked namecache node */
334 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
335 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
341 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
342 * caches all information required to create the entry in the
343 * directory inode. We expect a return code of EJUSTRETURN for
344 * the CREATE case. The cnp must simulated a saved-name situation.
346 bzero(&cnp, sizeof(cnp));
347 cnp.cn_nameiop = NAMEI_CREATE;
348 cnp.cn_flags = CNP_LOCKPARENT;
349 cnp.cn_nameptr = ncp->nc_name;
350 cnp.cn_namelen = ncp->nc_nlen;
351 cnp.cn_cred = ap->a_cred;
355 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
358 * EJUSTRETURN should be returned for this case, which means that
359 * the VFS has setup the directory inode for the create. The dvp we
360 * passed in is expected to remain in a locked state.
362 * If the VOP_OLD_CREATE is successful we are responsible for updating
363 * the cache state of the locked ncp that was passed to us.
365 if (error == EJUSTRETURN) {
366 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
367 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
369 cache_setunresolved(nch);
370 cache_setvp(nch, *ap->a_vpp);
378 KKASSERT(*ap->a_vpp == NULL);
380 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
387 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
388 * struct vnode *a_dvp,
389 * struct vnode **a_vpp,
390 * struct ucred *a_cred,
391 * struct vattr *a_vap }
393 * Create a directory as specified by a_vap. Compatibility requires us to
394 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
395 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
398 vop_compat_nmkdir(struct vop_nmkdir_args *ap)
400 struct thread *td = curthread;
401 struct componentname cnp;
402 struct nchandle *nch;
403 struct namecache *ncp;
408 * Sanity checks, get a locked directory vnode.
410 nch = ap->a_nch; /* locked namecache node */
413 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
414 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
420 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
421 * caches all information required to create the entry in the
422 * directory inode. We expect a return code of EJUSTRETURN for
423 * the CREATE case. The cnp must simulated a saved-name situation.
425 bzero(&cnp, sizeof(cnp));
426 cnp.cn_nameiop = NAMEI_CREATE;
427 cnp.cn_flags = CNP_LOCKPARENT;
428 cnp.cn_nameptr = ncp->nc_name;
429 cnp.cn_namelen = ncp->nc_nlen;
430 cnp.cn_cred = ap->a_cred;
434 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
437 * EJUSTRETURN should be returned for this case, which means that
438 * the VFS has setup the directory inode for the create. The dvp we
439 * passed in is expected to remain in a locked state.
441 * If the VOP_OLD_MKDIR is successful we are responsible for updating
442 * the cache state of the locked ncp that was passed to us.
444 if (error == EJUSTRETURN) {
445 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
446 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
448 cache_setunresolved(nch);
449 cache_setvp(nch, *ap->a_vpp);
457 KKASSERT(*ap->a_vpp == NULL);
459 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
466 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
467 * struct vnode *a_dvp,
468 * struct vnode **a_vpp,
469 * struct ucred *a_cred,
470 * struct vattr *a_vap }
472 * Create a device or fifo node as specified by a_vap. Compatibility requires
473 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
474 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
477 vop_compat_nmknod(struct vop_nmknod_args *ap)
479 struct thread *td = curthread;
480 struct componentname cnp;
481 struct nchandle *nch;
482 struct namecache *ncp;
487 * Sanity checks, get a locked directory vnode.
489 nch = ap->a_nch; /* locked namecache node */
493 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
494 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
500 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
501 * caches all information required to create the entry in the
502 * directory inode. We expect a return code of EJUSTRETURN for
503 * the CREATE case. The cnp must simulated a saved-name situation.
505 bzero(&cnp, sizeof(cnp));
506 cnp.cn_nameiop = NAMEI_CREATE;
507 cnp.cn_flags = CNP_LOCKPARENT;
508 cnp.cn_nameptr = ncp->nc_name;
509 cnp.cn_namelen = ncp->nc_nlen;
510 cnp.cn_cred = ap->a_cred;
514 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
517 * EJUSTRETURN should be returned for this case, which means that
518 * the VFS has setup the directory inode for the create. The dvp we
519 * passed in is expected to remain in a locked state.
521 * If the VOP_OLD_MKNOD is successful we are responsible for updating
522 * the cache state of the locked ncp that was passed to us.
524 if (error == EJUSTRETURN) {
525 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
526 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
528 cache_setunresolved(nch);
529 cache_setvp(nch, *ap->a_vpp);
537 KKASSERT(*ap->a_vpp == NULL);
539 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
546 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
547 * struct vnode *a_dvp,
548 * struct vnode *a_vp,
549 * struct ucred *a_cred }
551 * The passed vp is locked and represents the source. The passed ncp is
552 * locked and represents the target to create.
555 vop_compat_nlink(struct vop_nlink_args *ap)
557 struct thread *td = curthread;
558 struct componentname cnp;
559 struct nchandle *nch;
560 struct namecache *ncp;
566 * Sanity checks, get a locked directory vnode.
568 nch = ap->a_nch; /* locked namecache node */
572 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
573 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
579 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
580 * caches all information required to create the entry in the
581 * directory inode. We expect a return code of EJUSTRETURN for
582 * the CREATE case. The cnp must simulated a saved-name situation.
584 * It should not be possible for there to be a vnode collision
585 * between the source vp and target (name lookup). However NFS
586 * clients racing each other can cause NFS to alias the same vnode
587 * across several names without the rest of the system knowing it.
588 * Use CNP_NOTVP to avoid a panic in this situation.
590 bzero(&cnp, sizeof(cnp));
591 cnp.cn_nameiop = NAMEI_CREATE;
592 cnp.cn_flags = CNP_LOCKPARENT | CNP_NOTVP;
593 cnp.cn_nameptr = ncp->nc_name;
594 cnp.cn_namelen = ncp->nc_nlen;
595 cnp.cn_cred = ap->a_cred;
597 cnp.cn_notvp = ap->a_vp;
600 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
603 * EJUSTRETURN should be returned for this case, which means that
604 * the VFS has setup the directory inode for the create. The dvp we
605 * passed in is expected to remain in a locked state.
607 * If the VOP_OLD_LINK is successful we are responsible for updating
608 * the cache state of the locked ncp that was passed to us.
610 if (error == EJUSTRETURN) {
611 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
612 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
614 cache_setunresolved(nch);
615 cache_setvp(nch, ap->a_vp);
623 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
630 vop_compat_nsymlink(struct vop_nsymlink_args *ap)
632 struct thread *td = curthread;
633 struct componentname cnp;
634 struct nchandle *nch;
635 struct namecache *ncp;
641 * Sanity checks, get a locked directory vnode.
644 nch = ap->a_nch; /* locked namecache node */
648 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
649 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
655 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
656 * caches all information required to create the entry in the
657 * directory inode. We expect a return code of EJUSTRETURN for
658 * the CREATE case. The cnp must simulated a saved-name situation.
660 bzero(&cnp, sizeof(cnp));
661 cnp.cn_nameiop = NAMEI_CREATE;
662 cnp.cn_flags = CNP_LOCKPARENT;
663 cnp.cn_nameptr = ncp->nc_name;
664 cnp.cn_namelen = ncp->nc_nlen;
665 cnp.cn_cred = ap->a_cred;
669 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
672 * EJUSTRETURN should be returned for this case, which means that
673 * the VFS has setup the directory inode for the create. The dvp we
674 * passed in is expected to remain in a locked state.
676 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
677 * the cache state of the locked ncp that was passed to us.
679 if (error == EJUSTRETURN) {
680 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
681 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
683 cache_setunresolved(nch);
684 cache_setvp(nch, vp);
693 KKASSERT(vp == NULL);
695 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
702 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
703 * struct vnode *a_dvp,
704 * struct ucred *a_cred,
707 * Issie a whiteout operation (create, lookup, or delete). Compatibility
708 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
709 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
710 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
711 * no lookup is necessary.
714 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
716 struct thread *td = curthread;
717 struct componentname cnp;
718 struct nchandle *nch;
719 struct namecache *ncp;
725 * Sanity checks, get a locked directory vnode.
727 nch = ap->a_nch; /* locked namecache node */
731 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
732 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
738 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
739 * caches all information required to create the entry in the
740 * directory inode. We expect a return code of EJUSTRETURN for
741 * the CREATE case. The cnp must simulated a saved-name situation.
743 bzero(&cnp, sizeof(cnp));
744 cnp.cn_nameiop = ap->a_flags;
745 cnp.cn_flags = CNP_LOCKPARENT;
746 cnp.cn_nameptr = ncp->nc_name;
747 cnp.cn_namelen = ncp->nc_nlen;
748 cnp.cn_cred = ap->a_cred;
754 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
755 * The VFS has setup the directory inode for the create. The dvp we
756 * passed in is expected to remain in a locked state.
758 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
759 * the cache state of the locked ncp that was passed to us.
761 switch(ap->a_flags) {
763 cnp.cn_flags |= CNP_DOWHITEOUT;
766 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
767 if (error == EJUSTRETURN) {
768 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
769 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
771 cache_setunresolved(nch);
778 KKASSERT(vp == NULL);
782 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
788 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
796 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
797 * struct vnode *a_dvp,
798 * struct ucred *a_cred }
801 vop_compat_nremove(struct vop_nremove_args *ap)
803 struct thread *td = curthread;
804 struct componentname cnp;
805 struct nchandle *nch;
806 struct namecache *ncp;
812 * Sanity checks, get a locked directory vnode.
814 nch = ap->a_nch; /* locked namecache node */
818 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
819 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
825 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
826 * caches all information required to delete the entry in the
827 * directory inode. We expect a return code of 0 for the DELETE
828 * case (meaning that a vp has been found). The cnp must simulated
829 * a saved-name situation.
831 bzero(&cnp, sizeof(cnp));
832 cnp.cn_nameiop = NAMEI_DELETE;
833 cnp.cn_flags = CNP_LOCKPARENT;
834 cnp.cn_nameptr = ncp->nc_name;
835 cnp.cn_namelen = ncp->nc_nlen;
836 cnp.cn_cred = ap->a_cred;
840 * The vnode must be a directory and must not represent the
844 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
845 if (error == 0 && vp->v_type == VDIR)
848 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
849 error = VOP_OLD_REMOVE(dvp, vp, &cnp);
859 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
866 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
868 * struct ucred *a_cred }
871 vop_compat_nrmdir(struct vop_nrmdir_args *ap)
873 struct thread *td = curthread;
874 struct componentname cnp;
875 struct nchandle *nch;
876 struct namecache *ncp;
882 * Sanity checks, get a locked directory vnode.
884 nch = ap->a_nch; /* locked namecache node */
888 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
889 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
895 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
896 * caches all information required to delete the entry in the
897 * directory inode. We expect a return code of 0 for the DELETE
898 * case (meaning that a vp has been found). The cnp must simulated
899 * a saved-name situation.
901 bzero(&cnp, sizeof(cnp));
902 cnp.cn_nameiop = NAMEI_DELETE;
903 cnp.cn_flags = CNP_LOCKPARENT;
904 cnp.cn_nameptr = ncp->nc_name;
905 cnp.cn_namelen = ncp->nc_nlen;
906 cnp.cn_cred = ap->a_cred;
910 * The vnode must be a directory and must not represent the
914 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
915 if (error == 0 && vp->v_type != VDIR)
917 if (error == 0 && vp == dvp)
919 if (error == 0 && (vp->v_flag & VROOT))
922 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
923 error = VOP_OLD_RMDIR(dvp, vp, &cnp);
926 * Note that this invalidation will cause any process
927 * currently CD'd into the directory being removed to be
928 * disconnected from the topology and not be able to ".."
932 cache_inval(nch, CINV_DESTROY);
933 cache_inval_vp(vp, CINV_DESTROY);
942 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
949 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
950 * struct nchandle *a_tnch,
951 * struct ucred *a_cred }
953 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
954 * the source directory and vnode be unlocked and the target directory and
955 * vnode (if it exists) be locked. All arguments will be vrele'd and
956 * the targets will also be unlocked regardless of the return code.
959 vop_compat_nrename(struct vop_nrename_args *ap)
961 struct thread *td = curthread;
962 struct componentname fcnp;
963 struct componentname tcnp;
964 struct nchandle *fnch;
965 struct nchandle *tnch;
966 struct namecache *fncp;
967 struct namecache *tncp;
968 struct vnode *fdvp, *fvp;
969 struct vnode *tdvp, *tvp;
973 * Sanity checks, get referenced vnodes representing the source.
975 fnch = ap->a_fnch; /* locked namecache node */
980 * Temporarily lock the source directory and lookup in DELETE mode to
981 * check permissions. XXX delete permissions should have been
982 * checked by nlookup(), we need to add NLC_DELETE for delete
983 * checking. It is unclear whether VFS's require the directory setup
984 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
985 * since it isn't locked and since UFS always does a relookup of
986 * the source, it is believed that the only side effect that matters
987 * is the permissions check.
989 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) {
990 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
991 fncp, fncp->nc_name);
995 bzero(&fcnp, sizeof(fcnp));
996 fcnp.cn_nameiop = NAMEI_DELETE;
997 fcnp.cn_flags = CNP_LOCKPARENT;
998 fcnp.cn_nameptr = fncp->nc_name;
999 fcnp.cn_namelen = fncp->nc_nlen;
1000 fcnp.cn_cred = ap->a_cred;
1004 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1008 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
1009 if (error == 0 && (fvp->v_flag & VROOT)) {
1010 vput(fvp); /* as if vop_old_lookup had failed */
1013 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1014 fcnp.cn_flags |= CNP_PDIRUNLOCK;
1024 * fdvp and fvp are now referenced and unlocked.
1026 * Get a locked directory vnode for the target and lookup the target
1027 * in CREATE mode so it places the required information in the
1030 tnch = ap->a_tnch; /* locked namecache node */
1038 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) {
1039 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1040 tncp, tncp->nc_name);
1047 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1048 * caches all information required to create the entry in the
1049 * target directory inode.
1051 bzero(&tcnp, sizeof(tcnp));
1052 tcnp.cn_nameiop = NAMEI_RENAME;
1053 tcnp.cn_flags = CNP_LOCKPARENT;
1054 tcnp.cn_nameptr = tncp->nc_name;
1055 tcnp.cn_namelen = tncp->nc_nlen;
1056 tcnp.cn_cred = ap->a_cred;
1060 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
1062 if (error == EJUSTRETURN) {
1064 * Target does not exist. tvp should be NULL.
1066 KKASSERT(tvp == NULL);
1067 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1068 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1070 cache_rename(fnch, tnch);
1071 } else if (error == 0) {
1073 * Target exists. VOP_OLD_RENAME should correctly delete the
1076 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1077 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1079 cache_rename(fnch, tnch);
1083 if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1092 vop_nolookup(struct vop_old_lookup_args *ap)
1102 * Strategy routine for VFS devices that have none.
1104 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1105 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1106 * Typically B_INVAL is assumed to already be clear prior to a write
1107 * and should not be cleared manually unless you just made the buffer
1108 * invalid. B_ERROR should be cleared either way.
1112 vop_nostrategy (struct vop_strategy_args *ap)
1114 kprintf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
1115 vprint("", ap->a_vp);
1116 ap->a_bio->bio_buf->b_flags |= B_ERROR;
1117 ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1119 return (EOPNOTSUPP);
1123 vop_stdpathconf(struct vop_pathconf_args *ap)
1127 switch (ap->a_name) {
1129 *ap->a_retval = LINK_MAX;
1132 *ap->a_retval = NAME_MAX;
1135 *ap->a_retval = PATH_MAX;
1138 *ap->a_retval = MAX_CANON;
1141 *ap->a_retval = MAX_INPUT;
1144 *ap->a_retval = PIPE_BUF;
1146 case _PC_CHOWN_RESTRICTED:
1153 *ap->a_retval = _POSIX_VDISABLE;
1165 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
1167 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1170 vop_stdopen(struct vop_open_args *ap)
1172 struct vnode *vp = ap->a_vp;
1175 if ((fp = ap->a_fp) != NULL) {
1176 switch(vp->v_type) {
1178 fp->f_type = DTYPE_FIFO;
1181 fp->f_type = DTYPE_VNODE;
1184 fp->f_flag = ap->a_mode & FMASK;
1185 fp->f_ops = &vnode_fileops;
1189 if (ap->a_mode & FWRITE)
1191 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX);
1199 * (struct vnode *a_vp, int a_fflag)
1201 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1204 vop_stdclose(struct vop_close_args *ap)
1206 struct vnode *vp = ap->a_vp;
1208 KASSERT(vp->v_opencount > 0,
1209 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x",
1210 vp, vp->v_opencount, vp->v_type, *vp->v_ops, vp->v_flag));
1211 if (ap->a_fflag & FWRITE) {
1212 KASSERT(vp->v_writecount > 0,
1213 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d",
1214 vp, vp->v_writecount));
1222 * Implement standard getpages and putpages. All filesystems must use
1223 * the buffer cache to back regular files.
1226 vop_stdgetpages(struct vop_getpages_args *ap)
1231 if ((mp = ap->a_vp->v_mount) != NULL) {
1232 error = vnode_pager_generic_getpages(
1233 ap->a_vp, ap->a_m, ap->a_count,
1234 ap->a_reqpage, ap->a_seqaccess);
1236 error = VM_PAGER_BAD;
1242 vop_stdputpages(struct vop_putpages_args *ap)
1247 if ((mp = ap->a_vp->v_mount) != NULL) {
1248 error = vnode_pager_generic_putpages(
1249 ap->a_vp, ap->a_m, ap->a_count,
1250 ap->a_sync, ap->a_rtvals);
1252 error = VM_PAGER_BAD;
1258 vop_stdnoread(struct vop_read_args *ap)
1264 vop_stdnowrite(struct vop_write_args *ap)
1271 * used to fill the vfs fucntion table to get reasonable default return values.
1274 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
1280 vfs_stdunmount(struct mount *mp, int mntflags)
1286 vop_stdmountctl(struct vop_mountctl_args *ap)
1292 mp = ap->a_head.a_ops->head.vv_mount;
1295 case MOUNTCTL_MOUNTFLAGS:
1297 * Get a string buffer with all the mount flags
1298 * names comman separated.
1299 * mount(2) will use this information.
1301 *ap->a_res = vfs_flagstostr(mp->mnt_flag & MNT_VISFLAGMASK, NULL,
1302 ap->a_buf, ap->a_buflen, &error);
1304 case MOUNTCTL_INSTALL_VFS_JOURNAL:
1305 case MOUNTCTL_RESTART_VFS_JOURNAL:
1306 case MOUNTCTL_REMOVE_VFS_JOURNAL:
1307 case MOUNTCTL_RESYNC_VFS_JOURNAL:
1308 case MOUNTCTL_STATUS_VFS_JOURNAL:
1309 error = journal_mountctl(ap);
1319 vfs_stdroot(struct mount *mp, struct vnode **vpp)
1321 return (EOPNOTSUPP);
1325 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
1327 return (EOPNOTSUPP);
1331 * If the VFS does not implement statvfs, then call statfs and convert
1332 * the values. This code was taken from libc's __cvtstatvfs() function,
1333 * contributed by Joerg Sonnenberger.
1336 vfs_stdstatvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
1342 error = VFS_STATFS(mp, in, cred);
1344 bzero(sbp, sizeof(*sbp));
1346 sbp->f_bsize = in->f_bsize;
1347 sbp->f_frsize = in->f_bsize;
1348 sbp->f_blocks = in->f_blocks;
1349 sbp->f_bfree = in->f_bfree;
1350 sbp->f_bavail = in->f_bavail;
1351 sbp->f_files = in->f_files;
1352 sbp->f_ffree = in->f_ffree;
1356 * This field counts the number of available inodes to non-root
1357 * users, but this information is not available via statfs.
1358 * Just ignore this issue by returning the total number
1361 sbp->f_favail = in->f_ffree;
1365 * This field has a different meaning for statfs and statvfs.
1366 * For the former it is the cookie exported for NFS and not
1367 * intended for normal userland use.
1372 if (in->f_flags & MNT_RDONLY)
1373 sbp->f_flag |= ST_RDONLY;
1374 if (in->f_flags & MNT_NOSUID)
1375 sbp->f_flag |= ST_NOSUID;
1377 sbp->f_owner = in->f_owner;
1380 * statfs contains the type as string, statvfs expects it as
1385 sbp->f_syncreads = in->f_syncreads;
1386 sbp->f_syncwrites = in->f_syncwrites;
1387 sbp->f_asyncreads = in->f_asyncreads;
1388 sbp->f_asyncwrites = in->f_asyncwrites;
1394 vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
1396 return (EOPNOTSUPP);
1400 vfs_stdstart(struct mount *mp, int flags)
1406 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
1407 caddr_t arg, struct ucred *cred)
1409 return (EOPNOTSUPP);
1413 vfs_stdsync(struct mount *mp, int waitfor)
1419 vfs_stdnosync(struct mount *mp, int waitfor)
1421 return (EOPNOTSUPP);
1425 vfs_stdvget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
1427 return (EOPNOTSUPP);
1431 vfs_stdfhtovp(struct mount *mp, struct vnode *rootvp,
1432 struct fid *fhp, struct vnode **vpp)
1434 return (EOPNOTSUPP);
1438 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1439 struct ucred **credanonp)
1441 return (EOPNOTSUPP);
1445 vfs_stdinit(struct vfsconf *vfsp)
1451 vfs_stduninit(struct vfsconf *vfsp)
1457 vfs_stdextattrctl(struct mount *mp, int cmd, struct vnode *vp,
1458 int attrnamespace, const char *attrname,
1464 #define ACCOUNTING_NB_FSTYPES 7
1466 static const char *accounting_fstypes[ACCOUNTING_NB_FSTYPES] = {
1467 "ext2fs", "hammer", "mfs", "ntfs", "null", "tmpfs", "ufs" };
1470 vfs_stdac_init(struct mount *mp)
1472 const char* fs_type;
1473 int i, fstype_ok = 0;
1475 /* is mounted fs type one we want to do some accounting for ? */
1476 for (i=0; i<ACCOUNTING_NB_FSTYPES; i++) {
1477 fs_type = accounting_fstypes[i];
1478 if (strncmp(mp->mnt_stat.f_fstypename, fs_type,
1479 sizeof(mp->mnt_stat)) == 0) {
1492 vfs_stdac_done(struct mount *mp)
1498 vfs_stdncpgen_set(struct mount *mp, struct namecache *ncp)
1503 vfs_stdncpgen_test(struct mount *mp, struct namecache *ncp)
1507 /* end of vfs default ops */