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. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
36 * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $
39 #include <sys/param.h>
40 #include <sys/systm.h>
43 #include <sys/fcntl.h>
45 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/mount.h>
49 #include <sys/unistd.h>
50 #include <sys/vnode.h>
51 #include <sys/namei.h>
52 #include <sys/mountctl.h>
53 #include <sys/vfs_quota.h>
56 #include <machine/limits.h>
59 #include <vm/vm_object.h>
60 #include <vm/vm_page.h>
61 #include <vm/vm_pager.h>
62 #include <vm/vnode_pager.h>
64 static int vop_nolookup (struct vop_old_lookup_args
*);
65 static int vop_nostrategy (struct vop_strategy_args
*);
68 * This vnode table stores what we want to do if the filesystem doesn't
69 * implement a particular VOP.
71 * If there is no specific entry here, we will return EOPNOTSUPP.
73 struct vop_ops default_vnode_vops
= {
74 .vop_default
= vop_eopnotsupp
,
75 .vop_advlock
= (void *)vop_einval
,
76 .vop_fsync
= (void *)vop_null
,
77 .vop_fdatasync
= vop_stdfdatasync
,
78 .vop_ioctl
= (void *)vop_enotty
,
79 .vop_mmap
= (void *)vop_einval
,
80 .vop_old_lookup
= vop_nolookup
,
81 .vop_open
= vop_stdopen
,
82 .vop_close
= vop_stdclose
,
83 .vop_getattr_lite
= vop_stdgetattr_lite
,
84 .vop_pathconf
= vop_stdpathconf
,
85 .vop_readlink
= (void *)vop_einval
,
86 .vop_reallocblks
= (void *)vop_eopnotsupp
,
87 .vop_strategy
= vop_nostrategy
,
88 .vop_getacl
= (void *)vop_eopnotsupp
,
89 .vop_setacl
= (void *)vop_eopnotsupp
,
90 .vop_aclcheck
= (void *)vop_eopnotsupp
,
91 .vop_getextattr
= (void *)vop_eopnotsupp
,
92 .vop_setextattr
= (void *)vop_eopnotsupp
,
93 .vop_markatime
= vop_stdmarkatime
,
94 .vop_allocate
= vop_stdallocate
,
95 .vop_nresolve
= vop_compat_nresolve
,
96 .vop_nlookupdotdot
= vop_compat_nlookupdotdot
,
97 .vop_ncreate
= vop_compat_ncreate
,
98 .vop_nmkdir
= vop_compat_nmkdir
,
99 .vop_nmknod
= vop_compat_nmknod
,
100 .vop_nlink
= vop_compat_nlink
,
101 .vop_nsymlink
= vop_compat_nsymlink
,
102 .vop_nwhiteout
= vop_compat_nwhiteout
,
103 .vop_nremove
= vop_compat_nremove
,
104 .vop_nrmdir
= vop_compat_nrmdir
,
105 .vop_nrename
= vop_compat_nrename
,
106 .vop_mountctl
= vop_stdmountctl
109 VNODEOP_SET(default_vnode_vops
);
112 vop_eopnotsupp(struct vop_generic_args
*ap
)
118 vop_ebadf(struct vop_generic_args
*ap
)
124 vop_enotty(struct vop_generic_args
*ap
)
130 vop_einval(struct vop_generic_args
*ap
)
136 vop_stdmarkatime(struct vop_markatime_args
*ap
)
142 vop_null(struct vop_generic_args
*ap
)
148 vop_defaultop(struct vop_generic_args
*ap
)
150 return (VOCALL(&default_vnode_vops
, ap
));
154 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
155 * XXX STOPGAP FUNCTION
157 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
158 * WILL BE REMOVED. This procedure exists for all VFSs which have not
159 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
160 * vop_old_lookup() and does appropriate translations.
162 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
163 * VFSs will support this VOP and this routine can be removed, since
164 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
167 * A locked ncp is passed in to be resolved. The NCP is resolved by
168 * figuring out the vnode (if any) and calling cache_setvp() to attach the
169 * vnode to the entry. If the entry represents a non-existant node then
170 * cache_setvp() is called with a NULL vnode to resolve the entry into a
171 * negative cache entry. No vnode locks are retained and the
172 * ncp is left locked on return.
174 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
176 * There is a potential directory and vnode interlock. The lock order
177 * requirement is: namecache, governing directory, resolved vnode.
180 vop_compat_nresolve(struct vop_nresolve_args
*ap
)
185 struct nchandle
*nch
;
186 struct namecache
*ncp
;
187 struct componentname cnp
;
189 nch
= ap
->a_nch
; /* locked namecache node */
194 * UFS currently stores all sorts of side effects, including a loop
195 * variable, in the directory inode. That needs to be fixed and the
196 * other VFS's audited before we can switch to LK_SHARED.
198 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
199 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
204 bzero(&cnp
, sizeof(cnp
));
205 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
207 cnp
.cn_nameptr
= ncp
->nc_name
;
208 cnp
.cn_namelen
= ncp
->nc_nlen
;
209 cnp
.cn_cred
= ap
->a_cred
;
210 cnp
.cn_td
= curthread
; /* XXX */
213 * vop_old_lookup() always returns vp locked. dvp may or may not be
214 * left locked depending on CNP_PDIRUNLOCK.
216 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
219 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
221 if ((ncp
->nc_flag
& NCF_UNRESOLVED
) == 0) {
222 /* was resolved by another process while we were unlocked */
225 } else if (error
== 0) {
226 KKASSERT(vp
!= NULL
);
227 cache_setvp(nch
, vp
);
229 } else if (error
== ENOENT
) {
230 KKASSERT(vp
== NULL
);
231 if (cnp
.cn_flags
& CNP_ISWHITEOUT
)
232 ncp
->nc_flag
|= NCF_WHITEOUT
;
233 cache_setvp(nch
, NULL
);
240 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
241 * struct vnode **a_vpp,
242 * struct ucred *a_cred }
244 * Lookup the vnode representing the parent directory of the specified
245 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
246 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
248 * This function is designed to aid NFS server-side operations and is
249 * used by cache_fromdvp() to create a consistent, connected namecache
252 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
253 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
254 * permits VFSs will implement the remaining *_n*() calls and finally get
255 * rid of their *_lookup() call.
258 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args
*ap
)
260 struct componentname cnp
;
264 * UFS currently stores all sorts of side effects, including a loop
265 * variable, in the directory inode. That needs to be fixed and the
266 * other VFS's audited before we can switch to LK_SHARED.
269 if ((error
= vget(ap
->a_dvp
, LK_EXCLUSIVE
)) != 0)
271 if (ap
->a_dvp
->v_type
!= VDIR
) {
276 bzero(&cnp
, sizeof(cnp
));
277 cnp
.cn_nameiop
= NAMEI_LOOKUP
;
278 cnp
.cn_flags
= CNP_ISDOTDOT
;
279 cnp
.cn_nameptr
= "..";
281 cnp
.cn_cred
= ap
->a_cred
;
282 cnp
.cn_td
= curthread
; /* XXX */
285 * vop_old_lookup() always returns vp locked. dvp may or may not be
286 * left locked depending on CNP_PDIRUNLOCK.
288 * (*vpp) will be returned locked if no error occured, which is the
291 error
= vop_old_lookup(ap
->a_head
.a_ops
, ap
->a_dvp
, ap
->a_vpp
, &cnp
);
292 if (cnp
.cn_flags
& CNP_PDIRUNLOCK
)
300 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
301 * struct vnode *a_dvp,
302 * struct vnode **a_vpp,
303 * struct ucred *a_cred,
304 * struct vattr *a_vap }
306 * Create a file as specified by a_vap. Compatibility requires us to issue
307 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
308 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
311 vop_compat_ncreate(struct vop_ncreate_args
*ap
)
313 struct thread
*td
= curthread
;
314 struct componentname cnp
;
315 struct nchandle
*nch
;
316 struct namecache
*ncp
;
321 * Sanity checks, get a locked directory vnode.
323 nch
= ap
->a_nch
; /* locked namecache node */
327 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
328 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
334 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
335 * caches all information required to create the entry in the
336 * directory inode. We expect a return code of EJUSTRETURN for
337 * the CREATE case. The cnp must simulated a saved-name situation.
339 bzero(&cnp
, sizeof(cnp
));
340 cnp
.cn_nameiop
= NAMEI_CREATE
;
341 cnp
.cn_flags
= CNP_LOCKPARENT
;
342 cnp
.cn_nameptr
= ncp
->nc_name
;
343 cnp
.cn_namelen
= ncp
->nc_nlen
;
344 cnp
.cn_cred
= ap
->a_cred
;
348 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
351 * EJUSTRETURN should be returned for this case, which means that
352 * the VFS has setup the directory inode for the create. The dvp we
353 * passed in is expected to remain in a locked state.
355 * If the VOP_OLD_CREATE is successful we are responsible for updating
356 * the cache state of the locked ncp that was passed to us.
358 if (error
== EJUSTRETURN
) {
359 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
360 error
= VOP_OLD_CREATE(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
362 cache_setunresolved(nch
);
363 cache_setvp(nch
, *ap
->a_vpp
);
371 KKASSERT(*ap
->a_vpp
== NULL
);
373 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
380 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
381 * struct vnode *a_dvp,
382 * struct vnode **a_vpp,
383 * struct ucred *a_cred,
384 * struct vattr *a_vap }
386 * Create a directory as specified by a_vap. Compatibility requires us to
387 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
388 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
391 vop_compat_nmkdir(struct vop_nmkdir_args
*ap
)
393 struct thread
*td
= curthread
;
394 struct componentname cnp
;
395 struct nchandle
*nch
;
396 struct namecache
*ncp
;
401 * Sanity checks, get a locked directory vnode.
403 nch
= ap
->a_nch
; /* locked namecache node */
406 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
407 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
413 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
414 * caches all information required to create the entry in the
415 * directory inode. We expect a return code of EJUSTRETURN for
416 * the CREATE case. The cnp must simulated a saved-name situation.
418 bzero(&cnp
, sizeof(cnp
));
419 cnp
.cn_nameiop
= NAMEI_CREATE
;
420 cnp
.cn_flags
= CNP_LOCKPARENT
;
421 cnp
.cn_nameptr
= ncp
->nc_name
;
422 cnp
.cn_namelen
= ncp
->nc_nlen
;
423 cnp
.cn_cred
= ap
->a_cred
;
427 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
430 * EJUSTRETURN should be returned for this case, which means that
431 * the VFS has setup the directory inode for the create. The dvp we
432 * passed in is expected to remain in a locked state.
434 * If the VOP_OLD_MKDIR is successful we are responsible for updating
435 * the cache state of the locked ncp that was passed to us.
437 if (error
== EJUSTRETURN
) {
438 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
439 error
= VOP_OLD_MKDIR(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
441 cache_setunresolved(nch
);
442 cache_setvp(nch
, *ap
->a_vpp
);
450 KKASSERT(*ap
->a_vpp
== NULL
);
452 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
459 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
460 * struct vnode *a_dvp,
461 * struct vnode **a_vpp,
462 * struct ucred *a_cred,
463 * struct vattr *a_vap }
465 * Create a device or fifo node as specified by a_vap. Compatibility requires
466 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
467 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
470 vop_compat_nmknod(struct vop_nmknod_args
*ap
)
472 struct thread
*td
= curthread
;
473 struct componentname cnp
;
474 struct nchandle
*nch
;
475 struct namecache
*ncp
;
480 * Sanity checks, get a locked directory vnode.
482 nch
= ap
->a_nch
; /* locked namecache node */
486 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
487 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
493 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
494 * caches all information required to create the entry in the
495 * directory inode. We expect a return code of EJUSTRETURN for
496 * the CREATE case. The cnp must simulated a saved-name situation.
498 bzero(&cnp
, sizeof(cnp
));
499 cnp
.cn_nameiop
= NAMEI_CREATE
;
500 cnp
.cn_flags
= CNP_LOCKPARENT
;
501 cnp
.cn_nameptr
= ncp
->nc_name
;
502 cnp
.cn_namelen
= ncp
->nc_nlen
;
503 cnp
.cn_cred
= ap
->a_cred
;
507 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, ap
->a_vpp
, &cnp
);
510 * EJUSTRETURN should be returned for this case, which means that
511 * the VFS has setup the directory inode for the create. The dvp we
512 * passed in is expected to remain in a locked state.
514 * If the VOP_OLD_MKNOD is successful we are responsible for updating
515 * the cache state of the locked ncp that was passed to us.
517 if (error
== EJUSTRETURN
) {
518 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
519 error
= VOP_OLD_MKNOD(dvp
, ap
->a_vpp
, &cnp
, ap
->a_vap
);
521 cache_setunresolved(nch
);
522 cache_setvp(nch
, *ap
->a_vpp
);
530 KKASSERT(*ap
->a_vpp
== NULL
);
532 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
539 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
540 * struct vnode *a_dvp,
541 * struct vnode *a_vp,
542 * struct ucred *a_cred }
544 * The passed vp is locked and represents the source. The passed ncp is
545 * locked and represents the target to create.
548 vop_compat_nlink(struct vop_nlink_args
*ap
)
550 struct thread
*td
= curthread
;
551 struct componentname cnp
;
552 struct nchandle
*nch
;
553 struct namecache
*ncp
;
559 * Sanity checks, get a locked directory vnode.
561 nch
= ap
->a_nch
; /* locked namecache node */
565 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
566 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
572 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
573 * caches all information required to create the entry in the
574 * directory inode. We expect a return code of EJUSTRETURN for
575 * the CREATE case. The cnp must simulated a saved-name situation.
577 * It should not be possible for there to be a vnode collision
578 * between the source vp and target (name lookup). However NFS
579 * clients racing each other can cause NFS to alias the same vnode
580 * across several names without the rest of the system knowing it.
581 * Use CNP_NOTVP to avoid a panic in this situation.
583 bzero(&cnp
, sizeof(cnp
));
584 cnp
.cn_nameiop
= NAMEI_CREATE
;
585 cnp
.cn_flags
= CNP_LOCKPARENT
| CNP_NOTVP
;
586 cnp
.cn_nameptr
= ncp
->nc_name
;
587 cnp
.cn_namelen
= ncp
->nc_nlen
;
588 cnp
.cn_cred
= ap
->a_cred
;
590 cnp
.cn_notvp
= ap
->a_vp
;
593 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &tvp
, &cnp
);
596 * EJUSTRETURN should be returned for this case, which means that
597 * the VFS has setup the directory inode for the create. The dvp we
598 * passed in is expected to remain in a locked state.
600 * If the VOP_OLD_LINK is successful we are responsible for updating
601 * the cache state of the locked ncp that was passed to us.
603 if (error
== EJUSTRETURN
) {
604 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
605 error
= VOP_OLD_LINK(dvp
, ap
->a_vp
, &cnp
);
607 cache_setunresolved(nch
);
608 cache_setvp(nch
, ap
->a_vp
);
616 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
623 vop_compat_nsymlink(struct vop_nsymlink_args
*ap
)
625 struct thread
*td
= curthread
;
626 struct componentname cnp
;
627 struct nchandle
*nch
;
628 struct namecache
*ncp
;
634 * Sanity checks, get a locked directory vnode.
637 nch
= ap
->a_nch
; /* locked namecache node */
641 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
642 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
648 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
649 * caches all information required to create the entry in the
650 * directory inode. We expect a return code of EJUSTRETURN for
651 * the CREATE case. The cnp must simulated a saved-name situation.
653 bzero(&cnp
, sizeof(cnp
));
654 cnp
.cn_nameiop
= NAMEI_CREATE
;
655 cnp
.cn_flags
= CNP_LOCKPARENT
;
656 cnp
.cn_nameptr
= ncp
->nc_name
;
657 cnp
.cn_namelen
= ncp
->nc_nlen
;
658 cnp
.cn_cred
= ap
->a_cred
;
662 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
665 * EJUSTRETURN should be returned for this case, which means that
666 * the VFS has setup the directory inode for the create. The dvp we
667 * passed in is expected to remain in a locked state.
669 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
670 * the cache state of the locked ncp that was passed to us.
672 if (error
== EJUSTRETURN
) {
673 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
674 error
= VOP_OLD_SYMLINK(dvp
, &vp
, &cnp
, ap
->a_vap
, ap
->a_target
);
676 cache_setunresolved(nch
);
677 cache_setvp(nch
, vp
);
686 KKASSERT(vp
== NULL
);
688 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
695 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
696 * struct vnode *a_dvp,
697 * struct ucred *a_cred,
700 * Issie a whiteout operation (create, lookup, or delete). Compatibility
701 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
702 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
703 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
704 * no lookup is necessary.
707 vop_compat_nwhiteout(struct vop_nwhiteout_args
*ap
)
709 struct thread
*td
= curthread
;
710 struct componentname cnp
;
711 struct nchandle
*nch
;
712 struct namecache
*ncp
;
718 * Sanity checks, get a locked directory vnode.
720 nch
= ap
->a_nch
; /* locked namecache node */
724 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
725 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
731 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
732 * caches all information required to create the entry in the
733 * directory inode. We expect a return code of EJUSTRETURN for
734 * the CREATE case. The cnp must simulated a saved-name situation.
736 bzero(&cnp
, sizeof(cnp
));
737 cnp
.cn_nameiop
= ap
->a_flags
;
738 cnp
.cn_flags
= CNP_LOCKPARENT
;
739 cnp
.cn_nameptr
= ncp
->nc_name
;
740 cnp
.cn_namelen
= ncp
->nc_nlen
;
741 cnp
.cn_cred
= ap
->a_cred
;
747 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
748 * The VFS has setup the directory inode for the create. The dvp we
749 * passed in is expected to remain in a locked state.
751 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
752 * the cache state of the locked ncp that was passed to us.
754 switch(ap
->a_flags
) {
756 cnp
.cn_flags
|= CNP_DOWHITEOUT
;
759 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
760 if (error
== EJUSTRETURN
) {
761 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
762 error
= VOP_OLD_WHITEOUT(dvp
, &cnp
, ap
->a_flags
);
764 cache_setunresolved(nch
);
771 KKASSERT(vp
== NULL
);
775 error
= VOP_OLD_WHITEOUT(dvp
, NULL
, ap
->a_flags
);
781 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
789 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
790 * struct vnode *a_dvp,
791 * struct ucred *a_cred }
794 vop_compat_nremove(struct vop_nremove_args
*ap
)
796 struct thread
*td
= curthread
;
797 struct componentname cnp
;
798 struct nchandle
*nch
;
799 struct namecache
*ncp
;
805 * Sanity checks, get a locked directory vnode.
807 nch
= ap
->a_nch
; /* locked namecache node */
811 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
812 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
818 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
819 * caches all information required to delete the entry in the
820 * directory inode. We expect a return code of 0 for the DELETE
821 * case (meaning that a vp has been found). The cnp must simulated
822 * a saved-name situation.
824 bzero(&cnp
, sizeof(cnp
));
825 cnp
.cn_nameiop
= NAMEI_DELETE
;
826 cnp
.cn_flags
= CNP_LOCKPARENT
;
827 cnp
.cn_nameptr
= ncp
->nc_name
;
828 cnp
.cn_namelen
= ncp
->nc_nlen
;
829 cnp
.cn_cred
= ap
->a_cred
;
833 * The vnode must be a directory and must not represent the
837 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
838 if (error
== 0 && vp
->v_type
== VDIR
)
841 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
842 error
= VOP_OLD_REMOVE(dvp
, vp
, &cnp
);
852 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
859 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
861 * struct ucred *a_cred }
864 vop_compat_nrmdir(struct vop_nrmdir_args
*ap
)
866 struct thread
*td
= curthread
;
867 struct componentname cnp
;
868 struct nchandle
*nch
;
869 struct namecache
*ncp
;
875 * Sanity checks, get a locked directory vnode.
877 nch
= ap
->a_nch
; /* locked namecache node */
881 if ((error
= vget(dvp
, LK_EXCLUSIVE
)) != 0) {
882 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
888 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
889 * caches all information required to delete the entry in the
890 * directory inode. We expect a return code of 0 for the DELETE
891 * case (meaning that a vp has been found). The cnp must simulated
892 * a saved-name situation.
894 bzero(&cnp
, sizeof(cnp
));
895 cnp
.cn_nameiop
= NAMEI_DELETE
;
896 cnp
.cn_flags
= CNP_LOCKPARENT
;
897 cnp
.cn_nameptr
= ncp
->nc_name
;
898 cnp
.cn_namelen
= ncp
->nc_nlen
;
899 cnp
.cn_cred
= ap
->a_cred
;
903 * The vnode must be a directory and must not represent the
907 error
= vop_old_lookup(ap
->a_head
.a_ops
, dvp
, &vp
, &cnp
);
908 if (error
== 0 && vp
->v_type
!= VDIR
)
910 if (error
== 0 && vp
== dvp
)
912 if (error
== 0 && (vp
->v_flag
& VROOT
))
915 KKASSERT((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
916 error
= VOP_OLD_RMDIR(dvp
, vp
, &cnp
);
919 * Note that this invalidation will cause any process
920 * currently CD'd into the directory being removed to be
921 * disconnected from the topology and not be able to ".."
925 cache_inval(nch
, CINV_DESTROY
);
926 cache_inval_vp(vp
, CINV_DESTROY
);
935 if ((cnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0)
942 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
943 * struct nchandle *a_tnch,
944 * struct ucred *a_cred }
946 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
947 * the source directory and vnode be unlocked and the target directory and
948 * vnode (if it exists) be locked. All arguments will be vrele'd and
949 * the targets will also be unlocked regardless of the return code.
952 vop_compat_nrename(struct vop_nrename_args
*ap
)
954 struct thread
*td
= curthread
;
955 struct componentname fcnp
;
956 struct componentname tcnp
;
957 struct nchandle
*fnch
;
958 struct nchandle
*tnch
;
959 struct namecache
*fncp
;
960 struct namecache
*tncp
;
961 struct vnode
*fdvp
, *fvp
;
962 struct vnode
*tdvp
, *tvp
;
966 * Sanity checks, get referenced vnodes representing the source.
968 fnch
= ap
->a_fnch
; /* locked namecache node */
973 * Temporarily lock the source directory and lookup in DELETE mode to
974 * check permissions. XXX delete permissions should have been
975 * checked by nlookup(), we need to add NLC_DELETE for delete
976 * checking. It is unclear whether VFS's require the directory setup
977 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
978 * since it isn't locked and since UFS always does a relookup of
979 * the source, it is believed that the only side effect that matters
980 * is the permissions check.
982 if ((error
= vget(fdvp
, LK_EXCLUSIVE
)) != 0) {
983 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
984 fncp
, fncp
->nc_name
);
988 bzero(&fcnp
, sizeof(fcnp
));
989 fcnp
.cn_nameiop
= NAMEI_DELETE
;
990 fcnp
.cn_flags
= CNP_LOCKPARENT
;
991 fcnp
.cn_nameptr
= fncp
->nc_name
;
992 fcnp
.cn_namelen
= fncp
->nc_nlen
;
993 fcnp
.cn_cred
= ap
->a_cred
;
997 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1001 error
= vop_old_lookup(ap
->a_head
.a_ops
, fdvp
, &fvp
, &fcnp
);
1002 if (error
== 0 && (fvp
->v_flag
& VROOT
)) {
1003 vput(fvp
); /* as if vop_old_lookup had failed */
1006 if ((fcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0) {
1007 fcnp
.cn_flags
|= CNP_PDIRUNLOCK
;
1017 * fdvp and fvp are now referenced and unlocked.
1019 * Get a locked directory vnode for the target and lookup the target
1020 * in CREATE mode so it places the required information in the
1023 tnch
= ap
->a_tnch
; /* locked namecache node */
1031 if ((error
= vget(tdvp
, LK_EXCLUSIVE
)) != 0) {
1032 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1033 tncp
, tncp
->nc_name
);
1040 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1041 * caches all information required to create the entry in the
1042 * target directory inode.
1044 bzero(&tcnp
, sizeof(tcnp
));
1045 tcnp
.cn_nameiop
= NAMEI_RENAME
;
1046 tcnp
.cn_flags
= CNP_LOCKPARENT
;
1047 tcnp
.cn_nameptr
= tncp
->nc_name
;
1048 tcnp
.cn_namelen
= tncp
->nc_nlen
;
1049 tcnp
.cn_cred
= ap
->a_cred
;
1053 error
= vop_old_lookup(ap
->a_head
.a_ops
, tdvp
, &tvp
, &tcnp
);
1055 if (error
== EJUSTRETURN
) {
1057 * Target does not exist. tvp should be NULL.
1059 KKASSERT(tvp
== NULL
);
1060 KKASSERT((tcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
1061 error
= VOP_OLD_RENAME(fdvp
, fvp
, &fcnp
, tdvp
, tvp
, &tcnp
);
1063 cache_rename(fnch
, tnch
);
1064 } else if (error
== 0) {
1066 * Target exists. VOP_OLD_RENAME should correctly delete the
1069 KKASSERT((tcnp
.cn_flags
& CNP_PDIRUNLOCK
) == 0);
1070 error
= VOP_OLD_RENAME(fdvp
, fvp
, &fcnp
, tdvp
, tvp
, &tcnp
);
1072 cache_rename(fnch
, tnch
);
1076 if (tcnp
.cn_flags
& CNP_PDIRUNLOCK
)
1085 vop_nolookup(struct vop_old_lookup_args
*ap
)
1095 * Strategy routine for VFS devices that have none.
1097 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1098 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1099 * Typically B_INVAL is assumed to already be clear prior to a write
1100 * and should not be cleared manually unless you just made the buffer
1101 * invalid. B_ERROR should be cleared either way.
1105 vop_nostrategy (struct vop_strategy_args
*ap
)
1107 kprintf("No strategy for buffer at %p\n", ap
->a_bio
->bio_buf
);
1108 vprint("", ap
->a_vp
);
1109 ap
->a_bio
->bio_buf
->b_flags
|= B_ERROR
;
1110 ap
->a_bio
->bio_buf
->b_error
= EOPNOTSUPP
;
1112 return (EOPNOTSUPP
);
1116 vop_stdpathconf(struct vop_pathconf_args
*ap
)
1120 switch (ap
->a_name
) {
1121 case _PC_CHOWN_RESTRICTED
:
1122 *ap
->a_retval
= _POSIX_CHOWN_RESTRICTED
;
1125 *ap
->a_retval
= LINK_MAX
;
1128 *ap
->a_retval
= MAX_CANON
;
1131 *ap
->a_retval
= MAX_INPUT
;
1134 *ap
->a_retval
= NAME_MAX
;
1137 *ap
->a_retval
= _POSIX_NO_TRUNC
;
1140 *ap
->a_retval
= PATH_MAX
;
1143 *ap
->a_retval
= PIPE_BUF
;
1146 *ap
->a_retval
= _POSIX_VDISABLE
;
1158 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
1160 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1163 vop_stdopen(struct vop_open_args
*ap
)
1165 struct vnode
*vp
= ap
->a_vp
;
1171 switch(vp
->v_type
) {
1173 fp
->f_type
= DTYPE_FIFO
;
1176 fp
->f_type
= DTYPE_VNODE
;
1179 /* retain flags not to be copied */
1180 fp
->f_flag
= (fp
->f_flag
& ~FMASK
) | (ap
->a_mode
& FMASK
);
1181 fp
->f_ops
= &vnode_fileops
;
1185 if (ap
->a_mode
& FWRITE
)
1186 atomic_add_int(&vp
->v_writecount
, 1);
1187 KKASSERT(vp
->v_opencount
>= 0 && vp
->v_opencount
!= INT_MAX
);
1188 atomic_add_int(&vp
->v_opencount
, 1);
1195 * (struct vnode *a_vp, int a_fflag)
1197 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1199 * v_lastwrite_ts is used to record the timestamp that should be used to
1200 * set the file mtime for any asynchronously flushed pages modified via
1201 * mmap(), which can occur after the last close().
1204 vop_stdclose(struct vop_close_args
*ap
)
1206 struct vnode
*vp
= ap
->a_vp
;
1208 KASSERT(vp
->v_opencount
> 0,
1209 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x",
1210 vp
, vp
->v_opencount
, vp
->v_type
, *vp
->v_ops
, vp
->v_flag
));
1211 if (ap
->a_fflag
& FWRITE
) {
1212 KASSERT(vp
->v_writecount
> 0,
1213 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d",
1214 vp
, vp
->v_writecount
));
1215 atomic_add_int(&vp
->v_writecount
, -1);
1217 atomic_add_int(&vp
->v_opencount
, -1);
1222 * Standard getattr_lite
1224 * Just calls getattr
1227 vop_stdgetattr_lite(struct vop_getattr_lite_args
*ap
)
1230 struct vattr_lite
*lvap
;
1233 error
= VOP_GETATTR(ap
->a_vp
, &va
);
1234 if (__predict_true(error
== 0)) {
1236 lvap
->va_type
= va
.va_type
;
1237 lvap
->va_nlink
= va
.va_nlink
;
1238 lvap
->va_mode
= va
.va_mode
;
1239 lvap
->va_uid
= va
.va_uid
;
1240 lvap
->va_gid
= va
.va_gid
;
1241 lvap
->va_size
= va
.va_size
;
1242 lvap
->va_flags
= va
.va_flags
;
1248 * Implement standard getpages and putpages. All filesystems must use
1249 * the buffer cache to back regular files.
1252 vop_stdgetpages(struct vop_getpages_args
*ap
)
1257 if ((mp
= ap
->a_vp
->v_mount
) != NULL
) {
1258 error
= vnode_pager_generic_getpages(
1259 ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1260 ap
->a_reqpage
, ap
->a_seqaccess
);
1262 error
= VM_PAGER_BAD
;
1268 vop_stdputpages(struct vop_putpages_args
*ap
)
1273 if ((mp
= ap
->a_vp
->v_mount
) != NULL
) {
1274 error
= vnode_pager_generic_putpages(
1275 ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1276 ap
->a_flags
, ap
->a_rtvals
);
1278 error
= VM_PAGER_BAD
;
1284 vop_stdnoread(struct vop_read_args
*ap
)
1290 vop_stdnowrite(struct vop_write_args
*ap
)
1297 * used to fill the vfs fucntion table to get reasonable default return values.
1300 vop_stdmountctl(struct vop_mountctl_args
*ap
)
1306 mp
= ap
->a_head
.a_ops
->head
.vv_mount
;
1309 case MOUNTCTL_MOUNTFLAGS
:
1311 * Get a string buffer with all the mount flags
1312 * names comman separated.
1313 * mount(2) will use this information.
1315 *ap
->a_res
= vfs_flagstostr(mp
->mnt_flag
& MNT_VISFLAGMASK
, NULL
,
1316 ap
->a_buf
, ap
->a_buflen
, &error
);
1318 case MOUNTCTL_INSTALL_VFS_JOURNAL
:
1319 case MOUNTCTL_RESTART_VFS_JOURNAL
:
1320 case MOUNTCTL_REMOVE_VFS_JOURNAL
:
1321 case MOUNTCTL_RESYNC_VFS_JOURNAL
:
1322 case MOUNTCTL_STATUS_VFS_JOURNAL
:
1323 error
= journal_mountctl(ap
);
1333 vop_stdallocate(struct vop_allocate_args
*ap
)
1337 struct vattr vattr
, *vap
;
1341 off_t offset
, len
, fsize
;
1345 bzero(&auio
, sizeof(auio
));
1352 offset
= ap
->a_offset
;
1355 error
= VOP_GETATTR(vp
, vap
);
1358 fsize
= vap
->va_size
;
1359 iosize
= vap
->va_blocksize
;
1361 iosize
= BLKDEV_IOSIZE
;
1362 if (iosize
> vmaxiosize(vp
))
1363 iosize
= vmaxiosize(vp
);
1364 buf
= kmalloc(iosize
, M_TEMP
, M_WAITOK
);
1366 if (offset
+ len
> vap
->va_size
) {
1368 * Test offset + len against the filesystem's maxfilesize.
1371 vap
->va_size
= offset
+ len
;
1372 error
= VOP_SETATTR(vp
, vap
, td
->td_ucred
);
1376 vap
->va_size
= fsize
;
1377 error
= VOP_SETATTR(vp
, vap
, td
->td_ucred
);
1384 * Read and write back anything below the nominal file
1385 * size. There's currently no way outside the filesystem
1386 * to know whether this area is sparse or not.
1389 if ((offset
% iosize
) != 0)
1390 cur
-= (offset
% iosize
);
1393 if (offset
< fsize
) {
1394 aiov
.iov_base
= buf
;
1396 auio
.uio_iov
= &aiov
;
1397 auio
.uio_iovcnt
= 1;
1398 auio
.uio_offset
= offset
;
1399 auio
.uio_resid
= cur
;
1400 auio
.uio_segflg
= UIO_SYSSPACE
;
1401 auio
.uio_rw
= UIO_READ
;
1403 error
= VOP_READ(vp
, &auio
, 0, td
->td_ucred
);
1406 if (auio
.uio_resid
> 0) {
1407 bzero(buf
+ cur
- auio
.uio_resid
,
1414 aiov
.iov_base
= buf
;
1416 auio
.uio_iov
= &aiov
;
1417 auio
.uio_iovcnt
= 1;
1418 auio
.uio_offset
= offset
;
1419 auio
.uio_resid
= cur
;
1420 auio
.uio_segflg
= UIO_SYSSPACE
;
1421 auio
.uio_rw
= UIO_WRITE
;
1424 error
= VOP_WRITE(vp
, &auio
, 0, td
->td_ucred
);
1438 ap
->a_offset
= offset
;
1446 vop_stdfdatasync(struct vop_fdatasync_args
*ap
)
1448 return (VOP_FSYNC_FP(ap
->a_vp
, ap
->a_waitfor
, ap
->a_flags
, ap
->a_fp
));
1452 vfs_stdroot(struct mount
*mp
, struct vnode
**vpp
)
1454 return (EOPNOTSUPP
);
1458 vfs_stdstatfs(struct mount
*mp
, struct statfs
*sbp
, struct ucred
*cred
)
1460 return (EOPNOTSUPP
);
1464 * If the VFS does not implement statvfs, then call statfs and convert
1465 * the values. This code was taken from libc's __cvtstatvfs() function,
1466 * contributed by Joerg Sonnenberger.
1469 vfs_stdstatvfs(struct mount
*mp
, struct statvfs
*sbp
, struct ucred
*cred
)
1475 error
= VFS_STATFS(mp
, in
, cred
);
1477 bzero(sbp
, sizeof(*sbp
));
1479 sbp
->f_bsize
= in
->f_bsize
;
1480 sbp
->f_frsize
= in
->f_bsize
;
1481 sbp
->f_blocks
= in
->f_blocks
;
1482 sbp
->f_bfree
= in
->f_bfree
;
1483 sbp
->f_bavail
= in
->f_bavail
;
1484 sbp
->f_files
= in
->f_files
;
1485 sbp
->f_ffree
= in
->f_ffree
;
1489 * This field counts the number of available inodes to non-root
1490 * users, but this information is not available via statfs.
1491 * Just ignore this issue by returning the total number
1494 sbp
->f_favail
= in
->f_ffree
;
1498 * This field has a different meaning for statfs and statvfs.
1499 * For the former it is the cookie exported for NFS and not
1500 * intended for normal userland use.
1505 if (in
->f_flags
& MNT_RDONLY
)
1506 sbp
->f_flag
|= ST_RDONLY
;
1507 if (in
->f_flags
& MNT_NOSUID
)
1508 sbp
->f_flag
|= ST_NOSUID
;
1510 sbp
->f_owner
= in
->f_owner
;
1513 * statfs contains the type as string, statvfs expects it as
1518 sbp
->f_syncreads
= in
->f_syncreads
;
1519 sbp
->f_syncwrites
= in
->f_syncwrites
;
1520 sbp
->f_asyncreads
= in
->f_asyncreads
;
1521 sbp
->f_asyncwrites
= in
->f_asyncwrites
;
1527 vfs_stdvptofh(struct vnode
*vp
, struct fid
*fhp
)
1529 return (EOPNOTSUPP
);
1533 vfs_stdstart(struct mount
*mp
, int flags
)
1539 vfs_stdquotactl(struct mount
*mp
, int cmds
, uid_t uid
,
1540 caddr_t arg
, struct ucred
*cred
)
1542 return (EOPNOTSUPP
);
1546 vfs_stdsync(struct mount
*mp
, int waitfor
)
1552 vfs_stdnosync(struct mount
*mp
, int waitfor
)
1554 return (EOPNOTSUPP
);
1558 vfs_stdvget(struct mount
*mp
, struct vnode
*dvp
, ino_t ino
, struct vnode
**vpp
)
1560 return (EOPNOTSUPP
);
1564 vfs_stdfhtovp(struct mount
*mp
, struct vnode
*rootvp
,
1565 struct fid
*fhp
, struct vnode
**vpp
)
1567 return (EOPNOTSUPP
);
1571 vfs_stdcheckexp(struct mount
*mp
, struct sockaddr
*nam
, int *extflagsp
,
1572 struct ucred
**credanonp
)
1574 return (EOPNOTSUPP
);
1578 vfs_stdinit(struct vfsconf
*vfsp
)
1584 vfs_stduninit(struct vfsconf
*vfsp
)
1590 vfs_stdextattrctl(struct mount
*mp
, int cmd
, struct vnode
*vp
,
1591 int attrnamespace
, const char *attrname
,
1597 #define ACCOUNTING_NB_FSTYPES 7
1599 static const char *accounting_fstypes
[ACCOUNTING_NB_FSTYPES
] = {
1600 "ext2fs", "hammer", "mfs", "ntfs", "null", "tmpfs", "ufs" };
1603 vfs_stdac_init(struct mount
*mp
)
1605 const char* fs_type
;
1606 int i
, fstype_ok
= 0;
1608 /* is mounted fs type one we want to do some accounting for ? */
1609 for (i
=0; i
<ACCOUNTING_NB_FSTYPES
; i
++) {
1610 fs_type
= accounting_fstypes
[i
];
1611 if (strncmp(mp
->mnt_stat
.f_fstypename
, fs_type
,
1612 sizeof(mp
->mnt_stat
)) == 0) {
1625 vfs_stdac_done(struct mount
*mp
)
1631 vfs_stdncpgen_set(struct mount
*mp
, struct namecache
*ncp
)
1636 vfs_stdncpgen_test(struct mount
*mp
, struct namecache
*ncp
)
1642 vfs_stdmodifying(struct mount
*mp
)
1644 if (mp
->mnt_flag
& MNT_RDONLY
)
1648 /* end of vfs default ops */