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 $
41 * $DragonFly: src/sys/kern/vfs_default.c,v 1.55 2008/09/28 04:31:50 dillon Exp $
44 #include <sys/param.h>
45 #include <sys/systm.h>
48 #include <sys/fcntl.h>
50 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/mount.h>
54 #include <sys/unistd.h>
55 #include <sys/vnode.h>
56 #include <sys/namei.h>
57 #include <sys/nlookup.h>
59 #include <sys/mountctl.h>
61 #include <machine/limits.h>
64 #include <vm/vm_object.h>
65 #include <vm/vm_page.h>
66 #include <vm/vm_pager.h>
67 #include <vm/vnode_pager.h>
69 static int vop_nolookup (struct vop_old_lookup_args
*);
70 static int vop_nostrategy (struct vop_strategy_args
*);
73 * This vnode table stores what we want to do if the filesystem doesn't
74 * implement a particular VOP.
76 * If there is no specific entry here, we will return EOPNOTSUPP.
78 struct vop_ops default_vnode_vops
= {
79 .vop_default
= vop_eopnotsupp
,
80 .vop_advlock
= (void *)vop_einval
,
81 .vop_fsync
= (void *)vop_null
,
82 .vop_ioctl
= (void *)vop_enotty
,
83 .vop_mmap
= (void *)vop_einval
,
84 .vop_old_lookup
= vop_nolookup
,
85 .vop_open
= vop_stdopen
,
86 .vop_close
= vop_stdclose
,
87 .vop_pathconf
= vop_stdpathconf
,
88 .vop_poll
= vop_nopoll
,
89 .vop_readlink
= (void *)vop_einval
,
90 .vop_reallocblks
= (void *)vop_eopnotsupp
,
91 .vop_revoke
= vop_stdrevoke
,
92 .vop_strategy
= vop_nostrategy
,
93 .vop_getacl
= (void *)vop_eopnotsupp
,
94 .vop_setacl
= (void *)vop_eopnotsupp
,
95 .vop_aclcheck
= (void *)vop_eopnotsupp
,
96 .vop_getextattr
= (void *)vop_eopnotsupp
,
97 .vop_setextattr
= (void *)vop_eopnotsupp
,
98 .vop_markatime
= vop_stdmarkatime
,
99 .vop_nresolve
= vop_compat_nresolve
,
100 .vop_nlookupdotdot
= vop_compat_nlookupdotdot
,
101 .vop_ncreate
= vop_compat_ncreate
,
102 .vop_nmkdir
= vop_compat_nmkdir
,
103 .vop_nmknod
= vop_compat_nmknod
,
104 .vop_nlink
= vop_compat_nlink
,
105 .vop_nsymlink
= vop_compat_nsymlink
,
106 .vop_nwhiteout
= vop_compat_nwhiteout
,
107 .vop_nremove
= vop_compat_nremove
,
108 .vop_nrmdir
= vop_compat_nrmdir
,
109 .vop_nrename
= vop_compat_nrename
,
110 .vop_mountctl
= journal_mountctl
113 VNODEOP_SET(default_vnode_vops
);
116 vop_eopnotsupp(struct vop_generic_args
*ap
)
122 vop_ebadf(struct vop_generic_args
*ap
)
128 vop_enotty(struct vop_generic_args
*ap
)
134 vop_einval(struct vop_generic_args
*ap
)
140 vop_stdmarkatime(struct vop_markatime_args
*ap
)
146 vop_null(struct vop_generic_args
*ap
)
152 vop_defaultop(struct vop_generic_args
*ap
)
154 return (VOCALL(&default_vnode_vops
, ap
));
158 vop_panic(struct vop_generic_args
*ap
)
160 panic("filesystem goof: vop_panic[%s]", ap
->a_desc
->sd_name
);
164 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
165 * XXX STOPGAP FUNCTION
167 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
168 * WILL BE REMOVED. This procedure exists for all VFSs which have not
169 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
170 * vop_old_lookup() and does appropriate translations.
172 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
173 * VFSs will support this VOP and this routine can be removed, since
174 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
177 * A locked ncp is passed in to be resolved. The NCP is resolved by
178 * figuring out the vnode (if any) and calling cache_setvp() to attach the
179 * vnode to the entry. If the entry represents a non-existant node then
180 * cache_setvp() is called with a NULL vnode to resolve the entry into a
181 * negative cache entry. No vnode locks are retained and the
182 * ncp is left locked on return.
184 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
186 * There is a potential directory and vnode interlock. The lock order
187 * requirement is: namecache, governing directory, resolved vnode.
190 vop_compat_nresolve(struct vop_nresolve_args
*ap
)
195 struct nchandle
*nch
;
196 struct namecache
*ncp
;
197 struct componentname cnp
;
199 nch
= ap
->a_nch
; /* locked namecache node */
204 * UFS currently stores all sorts of side effects, including a loop
205 * variable, in the directory inode. That needs to be fixed and the
206 * other VFS's audited before we can switch to LK_SHARED.
208 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
209 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
214 bzero(&cnp
, sizeof(cnp
));
215 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
217 cnp
.cn_nameptr
= ncp
->nc_name
;
218 cnp
.cn_namelen
= ncp
->nc_nlen
;
219 cnp
.cn_cred
= ap
->a_cred
;
220 cnp
.cn_td
= curthread
; /* XXX */
223 * vop_old_lookup() always returns vp locked. dvp may or may not be
224 * left locked depending on CNP_PDIRUNLOCK.
226 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
229 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
231 if ((ncp
->nc_flag
& NCF_UNRESOLVED
) == 0) {
232 /* was resolved by another process while we were unlocked */
235 } else if (error
== 0) {
236 KKASSERT(vp
!= NULL
);
237 cache_setvp(nch
, vp
);
239 } else if (error
== ENOENT
) {
240 KKASSERT(vp
== NULL
);
241 if (cnp
.cn_flags
& CNP_ISWHITEOUT
)
242 ncp
->nc_flag
|= NCF_WHITEOUT
;
243 cache_setvp(nch
, NULL
);
250 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
251 * struct vnode **a_vpp,
252 * struct ucred *a_cred }
254 * Lookup the vnode representing the parent directory of the specified
255 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
256 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
258 * This function is designed to aid NFS server-side operations and is
259 * used by cache_fromdvp() to create a consistent, connected namecache
262 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
263 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
264 * permits VFSs will implement the remaining *_n*() calls and finally get
265 * rid of their *_lookup() call.
268 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args
*ap
)
270 struct componentname cnp
;
274 * UFS currently stores all sorts of side effects, including a loop
275 * variable, in the directory inode. That needs to be fixed and the
276 * other VFS's audited before we can switch to LK_SHARED.
279 if ((error
= vget(ap
->a_dvp
, LK_EXCLUSIVE
)) != 0)
281 if (ap
->a_dvp
->v_type
!= VDIR
) {
286 bzero(&cnp
, sizeof(cnp
));
287 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
288 cnp
.cn_flags
= CNP_ISDOTDOT
;
289 cnp
.cn_nameptr
= "..";
291 cnp
.cn_cred
= ap
->a_cred
;
292 cnp
.cn_td
= curthread
; /* XXX */
295 * vop_old_lookup() always returns vp locked. dvp may or may not be
296 * left locked depending on CNP_PDIRUNLOCK.
298 error
= vop_old_lookup(ap
->a_head
.a_ops
, ap
->a_dvp
, ap
->a_vpp
, &cnp
);
300 vn_unlock(*ap
->a_vpp
);
301 if (cnp
.cn_flags
& CNP_PDIRUNLOCK
)
309 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
310 * struct vnode *a_dvp,
311 * struct vnode **a_vpp,
312 * struct ucred *a_cred,
313 * struct vattr *a_vap }
315 * Create a file as specified by a_vap. Compatibility requires us to issue
316 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
317 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
320 vop_compat_ncreate(struct vop_ncreate_args
*ap
)
322 struct thread
*td
= curthread
;
323 struct componentname cnp
;
324 struct nchandle
*nch
;
325 struct namecache
*ncp
;
330 * Sanity checks, get a locked directory vnode.
332 nch
= ap
->a_nch
; /* locked namecache node */
336 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
337 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
343 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
344 * caches all information required to create the entry in the
345 * directory inode. We expect a return code of EJUSTRETURN for
346 * the CREATE case. The cnp must simulated a saved-name situation.
348 bzero(&cnp
, sizeof(cnp
));
349 cnp
.cn_nameiop
= NAMEI_CREATE
;
350 cnp
.cn_flags
= CNP_LOCKPARENT
;
351 cnp
.cn_nameptr
= ncp
->nc_name
;
352 cnp
.cn_namelen
= ncp
->nc_nlen
;
353 cnp
.cn_cred
= ap
->a_cred
;
357 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
360 * EJUSTRETURN should be returned for this case, which means that
361 * the VFS has setup the directory inode for the create. The dvp we
362 * passed in is expected to remain in a locked state.
364 * If the VOP_OLD_CREATE is successful we are responsible for updating
365 * the cache state of the locked ncp that was passed to us.
367 if (error
== EJUSTRETURN
) {
368 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
369 error
= VOP_OLD_CREATE(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
371 cache_setunresolved(nch
);
372 cache_setvp(nch
, *ap
->a_vpp
);
380 KKASSERT(*ap
->a_vpp
== NULL
);
382 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
389 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
390 * struct vnode *a_dvp,
391 * struct vnode **a_vpp,
392 * struct ucred *a_cred,
393 * struct vattr *a_vap }
395 * Create a directory as specified by a_vap. Compatibility requires us to
396 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
397 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
400 vop_compat_nmkdir(struct vop_nmkdir_args
*ap
)
402 struct thread
*td
= curthread
;
403 struct componentname cnp
;
404 struct nchandle
*nch
;
405 struct namecache
*ncp
;
410 * Sanity checks, get a locked directory vnode.
412 nch
= ap
->a_nch
; /* locked namecache node */
415 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
416 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
422 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
423 * caches all information required to create the entry in the
424 * directory inode. We expect a return code of EJUSTRETURN for
425 * the CREATE case. The cnp must simulated a saved-name situation.
427 bzero(&cnp
, sizeof(cnp
));
428 cnp
.cn_nameiop
= NAMEI_CREATE
;
429 cnp
.cn_flags
= CNP_LOCKPARENT
;
430 cnp
.cn_nameptr
= ncp
->nc_name
;
431 cnp
.cn_namelen
= ncp
->nc_nlen
;
432 cnp
.cn_cred
= ap
->a_cred
;
436 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
439 * EJUSTRETURN should be returned for this case, which means that
440 * the VFS has setup the directory inode for the create. The dvp we
441 * passed in is expected to remain in a locked state.
443 * If the VOP_OLD_MKDIR is successful we are responsible for updating
444 * the cache state of the locked ncp that was passed to us.
446 if (error
== EJUSTRETURN
) {
447 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
448 error
= VOP_OLD_MKDIR(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
450 cache_setunresolved(nch
);
451 cache_setvp(nch
, *ap
->a_vpp
);
459 KKASSERT(*ap
->a_vpp
== NULL
);
461 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
468 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
469 * struct vnode *a_dvp,
470 * struct vnode **a_vpp,
471 * struct ucred *a_cred,
472 * struct vattr *a_vap }
474 * Create a device or fifo node as specified by a_vap. Compatibility requires
475 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
476 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
479 vop_compat_nmknod(struct vop_nmknod_args
*ap
)
481 struct thread
*td
= curthread
;
482 struct componentname cnp
;
483 struct nchandle
*nch
;
484 struct namecache
*ncp
;
489 * Sanity checks, get a locked directory vnode.
491 nch
= ap
->a_nch
; /* locked namecache node */
495 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
496 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
502 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
503 * caches all information required to create the entry in the
504 * directory inode. We expect a return code of EJUSTRETURN for
505 * the CREATE case. The cnp must simulated a saved-name situation.
507 bzero(&cnp
, sizeof(cnp
));
508 cnp
.cn_nameiop
= NAMEI_CREATE
;
509 cnp
.cn_flags
= CNP_LOCKPARENT
;
510 cnp
.cn_nameptr
= ncp
->nc_name
;
511 cnp
.cn_namelen
= ncp
->nc_nlen
;
512 cnp
.cn_cred
= ap
->a_cred
;
516 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
519 * EJUSTRETURN should be returned for this case, which means that
520 * the VFS has setup the directory inode for the create. The dvp we
521 * passed in is expected to remain in a locked state.
523 * If the VOP_OLD_MKNOD is successful we are responsible for updating
524 * the cache state of the locked ncp that was passed to us.
526 if (error
== EJUSTRETURN
) {
527 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
528 error
= VOP_OLD_MKNOD(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
530 cache_setunresolved(nch
);
531 cache_setvp(nch
, *ap
->a_vpp
);
539 KKASSERT(*ap
->a_vpp
== NULL
);
541 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
548 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
549 * struct vnode *a_dvp,
550 * struct vnode *a_vp,
551 * struct ucred *a_cred }
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 */
574 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
575 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
581 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
582 * caches all information required to create the entry in the
583 * directory inode. We expect a return code of EJUSTRETURN for
584 * the CREATE case. The cnp must simulated a saved-name situation.
586 bzero(&cnp
, sizeof(cnp
));
587 cnp
.cn_nameiop
= NAMEI_CREATE
;
588 cnp
.cn_flags
= CNP_LOCKPARENT
;
589 cnp
.cn_nameptr
= ncp
->nc_name
;
590 cnp
.cn_namelen
= ncp
->nc_nlen
;
591 cnp
.cn_cred
= ap
->a_cred
;
595 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &tvp
, &cnp
);
598 * EJUSTRETURN should be returned for this case, which means that
599 * the VFS has setup the directory inode for the create. The dvp we
600 * passed in is expected to remain in a locked state.
602 * If the VOP_OLD_LINK is successful we are responsible for updating
603 * the cache state of the locked ncp that was passed to us.
605 if (error
== EJUSTRETURN
) {
606 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
607 error
= VOP_OLD_LINK(dvp
, ap
->a_vp
, &cnp
);
609 cache_setunresolved(nch
);
610 cache_setvp(nch
, ap
->a_vp
);
618 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
625 vop_compat_nsymlink(struct vop_nsymlink_args
*ap
)
627 struct thread
*td
= curthread
;
628 struct componentname cnp
;
629 struct nchandle
*nch
;
630 struct namecache
*ncp
;
636 * Sanity checks, get a locked directory vnode.
639 nch
= ap
->a_nch
; /* locked namecache node */
643 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
644 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
650 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
651 * caches all information required to create the entry in the
652 * directory inode. We expect a return code of EJUSTRETURN for
653 * the CREATE case. The cnp must simulated a saved-name situation.
655 bzero(&cnp
, sizeof(cnp
));
656 cnp
.cn_nameiop
= NAMEI_CREATE
;
657 cnp
.cn_flags
= CNP_LOCKPARENT
;
658 cnp
.cn_nameptr
= ncp
->nc_name
;
659 cnp
.cn_namelen
= ncp
->nc_nlen
;
660 cnp
.cn_cred
= ap
->a_cred
;
664 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
667 * EJUSTRETURN should be returned for this case, which means that
668 * the VFS has setup the directory inode for the create. The dvp we
669 * passed in is expected to remain in a locked state.
671 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
672 * the cache state of the locked ncp that was passed to us.
674 if (error
== EJUSTRETURN
) {
675 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
676 error
= VOP_OLD_SYMLINK(dvp
, &vp
, &cnp
, ap
->a_vap
, ap
->a_target
);
678 cache_setunresolved(nch
);
679 cache_setvp(nch
, vp
);
688 KKASSERT(vp
== NULL
);
690 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
697 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
698 * struct vnode *a_dvp,
699 * struct ucred *a_cred,
702 * Issie a whiteout operation (create, lookup, or delete). Compatibility
703 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
704 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
705 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
706 * no lookup is necessary.
709 vop_compat_nwhiteout(struct vop_nwhiteout_args
*ap
)
711 struct thread
*td
= curthread
;
712 struct componentname cnp
;
713 struct nchandle
*nch
;
714 struct namecache
*ncp
;
720 * Sanity checks, get a locked directory vnode.
722 nch
= ap
->a_nch
; /* locked namecache node */
726 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
727 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
733 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
734 * caches all information required to create the entry in the
735 * directory inode. We expect a return code of EJUSTRETURN for
736 * the CREATE case. The cnp must simulated a saved-name situation.
738 bzero(&cnp
, sizeof(cnp
));
739 cnp
.cn_nameiop
= ap
->a_flags
;
740 cnp
.cn_flags
= CNP_LOCKPARENT
;
741 cnp
.cn_nameptr
= ncp
->nc_name
;
742 cnp
.cn_namelen
= ncp
->nc_nlen
;
743 cnp
.cn_cred
= ap
->a_cred
;
749 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
750 * The VFS has setup the directory inode for the create. The dvp we
751 * passed in is expected to remain in a locked state.
753 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
754 * the cache state of the locked ncp that was passed to us.
756 switch(ap
->a_flags
) {
758 cnp
.cn_flags
|= CNP_DOWHITEOUT
;
761 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
762 if (error
== EJUSTRETURN
) {
763 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
764 error
= VOP_OLD_WHITEOUT(dvp
, &cnp
, ap
->a_flags
);
766 cache_setunresolved(nch
);
773 KKASSERT(vp
== NULL
);
777 error
= VOP_OLD_WHITEOUT(dvp
, NULL
, ap
->a_flags
);
783 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
791 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
792 * struct vnode *a_dvp,
793 * struct ucred *a_cred }
796 vop_compat_nremove(struct vop_nremove_args
*ap
)
798 struct thread
*td
= curthread
;
799 struct componentname cnp
;
800 struct nchandle
*nch
;
801 struct namecache
*ncp
;
807 * Sanity checks, get a locked directory vnode.
809 nch
= ap
->a_nch
; /* locked namecache node */
813 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
814 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
820 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
821 * caches all information required to delete the entry in the
822 * directory inode. We expect a return code of 0 for the DELETE
823 * case (meaning that a vp has been found). The cnp must simulated
824 * a saved-name situation.
826 bzero(&cnp
, sizeof(cnp
));
827 cnp
.cn_nameiop
= NAMEI_DELETE
;
828 cnp
.cn_flags
= CNP_LOCKPARENT
;
829 cnp
.cn_nameptr
= ncp
->nc_name
;
830 cnp
.cn_namelen
= ncp
->nc_nlen
;
831 cnp
.cn_cred
= ap
->a_cred
;
835 * The vnode must be a directory and must not represent the
839 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
840 if (error
== 0 && vp
->v_type
== VDIR
)
843 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
844 error
= VOP_OLD_REMOVE(dvp
, vp
, &cnp
);
846 cache_setunresolved(nch
);
847 cache_setvp(nch
, NULL
);
848 cache_inval_vp(vp
, CINV_DESTROY
);
857 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
864 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
866 * struct ucred *a_cred }
869 vop_compat_nrmdir(struct vop_nrmdir_args
*ap
)
871 struct thread
*td
= curthread
;
872 struct componentname cnp
;
873 struct nchandle
*nch
;
874 struct namecache
*ncp
;
880 * Sanity checks, get a locked directory vnode.
882 nch
= ap
->a_nch
; /* locked namecache node */
886 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
887 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
893 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
894 * caches all information required to delete the entry in the
895 * directory inode. We expect a return code of 0 for the DELETE
896 * case (meaning that a vp has been found). The cnp must simulated
897 * a saved-name situation.
899 bzero(&cnp
, sizeof(cnp
));
900 cnp
.cn_nameiop
= NAMEI_DELETE
;
901 cnp
.cn_flags
= CNP_LOCKPARENT
;
902 cnp
.cn_nameptr
= ncp
->nc_name
;
903 cnp
.cn_namelen
= ncp
->nc_nlen
;
904 cnp
.cn_cred
= ap
->a_cred
;
908 * The vnode must be a directory and must not represent the
912 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
913 if (error
== 0 && vp
->v_type
!= VDIR
)
915 if (error
== 0 && vp
== dvp
)
917 if (error
== 0 && (vp
->v_flag
& VROOT
))
920 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
921 error
= VOP_OLD_RMDIR(dvp
, vp
, &cnp
);
924 * Note that this invalidation will cause any process
925 * currently CD'd into the directory being removed to be
926 * disconnected from the topology and not be able to ".."
930 cache_inval(nch
, CINV_DESTROY
);
931 cache_inval_vp(vp
, CINV_DESTROY
);
940 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
947 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
948 * struct nchandle *a_tnch,
949 * struct ucred *a_cred }
951 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
952 * the source directory and vnode be unlocked and the target directory and
953 * vnode (if it exists) be locked. All arguments will be vrele'd and
954 * the targets will also be unlocked regardless of the return code.
957 vop_compat_nrename(struct vop_nrename_args
*ap
)
959 struct thread
*td
= curthread
;
960 struct componentname fcnp
;
961 struct componentname tcnp
;
962 struct nchandle
*fnch
;
963 struct nchandle
*tnch
;
964 struct namecache
*fncp
;
965 struct namecache
*tncp
;
966 struct vnode
*fdvp
, *fvp
;
967 struct vnode
*tdvp
, *tvp
;
971 * Sanity checks, get referenced vnodes representing the source.
973 fnch
= ap
->a_fnch
; /* locked namecache node */
978 * Temporarily lock the source directory and lookup in DELETE mode to
979 * check permissions. XXX delete permissions should have been
980 * checked by nlookup(), we need to add NLC_DELETE for delete
981 * checking. It is unclear whether VFS's require the directory setup
982 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
983 * since it isn't locked and since UFS always does a relookup of
984 * the source, it is believed that the only side effect that matters
985 * is the permissions check.
987 if ((error
= vget(fdvp
, LK_EXCLUSIVE
)) != 0) {
988 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
989 fncp
, fncp
->nc_name
);
993 bzero(&fcnp
, sizeof(fcnp
));
994 fcnp
.cn_nameiop
= NAMEI_DELETE
;
995 fcnp
.cn_flags
= CNP_LOCKPARENT
;
996 fcnp
.cn_nameptr
= fncp
->nc_name
;
997 fcnp
.cn_namelen
= fncp
->nc_nlen
;
998 fcnp
.cn_cred
= ap
->a_cred
;
1002 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1006 error
= vop_old_lookup(ap
->a_head
.a_ops
, fdvp
, &fvp
, &fcnp
);
1007 if (error
== 0 && (fvp
->v_flag
& VROOT
)) {
1008 vput(fvp
); /* as if vop_old_lookup had failed */
1011 if ((fcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0) {
1012 fcnp
.cn_flags
|= CNP_PDIRUNLOCK
;
1022 * fdvp and fvp are now referenced and unlocked.
1024 * Get a locked directory vnode for the target and lookup the target
1025 * in CREATE mode so it places the required information in the
1028 tnch
= ap
->a_tnch
; /* locked namecache node */
1036 if ((error
= vget(tdvp
, LK_EXCLUSIVE
)) != 0) {
1037 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1038 tncp
, tncp
->nc_name
);
1045 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1046 * caches all information required to create the entry in the
1047 * target directory inode.
1049 bzero(&tcnp
, sizeof(tcnp
));
1050 tcnp
.cn_nameiop
= NAMEI_RENAME
;
1051 tcnp
.cn_flags
= CNP_LOCKPARENT
;
1052 tcnp
.cn_nameptr
= tncp
->nc_name
;
1053 tcnp
.cn_namelen
= tncp
->nc_nlen
;
1054 tcnp
.cn_cred
= ap
->a_cred
;
1058 error
= vop_old_lookup(ap
->a_head
.a_ops
, tdvp
, &tvp
, &tcnp
);
1060 if (error
== EJUSTRETURN
) {
1062 * Target does not exist. tvp should be NULL.
1064 KKASSERT(tvp
== NULL
);
1065 KKASSERT((tcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
1066 error
= VOP_OLD_RENAME(fdvp
, fvp
, &fcnp
, tdvp
, tvp
, &tcnp
);
1068 cache_rename(fnch
, tnch
);
1069 } else if (error
== 0) {
1071 * Target exists. VOP_OLD_RENAME should correctly delete the
1074 KKASSERT((tcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
1075 error
= VOP_OLD_RENAME(fdvp
, fvp
, &fcnp
, tdvp
, tvp
, &tcnp
);
1077 cache_rename(fnch
, tnch
);
1081 if (tcnp
.cn_flags
& CNP_PDIRUNLOCK
)
1090 vop_nolookup(struct vop_old_lookup_args
*ap
)
1100 * Strategy routine for VFS devices that have none.
1102 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1103 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1104 * Typically B_INVAL is assumed to already be clear prior to a write
1105 * and should not be cleared manually unless you just made the buffer
1106 * invalid. B_ERROR should be cleared either way.
1110 vop_nostrategy (struct vop_strategy_args
*ap
)
1112 kprintf("No strategy for buffer at %p\n", ap
->a_bio
->bio_buf
);
1113 vprint("", ap
->a_vp
);
1114 ap
->a_bio
->bio_buf
->b_flags
|= B_ERROR
;
1115 ap
->a_bio
->bio_buf
->b_error
= EOPNOTSUPP
;
1117 return (EOPNOTSUPP
);
1121 vop_stdpathconf(struct vop_pathconf_args
*ap
)
1125 switch (ap
->a_name
) {
1127 *ap
->a_retval
= LINK_MAX
;
1130 *ap
->a_retval
= NAME_MAX
;
1133 *ap
->a_retval
= PATH_MAX
;
1136 *ap
->a_retval
= MAX_CANON
;
1139 *ap
->a_retval
= MAX_INPUT
;
1142 *ap
->a_retval
= PIPE_BUF
;
1144 case _PC_CHOWN_RESTRICTED
:
1151 *ap
->a_retval
= _POSIX_VDISABLE
;
1163 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
1165 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1168 vop_stdopen(struct vop_open_args
*ap
)
1170 struct vnode
*vp
= ap
->a_vp
;
1173 if ((fp
= ap
->a_fp
) != NULL
) {
1174 switch(vp
->v_type
) {
1176 fp
->f_type
= DTYPE_FIFO
;
1179 fp
->f_type
= DTYPE_VNODE
;
1182 fp
->f_flag
= ap
->a_mode
& FMASK
;
1183 fp
->f_ops
= &vnode_fileops
;
1187 if (ap
->a_mode
& FWRITE
)
1189 KKASSERT(vp
->v_opencount
>= 0 && vp
->v_opencount
!= INT_MAX
);
1197 * (struct vnode *a_vp, int a_fflag)
1199 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1202 vop_stdclose(struct vop_close_args
*ap
)
1204 struct vnode
*vp
= ap
->a_vp
;
1206 KASSERT(vp
->v_opencount
> 0,
1207 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x\n",
1208 vp
, vp
->v_opencount
, vp
->v_type
, *vp
->v_ops
, vp
->v_flag
));
1209 if (ap
->a_fflag
& FWRITE
) {
1210 KASSERT(vp
->v_writecount
> 0,
1211 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1212 vp
, vp
->v_writecount
));
1220 * Return true for select/poll.
1223 vop_nopoll(struct vop_poll_args
*ap
)
1226 * Return true for read/write. If the user asked for something
1227 * special, return POLLNVAL, so that clients have a way of
1228 * determining reliably whether or not the extended
1229 * functionality is present without hard-coding knowledge
1230 * of specific filesystem implementations.
1232 if (ap
->a_events
& ~POLLSTANDARD
)
1235 return (ap
->a_events
& (POLLIN
| POLLOUT
| POLLRDNORM
| POLLWRNORM
));
1239 * Implement poll for local filesystems that support it.
1242 vop_stdpoll(struct vop_poll_args
*ap
)
1244 if (ap
->a_events
& ~POLLSTANDARD
)
1245 return (vn_pollrecord(ap
->a_vp
, ap
->a_events
));
1246 return (ap
->a_events
& (POLLIN
| POLLOUT
| POLLRDNORM
| POLLWRNORM
));
1250 * Implement standard getpages and putpages. All filesystems must use
1251 * the buffer cache to back regular files.
1254 vop_stdgetpages(struct vop_getpages_args
*ap
)
1259 if ((mp
= ap
->a_vp
->v_mount
) != NULL
) {
1260 error
= vnode_pager_generic_getpages(
1261 ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1264 error
= VM_PAGER_BAD
;
1270 vop_stdputpages(struct vop_putpages_args
*ap
)
1275 if ((mp
= ap
->a_vp
->v_mount
) != NULL
) {
1276 error
= vnode_pager_generic_putpages(
1277 ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1278 ap
->a_sync
, ap
->a_rtvals
);
1280 error
= VM_PAGER_BAD
;
1287 * used to fill the vfs fucntion table to get reasonable default return values.
1290 vfs_stdmount(struct mount
*mp
, char *path
, caddr_t data
, struct ucred
*cred
)
1296 vfs_stdunmount(struct mount
*mp
, int mntflags
)
1302 vfs_stdroot(struct mount
*mp
, struct vnode
**vpp
)
1304 return (EOPNOTSUPP
);
1308 vfs_stdstatfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
1310 return (EOPNOTSUPP
);
1314 * If the VFS does not implement statvfs, then call statfs and convert
1315 * the values. This code was taken from libc's __cvtstatvfs() function,
1316 * contributed by Joerg Sonnenberger.
1319 vfs_stdstatvfs(struct mount
*mp
, struct statvfs
*sbp
, struct ucred
*cred
)
1325 error
= VFS_STATFS(mp
, in
, cred
);
1327 bzero(sbp
, sizeof(*sbp
));
1329 sbp
->f_bsize
= in
->f_bsize
;
1330 sbp
->f_frsize
= in
->f_bsize
;
1331 sbp
->f_blocks
= in
->f_blocks
;
1332 sbp
->f_bfree
= in
->f_bfree
;
1333 sbp
->f_bavail
= in
->f_bavail
;
1334 sbp
->f_files
= in
->f_files
;
1335 sbp
->f_ffree
= in
->f_ffree
;
1339 * This field counts the number of available inodes to non-root
1340 * users, but this information is not available via statfs.
1341 * Just ignore this issue by returning the total number
1344 sbp
->f_favail
= in
->f_ffree
;
1348 * This field has a different meaning for statfs and statvfs.
1349 * For the former it is the cookie exported for NFS and not
1350 * intended for normal userland use.
1355 if (in
->f_flags
& MNT_RDONLY
)
1356 sbp
->f_flag
|= ST_RDONLY
;
1357 if (in
->f_flags
& MNT_NOSUID
)
1358 sbp
->f_flag
|= ST_NOSUID
;
1360 sbp
->f_owner
= in
->f_owner
;
1363 * statfs contains the type as string, statvfs expects it as
1368 sbp
->f_syncreads
= in
->f_syncreads
;
1369 sbp
->f_syncwrites
= in
->f_syncwrites
;
1370 sbp
->f_asyncreads
= in
->f_asyncreads
;
1371 sbp
->f_asyncwrites
= in
->f_asyncwrites
;
1377 vfs_stdvptofh(struct vnode
*vp
, struct fid
*fhp
)
1379 return (EOPNOTSUPP
);
1383 vfs_stdstart(struct mount
*mp
, int flags
)
1389 vfs_stdquotactl(struct mount
*mp
, int cmds
, uid_t uid
,
1390 caddr_t arg
, struct ucred
*cred
)
1392 return (EOPNOTSUPP
);
1396 vfs_stdsync(struct mount
*mp
, int waitfor
)
1402 vfs_stdnosync(struct mount
*mp
, int waitfor
)
1404 return (EOPNOTSUPP
);
1408 vfs_stdvget(struct mount
*mp
, ino_t ino
, struct vnode
**vpp
)
1410 return (EOPNOTSUPP
);
1414 vfs_stdfhtovp(struct mount
*mp
, struct vnode
*rootvp
,
1415 struct fid
*fhp
, struct vnode
**vpp
)
1417 return (EOPNOTSUPP
);
1421 vfs_stdcheckexp(struct mount
*mp
, struct sockaddr
*nam
, int *extflagsp
,
1422 struct ucred
**credanonp
)
1424 return (EOPNOTSUPP
);
1428 vfs_stdinit(struct vfsconf
*vfsp
)
1434 vfs_stduninit(struct vfsconf
*vfsp
)
1440 vfs_stdextattrctl(struct mount
*mp
, int cmd
, const char *attrname
,
1441 caddr_t arg
, struct ucred
*cred
)
1446 /* end of vfs default ops */