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.47 2006/12/24 00:47:54 swildner 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_mmap
= (void *)vop_einval
,
83 .vop_old_lookup
= vop_nolookup
,
84 .vop_open
= vop_stdopen
,
85 .vop_close
= vop_stdclose
,
86 .vop_pathconf
= (void *)vop_einval
,
87 .vop_poll
= vop_nopoll
,
88 .vop_readlink
= (void *)vop_einval
,
89 .vop_reallocblks
= (void *)vop_eopnotsupp
,
90 .vop_revoke
= vop_stdrevoke
,
91 .vop_strategy
= vop_nostrategy
,
92 .vop_getacl
= (void *)vop_eopnotsupp
,
93 .vop_setacl
= (void *)vop_eopnotsupp
,
94 .vop_aclcheck
= (void *)vop_eopnotsupp
,
95 .vop_getextattr
= (void *)vop_eopnotsupp
,
96 .vop_setextattr
= (void *)vop_eopnotsupp
,
97 .vop_nresolve
= vop_compat_nresolve
,
98 .vop_nlookupdotdot
= vop_compat_nlookupdotdot
,
99 .vop_ncreate
= vop_compat_ncreate
,
100 .vop_nmkdir
= vop_compat_nmkdir
,
101 .vop_nmknod
= vop_compat_nmknod
,
102 .vop_nlink
= vop_compat_nlink
,
103 .vop_nsymlink
= vop_compat_nsymlink
,
104 .vop_nwhiteout
= vop_compat_nwhiteout
,
105 .vop_nremove
= vop_compat_nremove
,
106 .vop_nrmdir
= vop_compat_nrmdir
,
107 .vop_nrename
= vop_compat_nrename
,
108 .vop_mountctl
= journal_mountctl
111 VNODEOP_SET(default_vnode_vops
);
114 vop_eopnotsupp(struct vop_generic_args
*ap
)
120 vop_ebadf(struct vop_generic_args
*ap
)
126 vop_enotty(struct vop_generic_args
*ap
)
132 vop_einval(struct vop_generic_args
*ap
)
138 vop_null(struct vop_generic_args
*ap
)
144 vop_defaultop(struct vop_generic_args
*ap
)
146 return (VOCALL(&default_vnode_vops
, ap
));
150 vop_panic(struct vop_generic_args
*ap
)
152 panic("filesystem goof: vop_panic[%s]", ap
->a_desc
->sd_name
);
156 * vop_compat_resolve { struct nchandle *a_nch } XXX STOPGAP FUNCTION
158 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
159 * WILL BE REMOVED. This procedure exists for all VFSs which have not
160 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
161 * vop_old_lookup() and does appropriate translations.
163 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
164 * VFSs will support this VOP and this routine can be removed, since
165 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
168 * A locked ncp is passed in to be resolved. The NCP is resolved by
169 * figuring out the vnode (if any) and calling cache_setvp() to attach the
170 * vnode to the entry. If the entry represents a non-existant node then
171 * cache_setvp() is called with a NULL vnode to resolve the entry into a
172 * negative cache entry. No vnode locks are retained and the
173 * ncp is left locked on return.
175 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
177 * There is a potential directory and vnode interlock. The lock order
178 * requirement is: namecache, governing directory, resolved vnode.
181 vop_compat_nresolve(struct vop_nresolve_args
*ap
)
186 struct nchandle
*nch
;
187 struct namecache
*ncp
;
188 struct componentname cnp
;
190 nch
= ap
->a_nch
; /* locked namecache node */
192 if (ncp
->nc_parent
== NULL
)
194 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
198 * UFS currently stores all sorts of side effects, including a loop
199 * variable, in the directory inode. That needs to be fixed and the
200 * other VFS's audited before we can switch to LK_SHARED.
202 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
203 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
208 bzero(&cnp
, sizeof(cnp
));
209 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
211 cnp
.cn_nameptr
= ncp
->nc_name
;
212 cnp
.cn_namelen
= ncp
->nc_nlen
;
213 cnp
.cn_cred
= ap
->a_cred
;
214 cnp
.cn_td
= curthread
; /* XXX */
217 * vop_old_lookup() always returns vp locked. dvp may or may not be
218 * left locked depending on CNP_PDIRUNLOCK.
220 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
223 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
225 if ((ncp
->nc_flag
& NCF_UNRESOLVED
) == 0) {
226 /* was resolved by another process while we were unlocked */
229 } else if (error
== 0) {
230 KKASSERT(vp
!= NULL
);
231 cache_setvp(nch
, vp
);
233 } else if (error
== ENOENT
) {
234 KKASSERT(vp
== NULL
);
235 if (cnp
.cn_flags
& CNP_ISWHITEOUT
)
236 ncp
->nc_flag
|= NCF_WHITEOUT
;
237 cache_setvp(nch
, NULL
);
244 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
245 * struct vnode **a_vpp,
246 * struct ucred *a_cred }
248 * Lookup the vnode representing the parent directory of the specified
249 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
250 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
252 * This function is designed to aid NFS server-side operations and is
253 * used by cache_fromdvp() to create a consistent, connected namecache
256 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
257 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
258 * permits VFSs will implement the remaining *_n*() calls and finally get
259 * rid of their *_lookup() call.
262 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args
*ap
)
264 struct componentname cnp
;
268 * UFS currently stores all sorts of side effects, including a loop
269 * variable, in the directory inode. That needs to be fixed and the
270 * other VFS's audited before we can switch to LK_SHARED.
273 if ((error
= vget(ap
->a_dvp
, LK_EXCLUSIVE
)) != 0)
275 if (ap
->a_dvp
->v_type
!= VDIR
) {
280 bzero(&cnp
, sizeof(cnp
));
281 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
282 cnp
.cn_flags
= CNP_ISDOTDOT
;
283 cnp
.cn_nameptr
= "..";
285 cnp
.cn_cred
= ap
->a_cred
;
286 cnp
.cn_td
= curthread
; /* XXX */
289 * vop_old_lookup() always returns vp locked. dvp may or may not be
290 * left locked depending on CNP_PDIRUNLOCK.
292 error
= vop_old_lookup(ap
->a_head
.a_ops
, ap
->a_dvp
, ap
->a_vpp
, &cnp
);
294 vn_unlock(*ap
->a_vpp
);
295 if (cnp
.cn_flags
& CNP_PDIRUNLOCK
)
303 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
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
;
323 * Sanity checks, get a locked directory vnode.
325 nch
= ap
->a_nch
; /* locked namecache node */
327 if (ncp
->nc_parent
== NULL
)
329 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
332 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
333 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
339 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
340 * caches all information required to create the entry in the
341 * directory inode. We expect a return code of EJUSTRETURN for
342 * the CREATE case. The cnp must simulated a saved-name situation.
344 bzero(&cnp
, sizeof(cnp
));
345 cnp
.cn_nameiop
= NAMEI_CREATE
;
346 cnp
.cn_flags
= CNP_LOCKPARENT
;
347 cnp
.cn_nameptr
= ncp
->nc_name
;
348 cnp
.cn_namelen
= ncp
->nc_nlen
;
349 cnp
.cn_cred
= ap
->a_cred
;
353 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
356 * EJUSTRETURN should be returned for this case, which means that
357 * the VFS has setup the directory inode for the create. The dvp we
358 * passed in is expected to remain in a locked state.
360 * If the VOP_OLD_CREATE is successful we are responsible for updating
361 * the cache state of the locked ncp that was passed to us.
363 if (error
== EJUSTRETURN
) {
364 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
365 error
= VOP_OLD_CREATE(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
367 cache_setunresolved(nch
);
368 cache_setvp(nch
, *ap
->a_vpp
);
376 KKASSERT(*ap
->a_vpp
== NULL
);
378 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
385 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
386 * struct vnode *a_vpp,
387 * struct ucred *a_cred,
388 * struct vattr *a_vap }
390 * Create a directory as specified by a_vap. Compatibility requires us to
391 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
392 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
395 vop_compat_nmkdir(struct vop_nmkdir_args
*ap
)
397 struct thread
*td
= curthread
;
398 struct componentname cnp
;
399 struct nchandle
*nch
;
400 struct namecache
*ncp
;
405 * Sanity checks, get a locked directory vnode.
407 nch
= ap
->a_nch
; /* locked namecache node */
409 if (ncp
->nc_parent
== NULL
)
411 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
414 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
415 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
421 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
422 * caches all information required to create the entry in the
423 * directory inode. We expect a return code of EJUSTRETURN for
424 * the CREATE case. The cnp must simulated a saved-name situation.
426 bzero(&cnp
, sizeof(cnp
));
427 cnp
.cn_nameiop
= NAMEI_CREATE
;
428 cnp
.cn_flags
= CNP_LOCKPARENT
;
429 cnp
.cn_nameptr
= ncp
->nc_name
;
430 cnp
.cn_namelen
= ncp
->nc_nlen
;
431 cnp
.cn_cred
= ap
->a_cred
;
435 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
438 * EJUSTRETURN should be returned for this case, which means that
439 * the VFS has setup the directory inode for the create. The dvp we
440 * passed in is expected to remain in a locked state.
442 * If the VOP_OLD_MKDIR is successful we are responsible for updating
443 * the cache state of the locked ncp that was passed to us.
445 if (error
== EJUSTRETURN
) {
446 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
447 error
= VOP_OLD_MKDIR(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
449 cache_setunresolved(nch
);
450 cache_setvp(nch
, *ap
->a_vpp
);
458 KKASSERT(*ap
->a_vpp
== NULL
);
460 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
467 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
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 */
491 if (ncp
->nc_parent
== NULL
)
493 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
496 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
497 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
503 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
504 * caches all information required to create the entry in the
505 * directory inode. We expect a return code of EJUSTRETURN for
506 * the CREATE case. The cnp must simulated a saved-name situation.
508 bzero(&cnp
, sizeof(cnp
));
509 cnp
.cn_nameiop
= NAMEI_CREATE
;
510 cnp
.cn_flags
= CNP_LOCKPARENT
;
511 cnp
.cn_nameptr
= ncp
->nc_name
;
512 cnp
.cn_namelen
= ncp
->nc_nlen
;
513 cnp
.cn_cred
= ap
->a_cred
;
517 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
520 * EJUSTRETURN should be returned for this case, which means that
521 * the VFS has setup the directory inode for the create. The dvp we
522 * passed in is expected to remain in a locked state.
524 * If the VOP_OLD_MKNOD is successful we are responsible for updating
525 * the cache state of the locked ncp that was passed to us.
527 if (error
== EJUSTRETURN
) {
528 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
529 error
= VOP_OLD_MKNOD(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
531 cache_setunresolved(nch
);
532 cache_setvp(nch
, *ap
->a_vpp
);
540 KKASSERT(*ap
->a_vpp
== NULL
);
542 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
549 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
550 * struct vnode *a_vp,
551 * struct ucred *a_cred }
553 * The passed vp is locked and represents the source. The passed ncp is
554 * locked and represents the target to create.
557 vop_compat_nlink(struct vop_nlink_args
*ap
)
559 struct thread
*td
= curthread
;
560 struct componentname cnp
;
561 struct nchandle
*nch
;
562 struct namecache
*ncp
;
568 * Sanity checks, get a locked directory vnode.
570 nch
= ap
->a_nch
; /* locked namecache node */
572 if (ncp
->nc_parent
== NULL
)
574 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
577 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
578 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
584 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
585 * caches all information required to create the entry in the
586 * directory inode. We expect a return code of EJUSTRETURN for
587 * the CREATE case. The cnp must simulated a saved-name situation.
589 bzero(&cnp
, sizeof(cnp
));
590 cnp
.cn_nameiop
= NAMEI_CREATE
;
591 cnp
.cn_flags
= CNP_LOCKPARENT
;
592 cnp
.cn_nameptr
= ncp
->nc_name
;
593 cnp
.cn_namelen
= ncp
->nc_nlen
;
594 cnp
.cn_cred
= ap
->a_cred
;
598 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &tvp
, &cnp
);
601 * EJUSTRETURN should be returned for this case, which means that
602 * the VFS has setup the directory inode for the create. The dvp we
603 * passed in is expected to remain in a locked state.
605 * If the VOP_OLD_LINK is successful we are responsible for updating
606 * the cache state of the locked ncp that was passed to us.
608 if (error
== EJUSTRETURN
) {
609 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
610 error
= VOP_OLD_LINK(dvp
, ap
->a_vp
, &cnp
);
612 cache_setunresolved(nch
);
613 cache_setvp(nch
, ap
->a_vp
);
621 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
628 vop_compat_nsymlink(struct vop_nsymlink_args
*ap
)
630 struct thread
*td
= curthread
;
631 struct componentname cnp
;
632 struct nchandle
*nch
;
633 struct namecache
*ncp
;
639 * Sanity checks, get a locked directory vnode.
642 nch
= ap
->a_nch
; /* locked namecache node */
644 if (ncp
->nc_parent
== NULL
)
646 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
649 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
650 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
656 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
657 * caches all information required to create the entry in the
658 * directory inode. We expect a return code of EJUSTRETURN for
659 * the CREATE case. The cnp must simulated a saved-name situation.
661 bzero(&cnp
, sizeof(cnp
));
662 cnp
.cn_nameiop
= NAMEI_CREATE
;
663 cnp
.cn_flags
= CNP_LOCKPARENT
;
664 cnp
.cn_nameptr
= ncp
->nc_name
;
665 cnp
.cn_namelen
= ncp
->nc_nlen
;
666 cnp
.cn_cred
= ap
->a_cred
;
670 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
673 * EJUSTRETURN should be returned for this case, which means that
674 * the VFS has setup the directory inode for the create. The dvp we
675 * passed in is expected to remain in a locked state.
677 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
678 * the cache state of the locked ncp that was passed to us.
680 if (error
== EJUSTRETURN
) {
681 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
682 error
= VOP_OLD_SYMLINK(dvp
, &vp
, &cnp
, ap
->a_vap
, ap
->a_target
);
684 cache_setunresolved(nch
);
685 cache_setvp(nch
, vp
);
694 KKASSERT(vp
== NULL
);
696 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
703 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
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 */
729 if (ncp
->nc_parent
== NULL
)
731 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
734 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
735 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
741 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
742 * caches all information required to create the entry in the
743 * directory inode. We expect a return code of EJUSTRETURN for
744 * the CREATE case. The cnp must simulated a saved-name situation.
746 bzero(&cnp
, sizeof(cnp
));
747 cnp
.cn_nameiop
= ap
->a_flags
;
748 cnp
.cn_flags
= CNP_LOCKPARENT
;
749 cnp
.cn_nameptr
= ncp
->nc_name
;
750 cnp
.cn_namelen
= ncp
->nc_nlen
;
751 cnp
.cn_cred
= ap
->a_cred
;
757 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
758 * The VFS has setup the directory inode for the create. The dvp we
759 * passed in is expected to remain in a locked state.
761 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
762 * the cache state of the locked ncp that was passed to us.
764 switch(ap
->a_flags
) {
766 cnp
.cn_flags
|= CNP_DOWHITEOUT
;
769 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
770 if (error
== EJUSTRETURN
) {
771 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
772 error
= VOP_OLD_WHITEOUT(dvp
, &cnp
, ap
->a_flags
);
774 cache_setunresolved(nch
);
781 KKASSERT(vp
== NULL
);
785 error
= VOP_OLD_WHITEOUT(dvp
, NULL
, ap
->a_flags
);
791 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
799 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
800 * struct ucred *a_cred }
803 vop_compat_nremove(struct vop_nremove_args
*ap
)
805 struct thread
*td
= curthread
;
806 struct componentname cnp
;
807 struct nchandle
*nch
;
808 struct namecache
*ncp
;
814 * Sanity checks, get a locked directory vnode.
816 nch
= ap
->a_nch
; /* locked namecache node */
818 if (ncp
->nc_parent
== NULL
)
820 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
823 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
824 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
830 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
831 * caches all information required to delete the entry in the
832 * directory inode. We expect a return code of 0 for the DELETE
833 * case (meaning that a vp has been found). The cnp must simulated
834 * a saved-name situation.
836 bzero(&cnp
, sizeof(cnp
));
837 cnp
.cn_nameiop
= NAMEI_DELETE
;
838 cnp
.cn_flags
= CNP_LOCKPARENT
;
839 cnp
.cn_nameptr
= ncp
->nc_name
;
840 cnp
.cn_namelen
= ncp
->nc_nlen
;
841 cnp
.cn_cred
= ap
->a_cred
;
845 * The vnode must be a directory and must not represent the
849 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
850 if (error
== 0 && vp
->v_type
== VDIR
)
853 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
854 error
= VOP_OLD_REMOVE(dvp
, vp
, &cnp
);
856 cache_setunresolved(nch
);
857 cache_setvp(nch
, NULL
);
858 cache_inval_vp(vp
, CINV_DESTROY
);
867 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
874 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
875 * struct ucred *a_cred }
878 vop_compat_nrmdir(struct vop_nrmdir_args
*ap
)
880 struct thread
*td
= curthread
;
881 struct componentname cnp
;
882 struct nchandle
*nch
;
883 struct namecache
*ncp
;
889 * Sanity checks, get a locked directory vnode.
891 nch
= ap
->a_nch
; /* locked namecache node */
893 if (ncp
->nc_parent
== NULL
)
895 if ((dvp
= ncp
->nc_parent
->nc_vp
) == NULL
)
898 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
899 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
905 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
906 * caches all information required to delete the entry in the
907 * directory inode. We expect a return code of 0 for the DELETE
908 * case (meaning that a vp has been found). The cnp must simulated
909 * a saved-name situation.
911 bzero(&cnp
, sizeof(cnp
));
912 cnp
.cn_nameiop
= NAMEI_DELETE
;
913 cnp
.cn_flags
= CNP_LOCKPARENT
;
914 cnp
.cn_nameptr
= ncp
->nc_name
;
915 cnp
.cn_namelen
= ncp
->nc_nlen
;
916 cnp
.cn_cred
= ap
->a_cred
;
920 * The vnode must be a directory and must not represent the
924 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
925 if (error
== 0 && vp
->v_type
!= VDIR
)
927 if (error
== 0 && vp
== dvp
)
929 if (error
== 0 && (vp
->v_flag
& VROOT
))
932 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
933 error
= VOP_OLD_RMDIR(dvp
, vp
, &cnp
);
936 * Note that this invalidation will cause any process
937 * currently CD'd into the directory being removed to be
938 * disconnected from the topology and not be able to ".."
942 cache_inval(nch
, CINV_DESTROY
);
943 cache_inval_vp(vp
, CINV_DESTROY
);
952 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
959 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
960 * struct nchandle *a_tnch,
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 nchandle
*fnch
;
975 struct nchandle
*tnch
;
976 struct namecache
*fncp
;
977 struct namecache
*tncp
;
978 struct vnode
*fdvp
, *fvp
;
979 struct vnode
*tdvp
, *tvp
;
983 * Sanity checks, get referenced vnodes representing the source.
985 fnch
= ap
->a_fnch
; /* locked namecache node */
987 if (fncp
->nc_parent
== NULL
)
989 if ((fdvp
= fncp
->nc_parent
->nc_vp
) == NULL
)
993 * Temporarily lock the source directory and lookup in DELETE mode to
994 * check permissions. XXX delete permissions should have been
995 * checked by nlookup(), we need to add NLC_DELETE for delete
996 * checking. It is unclear whether VFS's require the directory setup
997 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
998 * since it isn't locked and since UFS always does a relookup of
999 * the source, it is believed that the only side effect that matters
1000 * is the permissions check.
1002 if ((error
= vget(fdvp
, LK_EXCLUSIVE
)) != 0) {
1003 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1004 fncp
, fncp
->nc_name
);
1008 bzero(&fcnp
, sizeof(fcnp
));
1009 fcnp
.cn_nameiop
= NAMEI_DELETE
;
1010 fcnp
.cn_flags
= CNP_LOCKPARENT
;
1011 fcnp
.cn_nameptr
= fncp
->nc_name
;
1012 fcnp
.cn_namelen
= fncp
->nc_nlen
;
1013 fcnp
.cn_cred
= ap
->a_cred
;
1017 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1021 error
= vop_old_lookup(ap
->a_head
.a_ops
, fdvp
, &fvp
, &fcnp
);
1022 if (error
== 0 && (fvp
->v_flag
& VROOT
)) {
1023 vput(fvp
); /* as if vop_old_lookup had failed */
1026 if ((fcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0) {
1027 fcnp
.cn_flags
|= CNP_PDIRUNLOCK
;
1037 * fdvp and fvp are now referenced and unlocked.
1039 * Get a locked directory vnode for the target and lookup the target
1040 * in CREATE mode so it places the required information in the
1043 tnch
= ap
->a_tnch
; /* locked namecache node */
1045 if (tncp
->nc_parent
== NULL
)
1047 if ((tdvp
= tncp
->nc_parent
->nc_vp
) == NULL
)
1054 if ((error
= vget(tdvp
, LK_EXCLUSIVE
)) != 0) {
1055 kprintf("[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(fnch
, tnch
);
1087 cache_setvp(tnch
, 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(fnch
, tnch
);
1098 cache_setvp(tnch
, fvp
);
1103 if (tcnp
.cn_flags
& CNP_PDIRUNLOCK
)
1112 vop_nolookup(struct vop_old_lookup_args
*ap
)
1122 * Strategy routine for VFS devices that have none.
1124 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1125 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1126 * Typically B_INVAL is assumed to already be clear prior to a write
1127 * and should not be cleared manually unless you just made the buffer
1128 * invalid. B_ERROR should be cleared either way.
1132 vop_nostrategy (struct vop_strategy_args
*ap
)
1134 kprintf("No strategy for buffer at %p\n", ap
->a_bio
->bio_buf
);
1135 vprint("", ap
->a_vp
);
1136 ap
->a_bio
->bio_buf
->b_flags
|= B_ERROR
;
1137 ap
->a_bio
->bio_buf
->b_error
= EOPNOTSUPP
;
1139 return (EOPNOTSUPP
);
1143 vop_stdpathconf(struct vop_pathconf_args
*ap
)
1146 switch (ap
->a_name
) {
1148 *ap
->a_retval
= LINK_MAX
;
1151 *ap
->a_retval
= MAX_CANON
;
1154 *ap
->a_retval
= MAX_INPUT
;
1157 *ap
->a_retval
= PIPE_BUF
;
1159 case _PC_CHOWN_RESTRICTED
:
1163 *ap
->a_retval
= _POSIX_VDISABLE
;
1174 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp,
1175 * struct thread *a_td)
1177 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1180 vop_stdopen(struct vop_open_args
*ap
)
1182 struct vnode
*vp
= ap
->a_vp
;
1185 if ((fp
= ap
->a_fp
) != NULL
) {
1186 switch(vp
->v_type
) {
1188 fp
->f_type
= DTYPE_FIFO
;
1191 fp
->f_type
= DTYPE_VNODE
;
1194 fp
->f_flag
= ap
->a_mode
& FMASK
;
1195 fp
->f_ops
= &vnode_fileops
;
1199 if (ap
->a_mode
& FWRITE
)
1201 KKASSERT(vp
->v_opencount
>= 0 && vp
->v_opencount
!= INT_MAX
);
1209 * (struct vnode *a_vp, int a_fflag, struct thread *a_td)
1211 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1214 vop_stdclose(struct vop_close_args
*ap
)
1216 struct vnode
*vp
= ap
->a_vp
;
1218 KASSERT(vp
->v_opencount
> 0,
1219 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d\n", vp
, vp
->v_opencount
));
1220 if (ap
->a_fflag
& FWRITE
) {
1221 KASSERT(vp
->v_writecount
> 0,
1222 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1223 vp
, vp
->v_writecount
));
1231 * Return true for select/poll.
1234 vop_nopoll(struct vop_poll_args
*ap
)
1237 * Return true for read/write. If the user asked for something
1238 * special, return POLLNVAL, so that clients have a way of
1239 * determining reliably whether or not the extended
1240 * functionality is present without hard-coding knowledge
1241 * of specific filesystem implementations.
1243 if (ap
->a_events
& ~POLLSTANDARD
)
1246 return (ap
->a_events
& (POLLIN
| POLLOUT
| POLLRDNORM
| POLLWRNORM
));
1250 * Implement poll for local filesystems that support it.
1253 vop_stdpoll(struct vop_poll_args
*ap
)
1255 if (ap
->a_events
& ~POLLSTANDARD
)
1256 return (vn_pollrecord(ap
->a_vp
, ap
->a_events
));
1257 return (ap
->a_events
& (POLLIN
| POLLOUT
| POLLRDNORM
| POLLWRNORM
));
1262 * used to fill the vfs fucntion table to get reasonable default return values.
1265 vfs_stdmount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
1271 vfs_stdunmount(struct mount
*mp
, int mntflags
)
1277 vfs_stdroot(struct mount
*mp
, struct vnode
**vpp
)
1279 return (EOPNOTSUPP
);
1283 vfs_stdstatfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
1285 return (EOPNOTSUPP
);
1289 vfs_stdvptofh(struct vnode
*vp
, struct fid
*fhp
)
1291 return (EOPNOTSUPP
);
1295 vfs_stdstart(struct mount
*mp
, int flags
)
1301 vfs_stdquotactl(struct mount
*mp
, int cmds
, uid_t uid
,
1302 caddr_t arg
, struct ucred
*cred
)
1304 return (EOPNOTSUPP
);
1308 vfs_stdsync(struct mount
*mp
, int waitfor
)
1314 vfs_stdnosync(struct mount
*mp
, int waitfor
)
1316 return (EOPNOTSUPP
);
1320 vfs_stdvget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
1322 return (EOPNOTSUPP
);
1326 vfs_stdfhtovp(struct mount
*mp
, struct fid
*fhp
, struct vnode
**vpp
)
1328 return (EOPNOTSUPP
);
1332 vfs_stdcheckexp(struct mount
*mp
, struct sockaddr
*nam
, int *extflagsp
,
1333 struct ucred
**credanonp
)
1335 return (EOPNOTSUPP
);
1339 vfs_stdinit(struct vfsconf
*vfsp
)
1345 vfs_stduninit(struct vfsconf
*vfsp
)
1351 vfs_stdextattrctl(struct mount
*mp
, int cmd
, const char *attrname
,
1352 caddr_t arg
, struct ucred
*cred
)
1357 /* end of vfs default ops */