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 * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $
40 * $DragonFly: src/sys/kern/vfs_default.c,v 1.42 2006/07/19 06:08:06 dillon 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>
58 #include <sys/mountctl.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_islocked = vop_stdislocked,
83 .vop_lock = vop_stdlock,
84 .vop_mmap = (void *)vop_einval,
85 .vop_old_lookup = vop_nolookup,
86 .vop_open = vop_stdopen,
87 .vop_close = vop_stdclose,
88 .vop_pathconf = (void *)vop_einval,
89 .vop_poll = vop_nopoll,
90 .vop_readlink = (void *)vop_einval,
91 .vop_reallocblks = (void *)vop_eopnotsupp,
92 .vop_revoke = vop_stdrevoke,
93 .vop_strategy = vop_nostrategy,
94 .vop_unlock = vop_stdunlock,
95 .vop_getacl = (void *)vop_eopnotsupp,
96 .vop_setacl = (void *)vop_eopnotsupp,
97 .vop_aclcheck = (void *)vop_eopnotsupp,
98 .vop_getextattr = (void *)vop_eopnotsupp,
99 .vop_setextattr = (void *)vop_eopnotsupp,
100 .vop_nresolve = vop_compat_nresolve,
101 .vop_nlookupdotdot = vop_compat_nlookupdotdot,
102 .vop_ncreate = vop_compat_ncreate,
103 .vop_nmkdir = vop_compat_nmkdir,
104 .vop_nmknod = vop_compat_nmknod,
105 .vop_nlink = vop_compat_nlink,
106 .vop_nsymlink = vop_compat_nsymlink,
107 .vop_nwhiteout = vop_compat_nwhiteout,
108 .vop_nremove = vop_compat_nremove,
109 .vop_nrmdir = vop_compat_nrmdir,
110 .vop_nrename = vop_compat_nrename,
111 .vop_mountctl = journal_mountctl
114 VNODEOP_SET(default_vnode_vops);
117 vop_eopnotsupp(struct vop_generic_args *ap)
123 vop_ebadf(struct vop_generic_args *ap)
129 vop_enotty(struct vop_generic_args *ap)
135 vop_einval(struct vop_generic_args *ap)
141 vop_null(struct vop_generic_args *ap)
147 vop_defaultop(struct vop_generic_args *ap)
149 return (VOCALL(&default_vnode_vops, ap));
153 vop_panic(struct vop_generic_args *ap)
155 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name);
159 * vop_compat_resolve { struct namecache *a_ncp } XXX STOPGAP FUNCTION
161 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
162 * WILL BE REMOVED. This procedure exists for all VFSs which have not
163 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
164 * vop_old_lookup() and does appropriate translations.
166 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
167 * VFSs will support this VOP and this routine can be removed, since
168 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
171 * A locked ncp is passed in to be resolved. The NCP is resolved by
172 * figuring out the vnode (if any) and calling cache_setvp() to attach the
173 * vnode to the entry. If the entry represents a non-existant node then
174 * cache_setvp() is called with a NULL vnode to resolve the entry into a
175 * negative cache entry. No vnode locks are retained and the
176 * ncp is left locked on return.
178 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
180 * There is a potential directory and vnode interlock. The lock order
181 * requirement is: namecache, governing directory, resolved vnode.
184 vop_compat_nresolve(struct vop_nresolve_args *ap)
189 struct namecache *ncp;
190 struct componentname cnp;
192 ncp = ap->a_ncp; /* locked namecache node */
193 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
195 if (ncp->nc_parent == NULL)
197 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
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 printf("[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(ncp, 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(ncp, 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 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
297 VOP_UNLOCK(*ap->a_vpp, 0);
298 if (cnp.cn_flags & CNP_PDIRUNLOCK)
306 * vop_compat_ncreate { struct namecache *a_ncp, XXX STOPGAP FUNCTION
307 * struct vnode *a_vpp,
308 * struct ucred *a_cred,
309 * struct vattr *a_vap }
311 * Create a file as specified by a_vap. Compatibility requires us to issue
312 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
313 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
316 vop_compat_ncreate(struct vop_ncreate_args *ap)
318 struct thread *td = curthread;
319 struct componentname cnp;
320 struct namecache *ncp;
325 * Sanity checks, get a locked directory vnode.
327 ncp = ap->a_ncp; /* locked namecache node */
328 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
330 if (ncp->nc_parent == NULL)
332 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
335 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
336 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
342 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
343 * caches all information required to create the entry in the
344 * directory inode. We expect a return code of EJUSTRETURN for
345 * the CREATE case. The cnp must simulated a saved-name situation.
347 bzero(&cnp, sizeof(cnp));
348 cnp.cn_nameiop = NAMEI_CREATE;
349 cnp.cn_flags = CNP_LOCKPARENT;
350 cnp.cn_nameptr = ncp->nc_name;
351 cnp.cn_namelen = ncp->nc_nlen;
352 cnp.cn_cred = ap->a_cred;
356 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
359 * EJUSTRETURN should be returned for this case, which means that
360 * the VFS has setup the directory inode for the create. The dvp we
361 * passed in is expected to remain in a locked state.
363 * If the VOP_OLD_CREATE is successful we are responsible for updating
364 * the cache state of the locked ncp that was passed to us.
366 if (error == EJUSTRETURN) {
367 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
368 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
370 cache_setunresolved(ncp);
371 cache_setvp(ncp, *ap->a_vpp);
379 KKASSERT(*ap->a_vpp == NULL);
381 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
388 * vop_compat_nmkdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION
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 namecache *ncp;
407 * Sanity checks, get a locked directory vnode.
409 ncp = ap->a_ncp; /* locked namecache node */
410 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
412 if (ncp->nc_parent == NULL)
414 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
417 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
418 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
424 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
425 * caches all information required to create the entry in the
426 * directory inode. We expect a return code of EJUSTRETURN for
427 * the CREATE case. The cnp must simulated a saved-name situation.
429 bzero(&cnp, sizeof(cnp));
430 cnp.cn_nameiop = NAMEI_CREATE;
431 cnp.cn_flags = CNP_LOCKPARENT;
432 cnp.cn_nameptr = ncp->nc_name;
433 cnp.cn_namelen = ncp->nc_nlen;
434 cnp.cn_cred = ap->a_cred;
438 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
441 * EJUSTRETURN should be returned for this case, which means that
442 * the VFS has setup the directory inode for the create. The dvp we
443 * passed in is expected to remain in a locked state.
445 * If the VOP_OLD_MKDIR is successful we are responsible for updating
446 * the cache state of the locked ncp that was passed to us.
448 if (error == EJUSTRETURN) {
449 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
450 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
452 cache_setunresolved(ncp);
453 cache_setvp(ncp, *ap->a_vpp);
461 KKASSERT(*ap->a_vpp == NULL);
463 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
470 * vop_compat_nmknod { struct namecache *a_ncp, XXX STOPGAP FUNCTION
471 * struct vnode *a_vpp,
472 * struct ucred *a_cred,
473 * struct vattr *a_vap }
475 * Create a device or fifo node as specified by a_vap. Compatibility requires
476 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
477 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
480 vop_compat_nmknod(struct vop_nmknod_args *ap)
482 struct thread *td = curthread;
483 struct componentname cnp;
484 struct namecache *ncp;
489 * Sanity checks, get a locked directory vnode.
491 ncp = ap->a_ncp; /* locked namecache node */
492 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
494 if (ncp->nc_parent == NULL)
496 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
499 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
500 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
506 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
507 * caches all information required to create the entry in the
508 * directory inode. We expect a return code of EJUSTRETURN for
509 * the CREATE case. The cnp must simulated a saved-name situation.
511 bzero(&cnp, sizeof(cnp));
512 cnp.cn_nameiop = NAMEI_CREATE;
513 cnp.cn_flags = CNP_LOCKPARENT;
514 cnp.cn_nameptr = ncp->nc_name;
515 cnp.cn_namelen = ncp->nc_nlen;
516 cnp.cn_cred = ap->a_cred;
520 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
523 * EJUSTRETURN should be returned for this case, which means that
524 * the VFS has setup the directory inode for the create. The dvp we
525 * passed in is expected to remain in a locked state.
527 * If the VOP_OLD_MKNOD is successful we are responsible for updating
528 * the cache state of the locked ncp that was passed to us.
530 if (error == EJUSTRETURN) {
531 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
532 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
534 cache_setunresolved(ncp);
535 cache_setvp(ncp, *ap->a_vpp);
543 KKASSERT(*ap->a_vpp == NULL);
545 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
552 * vop_compat_nlink { struct namecache *a_ncp, XXX STOPGAP FUNCTION
553 * struct vnode *a_vp,
554 * struct ucred *a_cred }
556 * The passed vp is locked and represents the source. The passed ncp is
557 * locked and represents the target to create.
560 vop_compat_nlink(struct vop_nlink_args *ap)
562 struct thread *td = curthread;
563 struct componentname cnp;
564 struct namecache *ncp;
570 * Sanity checks, get a locked directory vnode.
572 ncp = ap->a_ncp; /* locked namecache node */
573 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
575 if (ncp->nc_parent == NULL)
577 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
580 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
581 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
587 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
588 * caches all information required to create the entry in the
589 * directory inode. We expect a return code of EJUSTRETURN for
590 * the CREATE case. The cnp must simulated a saved-name situation.
592 bzero(&cnp, sizeof(cnp));
593 cnp.cn_nameiop = NAMEI_CREATE;
594 cnp.cn_flags = CNP_LOCKPARENT;
595 cnp.cn_nameptr = ncp->nc_name;
596 cnp.cn_namelen = ncp->nc_nlen;
597 cnp.cn_cred = ap->a_cred;
601 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
604 * EJUSTRETURN should be returned for this case, which means that
605 * the VFS has setup the directory inode for the create. The dvp we
606 * passed in is expected to remain in a locked state.
608 * If the VOP_OLD_LINK is successful we are responsible for updating
609 * the cache state of the locked ncp that was passed to us.
611 if (error == EJUSTRETURN) {
612 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
613 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
615 cache_setunresolved(ncp);
616 cache_setvp(ncp, ap->a_vp);
624 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
631 vop_compat_nsymlink(struct vop_nsymlink_args *ap)
633 struct thread *td = curthread;
634 struct componentname cnp;
635 struct namecache *ncp;
641 * Sanity checks, get a locked directory vnode.
644 ncp = ap->a_ncp; /* locked namecache node */
645 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
647 if (ncp->nc_parent == NULL)
649 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
652 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
653 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
659 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
660 * caches all information required to create the entry in the
661 * directory inode. We expect a return code of EJUSTRETURN for
662 * the CREATE case. The cnp must simulated a saved-name situation.
664 bzero(&cnp, sizeof(cnp));
665 cnp.cn_nameiop = NAMEI_CREATE;
666 cnp.cn_flags = CNP_LOCKPARENT;
667 cnp.cn_nameptr = ncp->nc_name;
668 cnp.cn_namelen = ncp->nc_nlen;
669 cnp.cn_cred = ap->a_cred;
673 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
676 * EJUSTRETURN should be returned for this case, which means that
677 * the VFS has setup the directory inode for the create. The dvp we
678 * passed in is expected to remain in a locked state.
680 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
681 * the cache state of the locked ncp that was passed to us.
683 if (error == EJUSTRETURN) {
684 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
685 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
687 cache_setunresolved(ncp);
688 cache_setvp(ncp, vp);
697 KKASSERT(vp == NULL);
699 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
706 * vop_compat_nwhiteout { struct namecache *a_ncp, XXX STOPGAP FUNCTION
707 * struct ucred *a_cred,
710 * Issie a whiteout operation (create, lookup, or delete). Compatibility
711 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
712 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
713 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
714 * no lookup is necessary.
717 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
719 struct thread *td = curthread;
720 struct componentname cnp;
721 struct namecache *ncp;
727 * Sanity checks, get a locked directory vnode.
729 ncp = ap->a_ncp; /* locked namecache node */
730 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
732 if (ncp->nc_parent == NULL)
734 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
737 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
738 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
744 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
745 * caches all information required to create the entry in the
746 * directory inode. We expect a return code of EJUSTRETURN for
747 * the CREATE case. The cnp must simulated a saved-name situation.
749 bzero(&cnp, sizeof(cnp));
750 cnp.cn_nameiop = ap->a_flags;
751 cnp.cn_flags = CNP_LOCKPARENT;
752 cnp.cn_nameptr = ncp->nc_name;
753 cnp.cn_namelen = ncp->nc_nlen;
754 cnp.cn_cred = ap->a_cred;
760 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
761 * The VFS has setup the directory inode for the create. The dvp we
762 * passed in is expected to remain in a locked state.
764 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
765 * the cache state of the locked ncp that was passed to us.
767 switch(ap->a_flags) {
769 cnp.cn_flags |= CNP_DOWHITEOUT;
772 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
773 if (error == EJUSTRETURN) {
774 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
775 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
777 cache_setunresolved(ncp);
784 KKASSERT(vp == NULL);
788 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
794 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
802 * vop_compat_nremove { struct namecache *a_ncp, XXX STOPGAP FUNCTION
803 * struct ucred *a_cred }
806 vop_compat_nremove(struct vop_nremove_args *ap)
808 struct thread *td = curthread;
809 struct componentname cnp;
810 struct namecache *ncp;
816 * Sanity checks, get a locked directory vnode.
818 ncp = ap->a_ncp; /* locked namecache node */
819 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
821 if (ncp->nc_parent == NULL)
823 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
826 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
827 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
833 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
834 * caches all information required to delete the entry in the
835 * directory inode. We expect a return code of 0 for the DELETE
836 * case (meaning that a vp has been found). The cnp must simulated
837 * a saved-name situation.
839 bzero(&cnp, sizeof(cnp));
840 cnp.cn_nameiop = NAMEI_DELETE;
841 cnp.cn_flags = CNP_LOCKPARENT;
842 cnp.cn_nameptr = ncp->nc_name;
843 cnp.cn_namelen = ncp->nc_nlen;
844 cnp.cn_cred = ap->a_cred;
848 * The vnode must be a directory and must not represent the
852 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
853 if (error == 0 && vp->v_type == VDIR)
856 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
857 error = VOP_OLD_REMOVE(dvp, vp, &cnp);
859 cache_setunresolved(ncp);
860 cache_setvp(ncp, NULL);
869 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
876 * vop_compat_nrmdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION
877 * struct ucred *a_cred }
880 vop_compat_nrmdir(struct vop_nrmdir_args *ap)
882 struct thread *td = curthread;
883 struct componentname cnp;
884 struct namecache *ncp;
890 * Sanity checks, get a locked directory vnode.
892 ncp = ap->a_ncp; /* locked namecache node */
893 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
895 if (ncp->nc_parent == NULL)
897 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
900 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
901 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
907 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
908 * caches all information required to delete the entry in the
909 * directory inode. We expect a return code of 0 for the DELETE
910 * case (meaning that a vp has been found). The cnp must simulated
911 * a saved-name situation.
913 bzero(&cnp, sizeof(cnp));
914 cnp.cn_nameiop = NAMEI_DELETE;
915 cnp.cn_flags = CNP_LOCKPARENT;
916 cnp.cn_nameptr = ncp->nc_name;
917 cnp.cn_namelen = ncp->nc_nlen;
918 cnp.cn_cred = ap->a_cred;
922 * The vnode must be a directory and must not represent the
926 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
927 if (error == 0 && vp->v_type != VDIR)
929 if (error == 0 && vp == dvp)
931 if (error == 0 && (vp->v_flag & VROOT))
934 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
935 error = VOP_OLD_RMDIR(dvp, vp, &cnp);
938 * Note that this invalidation will cause any process
939 * currently CD'd into the directory being removed to be
940 * disconnected from the topology and not be able to ".."
944 cache_inval(ncp, CINV_DESTROY);
952 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
959 * vop_compat_nrename { struct namecache *a_fncp, XXX STOPGAP FUNCTION
960 * struct namecache *a_tncp,
961 * struct ucred *a_cred }
963 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
964 * the source directory and vnode be unlocked and the target directory and
965 * vnode (if it exists) be locked. All arguments will be vrele'd and
966 * the targets will also be unlocked regardless of the return code.
969 vop_compat_nrename(struct vop_nrename_args *ap)
971 struct thread *td = curthread;
972 struct componentname fcnp;
973 struct componentname tcnp;
974 struct namecache *fncp;
975 struct namecache *tncp;
976 struct vnode *fdvp, *fvp;
977 struct vnode *tdvp, *tvp;
981 * Sanity checks, get referenced vnodes representing the source.
983 fncp = ap->a_fncp; /* locked namecache node */
984 if (fncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
986 if (fncp->nc_parent == NULL)
988 if ((fdvp = fncp->nc_parent->nc_vp) == NULL)
992 * Temporarily lock the source directory and lookup in DELETE mode to
993 * check permissions. XXX delete permissions should have been
994 * checked by nlookup(), we need to add NLC_DELETE for delete
995 * checking. It is unclear whether VFS's require the directory setup
996 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
997 * since it isn't locked and since UFS always does a relookup of
998 * the source, it is believed that the only side effect that matters
999 * is the permissions check.
1001 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) {
1002 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1003 fncp, fncp->nc_name);
1007 bzero(&fcnp, sizeof(fcnp));
1008 fcnp.cn_nameiop = NAMEI_DELETE;
1009 fcnp.cn_flags = CNP_LOCKPARENT;
1010 fcnp.cn_nameptr = fncp->nc_name;
1011 fcnp.cn_namelen = fncp->nc_nlen;
1012 fcnp.cn_cred = ap->a_cred;
1016 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1020 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
1021 if (error == 0 && (fvp->v_flag & VROOT)) {
1022 vput(fvp); /* as if vop_old_lookup had failed */
1025 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1026 fcnp.cn_flags |= CNP_PDIRUNLOCK;
1027 VOP_UNLOCK(fdvp, 0);
1036 * fdvp and fvp are now referenced and unlocked.
1038 * Get a locked directory vnode for the target and lookup the target
1039 * in CREATE mode so it places the required information in the
1042 tncp = ap->a_tncp; /* locked namecache node */
1043 if (tncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
1045 if (tncp->nc_parent == NULL)
1047 if ((tdvp = tncp->nc_parent->nc_vp) == NULL)
1054 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) {
1055 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1056 tncp, tncp->nc_name);
1063 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1064 * caches all information required to create the entry in the
1065 * target directory inode.
1067 bzero(&tcnp, sizeof(tcnp));
1068 tcnp.cn_nameiop = NAMEI_RENAME;
1069 tcnp.cn_flags = CNP_LOCKPARENT;
1070 tcnp.cn_nameptr = tncp->nc_name;
1071 tcnp.cn_namelen = tncp->nc_nlen;
1072 tcnp.cn_cred = ap->a_cred;
1076 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
1078 if (error == EJUSTRETURN) {
1080 * Target does not exist. tvp should be NULL.
1082 KKASSERT(tvp == NULL);
1083 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1084 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1086 cache_rename(fncp, tncp);
1087 cache_setvp(tncp, fvp);
1089 } else if (error == 0) {
1091 * Target exists. VOP_OLD_RENAME should correctly delete the
1094 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1095 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1097 cache_rename(fncp, tncp);
1098 cache_setvp(tncp, fvp);
1103 if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1113 struct vop_old_lookup_args /* {
1114 struct vnode *a_dvp;
1115 struct vnode **a_vpp;
1116 struct componentname *a_cnp;
1127 * Strategy routine for VFS devices that have none.
1129 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1130 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1131 * Typically B_INVAL is assumed to already be clear prior to a write
1132 * and should not be cleared manually unless you just made the buffer
1133 * invalid. B_ERROR should be cleared either way.
1137 vop_nostrategy (struct vop_strategy_args *ap)
1139 printf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
1140 vprint("", ap->a_vp);
1141 ap->a_bio->bio_buf->b_flags |= B_ERROR;
1142 ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1144 return (EOPNOTSUPP);
1149 struct vop_pathconf_args /* {
1156 switch (ap->a_name) {
1158 *ap->a_retval = LINK_MAX;
1161 *ap->a_retval = MAX_CANON;
1164 *ap->a_retval = MAX_INPUT;
1167 *ap->a_retval = PIPE_BUF;
1169 case _PC_CHOWN_RESTRICTED:
1173 *ap->a_retval = _POSIX_VDISABLE;
1184 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp,
1185 * struct thread *a_td)
1187 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1190 vop_stdopen(struct vop_open_args *ap)
1192 struct vnode *vp = ap->a_vp;
1195 if ((fp = ap->a_fp) != NULL) {
1196 switch(vp->v_type) {
1198 fp->f_type = DTYPE_FIFO;
1201 fp->f_type = DTYPE_VNODE;
1204 fp->f_flag = ap->a_mode & FMASK;
1205 fp->f_ops = &vnode_fileops;
1209 if (ap->a_mode & FWRITE)
1211 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX);
1219 * (struct vnode *a_vp, int a_fflag, struct thread *a_td)
1221 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1224 vop_stdclose(struct vop_close_args *ap)
1226 struct vnode *vp = ap->a_vp;
1228 KASSERT(vp->v_opencount > 0,
1229 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d\n", vp, vp->v_opencount));
1230 if (ap->a_fflag & FWRITE) {
1231 KASSERT(vp->v_writecount > 0,
1232 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1233 vp, vp->v_writecount));
1241 * Standard lock. The lock is recursive-capable only if the lock was
1242 * initialized with LK_CANRECURSE or that flag is passed in a_flags.
1246 struct vop_lock_args /* {
1254 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags);
1256 error = debuglockmgr(&ap->a_vp->v_lock, ap->a_flags,
1257 "vop_stdlock", ap->a_vp->filename, ap->a_vp->line);
1264 struct vop_unlock_args /* {
1271 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags | LK_RELEASE);
1277 struct vop_islocked_args /* {
1279 struct thread *a_td;
1282 return (lockstatus(&ap->a_vp->v_lock, ap->a_td));
1286 * Return true for select/poll.
1290 struct vop_poll_args /* {
1293 struct ucred *a_cred;
1298 * Return true for read/write. If the user asked for something
1299 * special, return POLLNVAL, so that clients have a way of
1300 * determining reliably whether or not the extended
1301 * functionality is present without hard-coding knowledge
1302 * of specific filesystem implementations.
1304 if (ap->a_events & ~POLLSTANDARD)
1307 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1311 * Implement poll for local filesystems that support it.
1315 struct vop_poll_args /* {
1318 struct ucred *a_cred;
1321 if (ap->a_events & ~POLLSTANDARD)
1322 return (vn_pollrecord(ap->a_vp, ap->a_events));
1323 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1328 * used to fill the vfs fucntion table to get reasonable default return values.
1331 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
1337 vfs_stdunmount(struct mount *mp, int mntflags)
1343 vfs_stdroot(struct mount *mp, struct vnode **vpp)
1345 return (EOPNOTSUPP);
1349 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
1351 return (EOPNOTSUPP);
1355 vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
1357 return (EOPNOTSUPP);
1361 vfs_stdstart(struct mount *mp, int flags)
1367 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
1368 caddr_t arg, struct ucred *cred)
1370 return (EOPNOTSUPP);
1374 vfs_stdsync(struct mount *mp, int waitfor)
1380 vfs_stdnosync(struct mount *mp, int waitfor)
1382 return (EOPNOTSUPP);
1386 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp)
1388 return (EOPNOTSUPP);
1392 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
1394 return (EOPNOTSUPP);
1398 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1399 struct ucred **credanonp)
1401 return (EOPNOTSUPP);
1405 vfs_stdinit(struct vfsconf *vfsp)
1411 vfs_stduninit(struct vfsconf *vfsp)
1417 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname,
1418 caddr_t arg, struct ucred *cred)
1423 /* end of vfs default ops */