Fix "ls: not found" problem during buildworld. mdate.sh script
[dragonfly.git] / sys / kern / vfs_default.c
blob47137ef73e7c8faeb8e298354f5a450fc4d15848
1 /*
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
12 * are met:
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
36 * SUCH DAMAGE.
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.29 2006/02/17 19:18:06 dillon Exp $
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/buf.h>
46 #include <sys/conf.h>
47 #include <sys/kernel.h>
48 #include <sys/lock.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/unistd.h>
52 #include <sys/vnode.h>
53 #include <sys/namei.h>
54 #include <sys/nlookup.h>
55 #include <sys/poll.h>
56 #include <sys/mountctl.h>
58 #include <machine/limits.h>
60 #include <vm/vm.h>
61 #include <vm/vm_object.h>
62 #include <vm/vm_page.h>
63 #include <vm/vm_pager.h>
64 #include <vm/vnode_pager.h>
66 static int vop_nolookup (struct vop_old_lookup_args *);
67 static int vop_nostrategy (struct vop_strategy_args *);
70 * This vnode table stores what we want to do if the filesystem doesn't
71 * implement a particular VOP.
73 * If there is no specific entry here, we will return EOPNOTSUPP.
75 struct vop_ops *default_vnode_vops;
76 static struct vnodeopv_entry_desc default_vnodeop_entries[] = {
77 { &vop_default_desc, vop_eopnotsupp },
78 { &vop_advlock_desc, vop_einval },
79 { &vop_bwrite_desc, (void *) vop_stdbwrite },
80 { &vop_close_desc, vop_null },
81 { &vop_createvobject_desc, (void *) vop_stdcreatevobject },
82 { &vop_destroyvobject_desc, (void *) vop_stddestroyvobject },
83 { &vop_fsync_desc, vop_null },
84 { &vop_getvobject_desc, (void *) vop_stdgetvobject },
85 { &vop_ioctl_desc, vop_enotty },
86 { &vop_islocked_desc, (void *) vop_stdislocked },
87 { &vop_lease_desc, vop_null },
88 { &vop_lock_desc, (void *) vop_stdlock },
89 { &vop_mmap_desc, vop_einval },
90 { &vop_old_lookup_desc, (void *) vop_nolookup },
91 { &vop_open_desc, vop_null },
92 { &vop_pathconf_desc, vop_einval },
93 { &vop_poll_desc, (void *) vop_nopoll },
94 { &vop_readlink_desc, vop_einval },
95 { &vop_reallocblks_desc, vop_eopnotsupp },
96 { &vop_revoke_desc, (void *) vop_stdrevoke },
97 { &vop_strategy_desc, (void *) vop_nostrategy },
98 { &vop_unlock_desc, (void *) vop_stdunlock },
99 { &vop_getacl_desc, vop_eopnotsupp },
100 { &vop_setacl_desc, vop_eopnotsupp },
101 { &vop_aclcheck_desc, vop_eopnotsupp },
102 { &vop_getextattr_desc, vop_eopnotsupp },
103 { &vop_setextattr_desc, vop_eopnotsupp },
104 { &vop_nresolve_desc, (void *) vop_compat_nresolve },
105 { &vop_nlookupdotdot_desc, (void *) vop_compat_nlookupdotdot },
106 { &vop_ncreate_desc, (void *) vop_compat_ncreate },
107 { &vop_nmkdir_desc, (void *) vop_compat_nmkdir },
108 { &vop_nmknod_desc, (void *) vop_compat_nmknod },
109 { &vop_nlink_desc, (void *) vop_compat_nlink },
110 { &vop_nsymlink_desc, (void *) vop_compat_nsymlink },
111 { &vop_nwhiteout_desc, (void *) vop_compat_nwhiteout },
112 { &vop_nremove_desc, (void *) vop_compat_nremove },
113 { &vop_nrmdir_desc, (void *) vop_compat_nrmdir },
114 { &vop_nrename_desc, (void *) vop_compat_nrename },
115 { &vop_mountctl_desc, (void *) journal_mountctl },
116 { NULL, NULL }
119 static struct vnodeopv_desc default_vnodeop_opv_desc =
120 { &default_vnode_vops, default_vnodeop_entries, 0 };
122 VNODEOP_SET(default_vnodeop_opv_desc);
125 vop_eopnotsupp(struct vop_generic_args *ap)
127 return (EOPNOTSUPP);
131 vop_ebadf(struct vop_generic_args *ap)
133 return (EBADF);
137 vop_enotty(struct vop_generic_args *ap)
139 return (ENOTTY);
143 vop_einval(struct vop_generic_args *ap)
145 return (EINVAL);
149 vop_null(struct vop_generic_args *ap)
151 return (0);
155 vop_defaultop(struct vop_generic_args *ap)
157 return (VOCALL(default_vnode_vops, ap));
161 vop_panic(struct vop_generic_args *ap)
164 panic("filesystem goof: vop_panic[%s]", ap->a_desc->vdesc_name);
168 * vop_compat_resolve { struct namecache *a_ncp } XXX STOPGAP FUNCTION
170 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
171 * WILL BE REMOVED. This procedure exists for all VFSs which have not
172 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
173 * vop_old_lookup() and does appropriate translations.
175 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
176 * VFSs will support this VOP and this routine can be removed, since
177 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
178 * API.
180 * A locked ncp is passed in to be resolved. The NCP is resolved by
181 * figuring out the vnode (if any) and calling cache_setvp() to attach the
182 * vnode to the entry. If the entry represents a non-existant node then
183 * cache_setvp() is called with a NULL vnode to resolve the entry into a
184 * negative cache entry. No vnode locks are retained and the
185 * ncp is left locked on return.
187 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
189 * There is a potential directory and vnode interlock. The lock order
190 * requirement is: namecache, governing directory, resolved vnode.
193 vop_compat_nresolve(struct vop_nresolve_args *ap)
195 int error;
196 struct vnode *dvp;
197 struct vnode *vp;
198 struct namecache *ncp;
199 struct componentname cnp;
201 ncp = ap->a_ncp; /* locked namecache node */
202 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
203 return(EPERM);
204 if (ncp->nc_parent == NULL)
205 return(EPERM);
206 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
207 return(EPERM);
210 * UFS currently stores all sorts of side effects, including a loop
211 * variable, in the directory inode. That needs to be fixed and the
212 * other VFS's audited before we can switch to LK_SHARED.
214 if ((error = vget(dvp, LK_EXCLUSIVE, curthread)) != 0) {
215 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
216 ncp, ncp->nc_name);
217 return(EAGAIN);
220 bzero(&cnp, sizeof(cnp));
221 cnp.cn_nameiop = NAMEI_LOOKUP;
222 cnp.cn_flags = 0;
223 cnp.cn_nameptr = ncp->nc_name;
224 cnp.cn_namelen = ncp->nc_nlen;
225 cnp.cn_cred = ap->a_cred;
226 cnp.cn_td = curthread; /* XXX */
229 * vop_old_lookup() always returns vp locked. dvp may or may not be
230 * left locked depending on CNP_PDIRUNLOCK.
232 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
233 if (error == 0)
234 VOP_UNLOCK(vp, 0, curthread);
235 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
236 VOP_UNLOCK(dvp, 0, curthread);
237 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
238 /* was resolved by another process while we were unlocked */
239 if (error == 0)
240 vrele(vp);
241 } else if (error == 0) {
242 KKASSERT(vp != NULL);
243 cache_setvp(ncp, vp);
244 vrele(vp);
245 } else if (error == ENOENT) {
246 KKASSERT(vp == NULL);
247 if (cnp.cn_flags & CNP_ISWHITEOUT)
248 ncp->nc_flag |= NCF_WHITEOUT;
249 cache_setvp(ncp, NULL);
251 vrele(dvp);
252 return (error);
256 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
257 * struct vnode **a_vpp,
258 * struct ucred *a_cred }
260 * Lookup the vnode representing the parent directory of the specified
261 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
262 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
264 * This function is designed to aid NFS server-side operations and is
265 * used by cache_fromdvp() to create a consistent, connected namecache
266 * topology.
268 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
269 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
270 * permits VFSs will implement the remaining *_n*() calls and finally get
271 * rid of their *_lookup() call.
274 vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
276 struct componentname cnp;
277 int error;
280 * UFS currently stores all sorts of side effects, including a loop
281 * variable, in the directory inode. That needs to be fixed and the
282 * other VFS's audited before we can switch to LK_SHARED.
284 *ap->a_vpp = NULL;
285 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE, curthread)) != 0)
286 return (error);
287 if (ap->a_dvp->v_type != VDIR) {
288 vput(ap->a_dvp);
289 return (ENOTDIR);
292 bzero(&cnp, sizeof(cnp));
293 cnp.cn_nameiop = NAMEI_LOOKUP;
294 cnp.cn_flags = CNP_ISDOTDOT;
295 cnp.cn_nameptr = "..";
296 cnp.cn_namelen = 2;
297 cnp.cn_cred = ap->a_cred;
298 cnp.cn_td = curthread; /* XXX */
301 * vop_old_lookup() always returns vp locked. dvp may or may not be
302 * left locked depending on CNP_PDIRUNLOCK.
304 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
305 if (error == 0)
306 VOP_UNLOCK(*ap->a_vpp, 0, curthread);
307 if (cnp.cn_flags & CNP_PDIRUNLOCK)
308 vrele(ap->a_dvp);
309 else
310 vput(ap->a_dvp);
311 return (error);
315 * vop_compat_ncreate { struct namecache *a_ncp, XXX STOPGAP FUNCTION
316 * struct vnode *a_vpp,
317 * struct ucred *a_cred,
318 * struct vattr *a_vap }
320 * Create a file as specified by a_vap. Compatibility requires us to issue
321 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
322 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
325 vop_compat_ncreate(struct vop_ncreate_args *ap)
327 struct thread *td = curthread;
328 struct componentname cnp;
329 struct namecache *ncp;
330 struct vnode *dvp;
331 int error;
334 * Sanity checks, get a locked directory vnode.
336 ncp = ap->a_ncp; /* locked namecache node */
337 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
338 return(EPERM);
339 if (ncp->nc_parent == NULL)
340 return(EPERM);
341 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
342 return(EPERM);
344 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
345 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
346 ncp, ncp->nc_name);
347 return(EAGAIN);
351 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
352 * caches all information required to create the entry in the
353 * directory inode. We expect a return code of EJUSTRETURN for
354 * the CREATE case. The cnp must simulated a saved-name situation.
356 bzero(&cnp, sizeof(cnp));
357 cnp.cn_nameiop = NAMEI_CREATE;
358 cnp.cn_flags = CNP_LOCKPARENT;
359 cnp.cn_nameptr = ncp->nc_name;
360 cnp.cn_namelen = ncp->nc_nlen;
361 cnp.cn_cred = ap->a_cred;
362 cnp.cn_td = td;
363 *ap->a_vpp = NULL;
365 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
368 * EJUSTRETURN should be returned for this case, which means that
369 * the VFS has setup the directory inode for the create. The dvp we
370 * passed in is expected to remain in a locked state.
372 * If the VOP_OLD_CREATE is successful we are responsible for updating
373 * the cache state of the locked ncp that was passed to us.
375 if (error == EJUSTRETURN) {
376 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
377 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
378 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
379 if (error == 0) {
380 cache_setunresolved(ncp);
381 cache_setvp(ncp, *ap->a_vpp);
383 } else {
384 if (error == 0) {
385 vput(*ap->a_vpp);
386 *ap->a_vpp = NULL;
387 error = EEXIST;
389 KKASSERT(*ap->a_vpp == NULL);
391 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
392 VOP_UNLOCK(dvp, 0, td);
393 vrele(dvp);
394 return (error);
398 * vop_compat_nmkdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION
399 * struct vnode *a_vpp,
400 * struct ucred *a_cred,
401 * struct vattr *a_vap }
403 * Create a directory as specified by a_vap. Compatibility requires us to
404 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
405 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
408 vop_compat_nmkdir(struct vop_nmkdir_args *ap)
410 struct thread *td = curthread;
411 struct componentname cnp;
412 struct namecache *ncp;
413 struct vnode *dvp;
414 int error;
417 * Sanity checks, get a locked directory vnode.
419 ncp = ap->a_ncp; /* locked namecache node */
420 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
421 return(EPERM);
422 if (ncp->nc_parent == NULL)
423 return(EPERM);
424 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
425 return(EPERM);
427 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
428 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
429 ncp, ncp->nc_name);
430 return(EAGAIN);
434 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
435 * caches all information required to create the entry in the
436 * directory inode. We expect a return code of EJUSTRETURN for
437 * the CREATE case. The cnp must simulated a saved-name situation.
439 bzero(&cnp, sizeof(cnp));
440 cnp.cn_nameiop = NAMEI_CREATE;
441 cnp.cn_flags = CNP_LOCKPARENT;
442 cnp.cn_nameptr = ncp->nc_name;
443 cnp.cn_namelen = ncp->nc_nlen;
444 cnp.cn_cred = ap->a_cred;
445 cnp.cn_td = td;
446 *ap->a_vpp = NULL;
448 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
451 * EJUSTRETURN should be returned for this case, which means that
452 * the VFS has setup the directory inode for the create. The dvp we
453 * passed in is expected to remain in a locked state.
455 * If the VOP_OLD_MKDIR is successful we are responsible for updating
456 * the cache state of the locked ncp that was passed to us.
458 if (error == EJUSTRETURN) {
459 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
460 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
461 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
462 if (error == 0) {
463 cache_setunresolved(ncp);
464 cache_setvp(ncp, *ap->a_vpp);
466 } else {
467 if (error == 0) {
468 vput(*ap->a_vpp);
469 *ap->a_vpp = NULL;
470 error = EEXIST;
472 KKASSERT(*ap->a_vpp == NULL);
474 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
475 VOP_UNLOCK(dvp, 0, td);
476 vrele(dvp);
477 return (error);
481 * vop_compat_nmknod { struct namecache *a_ncp, XXX STOPGAP FUNCTION
482 * struct vnode *a_vpp,
483 * struct ucred *a_cred,
484 * struct vattr *a_vap }
486 * Create a device or fifo node as specified by a_vap. Compatibility requires
487 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
488 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
491 vop_compat_nmknod(struct vop_nmknod_args *ap)
493 struct thread *td = curthread;
494 struct componentname cnp;
495 struct namecache *ncp;
496 struct vnode *dvp;
497 int error;
500 * Sanity checks, get a locked directory vnode.
502 ncp = ap->a_ncp; /* locked namecache node */
503 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
504 return(EPERM);
505 if (ncp->nc_parent == NULL)
506 return(EPERM);
507 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
508 return(EPERM);
510 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
511 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
512 ncp, ncp->nc_name);
513 return(EAGAIN);
517 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
518 * caches all information required to create the entry in the
519 * directory inode. We expect a return code of EJUSTRETURN for
520 * the CREATE case. The cnp must simulated a saved-name situation.
522 bzero(&cnp, sizeof(cnp));
523 cnp.cn_nameiop = NAMEI_CREATE;
524 cnp.cn_flags = CNP_LOCKPARENT;
525 cnp.cn_nameptr = ncp->nc_name;
526 cnp.cn_namelen = ncp->nc_nlen;
527 cnp.cn_cred = ap->a_cred;
528 cnp.cn_td = td;
529 *ap->a_vpp = NULL;
531 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
534 * EJUSTRETURN should be returned for this case, which means that
535 * the VFS has setup the directory inode for the create. The dvp we
536 * passed in is expected to remain in a locked state.
538 * If the VOP_OLD_MKNOD is successful we are responsible for updating
539 * the cache state of the locked ncp that was passed to us.
541 if (error == EJUSTRETURN) {
542 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
543 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
544 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
545 if (error == 0) {
546 cache_setunresolved(ncp);
547 cache_setvp(ncp, *ap->a_vpp);
549 } else {
550 if (error == 0) {
551 vput(*ap->a_vpp);
552 *ap->a_vpp = NULL;
553 error = EEXIST;
555 KKASSERT(*ap->a_vpp == NULL);
557 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
558 VOP_UNLOCK(dvp, 0, td);
559 vrele(dvp);
560 return (error);
564 * vop_compat_nlink { struct namecache *a_ncp, XXX STOPGAP FUNCTION
565 * struct vnode *a_vp,
566 * struct ucred *a_cred }
568 * The passed vp is locked and represents the source. The passed ncp is
569 * locked and represents the target to create.
572 vop_compat_nlink(struct vop_nlink_args *ap)
574 struct thread *td = curthread;
575 struct componentname cnp;
576 struct namecache *ncp;
577 struct vnode *dvp;
578 struct vnode *tvp;
579 int error;
582 * Sanity checks, get a locked directory vnode.
584 ncp = ap->a_ncp; /* locked namecache node */
585 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
586 return(EPERM);
587 if (ncp->nc_parent == NULL)
588 return(EPERM);
589 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
590 return(EPERM);
592 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
593 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
594 ncp, ncp->nc_name);
595 return(EAGAIN);
599 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
600 * caches all information required to create the entry in the
601 * directory inode. We expect a return code of EJUSTRETURN for
602 * the CREATE case. The cnp must simulated a saved-name situation.
604 bzero(&cnp, sizeof(cnp));
605 cnp.cn_nameiop = NAMEI_CREATE;
606 cnp.cn_flags = CNP_LOCKPARENT;
607 cnp.cn_nameptr = ncp->nc_name;
608 cnp.cn_namelen = ncp->nc_nlen;
609 cnp.cn_cred = ap->a_cred;
610 cnp.cn_td = td;
612 tvp = NULL;
613 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
616 * EJUSTRETURN should be returned for this case, which means that
617 * the VFS has setup the directory inode for the create. The dvp we
618 * passed in is expected to remain in a locked state.
620 * If the VOP_OLD_LINK is successful we are responsible for updating
621 * the cache state of the locked ncp that was passed to us.
623 if (error == EJUSTRETURN) {
624 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
625 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
626 VOP_LEASE(ap->a_vp, td, ap->a_cred, LEASE_WRITE);
627 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
628 if (error == 0) {
629 cache_setunresolved(ncp);
630 cache_setvp(ncp, ap->a_vp);
632 } else {
633 if (error == 0) {
634 vput(tvp);
635 error = EEXIST;
638 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
639 VOP_UNLOCK(dvp, 0, td);
640 vrele(dvp);
641 return (error);
645 vop_compat_nsymlink(struct vop_nsymlink_args *ap)
647 struct thread *td = curthread;
648 struct componentname cnp;
649 struct namecache *ncp;
650 struct vnode *dvp;
651 struct vnode *vp;
652 int error;
655 * Sanity checks, get a locked directory vnode.
657 *ap->a_vpp = NULL;
658 ncp = ap->a_ncp; /* locked namecache node */
659 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
660 return(EPERM);
661 if (ncp->nc_parent == NULL)
662 return(EPERM);
663 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
664 return(EPERM);
666 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
667 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
668 ncp, ncp->nc_name);
669 return(EAGAIN);
673 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
674 * caches all information required to create the entry in the
675 * directory inode. We expect a return code of EJUSTRETURN for
676 * the CREATE case. The cnp must simulated a saved-name situation.
678 bzero(&cnp, sizeof(cnp));
679 cnp.cn_nameiop = NAMEI_CREATE;
680 cnp.cn_flags = CNP_LOCKPARENT;
681 cnp.cn_nameptr = ncp->nc_name;
682 cnp.cn_namelen = ncp->nc_nlen;
683 cnp.cn_cred = ap->a_cred;
684 cnp.cn_td = td;
686 vp = NULL;
687 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
690 * EJUSTRETURN should be returned for this case, which means that
691 * the VFS has setup the directory inode for the create. The dvp we
692 * passed in is expected to remain in a locked state.
694 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
695 * the cache state of the locked ncp that was passed to us.
697 if (error == EJUSTRETURN) {
698 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
699 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
700 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
701 if (error == 0) {
702 cache_setunresolved(ncp);
703 cache_setvp(ncp, vp);
704 *ap->a_vpp = vp;
706 } else {
707 if (error == 0) {
708 vput(vp);
709 vp = NULL;
710 error = EEXIST;
712 KKASSERT(vp == NULL);
714 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
715 VOP_UNLOCK(dvp, 0, td);
716 vrele(dvp);
717 return (error);
721 * vop_compat_nwhiteout { struct namecache *a_ncp, XXX STOPGAP FUNCTION
722 * struct ucred *a_cred,
723 * int a_flags }
725 * Issie a whiteout operation (create, lookup, or delete). Compatibility
726 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
727 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
728 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
729 * no lookup is necessary.
732 vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
734 struct thread *td = curthread;
735 struct componentname cnp;
736 struct namecache *ncp;
737 struct vnode *dvp;
738 struct vnode *vp;
739 int error;
742 * Sanity checks, get a locked directory vnode.
744 ncp = ap->a_ncp; /* locked namecache node */
745 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
746 return(EPERM);
747 if (ncp->nc_parent == NULL)
748 return(EPERM);
749 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
750 return(EPERM);
752 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
753 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
754 ncp, ncp->nc_name);
755 return(EAGAIN);
759 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
760 * caches all information required to create the entry in the
761 * directory inode. We expect a return code of EJUSTRETURN for
762 * the CREATE case. The cnp must simulated a saved-name situation.
764 bzero(&cnp, sizeof(cnp));
765 cnp.cn_nameiop = ap->a_flags;
766 cnp.cn_flags = CNP_LOCKPARENT;
767 cnp.cn_nameptr = ncp->nc_name;
768 cnp.cn_namelen = ncp->nc_nlen;
769 cnp.cn_cred = ap->a_cred;
770 cnp.cn_td = td;
772 vp = NULL;
775 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
776 * The VFS has setup the directory inode for the create. The dvp we
777 * passed in is expected to remain in a locked state.
779 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
780 * the cache state of the locked ncp that was passed to us.
782 switch(ap->a_flags) {
783 case NAMEI_DELETE:
784 cnp.cn_flags |= CNP_DOWHITEOUT;
785 /* fall through */
786 case NAMEI_CREATE:
787 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
788 if (error == EJUSTRETURN) {
789 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
790 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
791 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
792 if (error == 0)
793 cache_setunresolved(ncp);
794 } else {
795 if (error == 0) {
796 vput(vp);
797 vp = NULL;
798 error = EEXIST;
800 KKASSERT(vp == NULL);
802 break;
803 case NAMEI_LOOKUP:
804 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
805 break;
806 default:
807 error = EINVAL;
808 break;
810 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
811 VOP_UNLOCK(dvp, 0, td);
812 vrele(dvp);
813 return (error);
818 * vop_compat_nremove { struct namecache *a_ncp, XXX STOPGAP FUNCTION
819 * struct ucred *a_cred }
822 vop_compat_nremove(struct vop_nremove_args *ap)
824 struct thread *td = curthread;
825 struct componentname cnp;
826 struct namecache *ncp;
827 struct vnode *dvp;
828 struct vnode *vp;
829 int error;
832 * Sanity checks, get a locked directory vnode.
834 ncp = ap->a_ncp; /* locked namecache node */
835 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
836 return(EPERM);
837 if (ncp->nc_parent == NULL)
838 return(EPERM);
839 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
840 return(EPERM);
842 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
843 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
844 ncp, ncp->nc_name);
845 return(EAGAIN);
849 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
850 * caches all information required to delete the entry in the
851 * directory inode. We expect a return code of 0 for the DELETE
852 * case (meaning that a vp has been found). The cnp must simulated
853 * a saved-name situation.
855 bzero(&cnp, sizeof(cnp));
856 cnp.cn_nameiop = NAMEI_DELETE;
857 cnp.cn_flags = CNP_LOCKPARENT;
858 cnp.cn_nameptr = ncp->nc_name;
859 cnp.cn_namelen = ncp->nc_nlen;
860 cnp.cn_cred = ap->a_cred;
861 cnp.cn_td = td;
864 * The vnode must be a directory and must not represent the
865 * current directory.
867 vp = NULL;
868 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
869 if (error == 0 && vp->v_type == VDIR)
870 error = EPERM;
871 if (error == 0) {
872 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
873 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
874 VOP_LEASE(vp, td, ap->a_cred, LEASE_WRITE);
875 error = VOP_OLD_REMOVE(dvp, vp, &cnp);
876 if (error == 0) {
877 cache_setunresolved(ncp);
878 cache_setvp(ncp, NULL);
881 if (vp) {
882 if (dvp == vp)
883 vrele(vp);
884 else
885 vput(vp);
887 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
888 VOP_UNLOCK(dvp, 0, td);
889 vrele(dvp);
890 return (error);
894 * vop_compat_nrmdir { struct namecache *a_ncp, XXX STOPGAP FUNCTION
895 * struct ucred *a_cred }
898 vop_compat_nrmdir(struct vop_nrmdir_args *ap)
900 struct thread *td = curthread;
901 struct componentname cnp;
902 struct namecache *ncp;
903 struct vnode *dvp;
904 struct vnode *vp;
905 int error;
908 * Sanity checks, get a locked directory vnode.
910 ncp = ap->a_ncp; /* locked namecache node */
911 if (ncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
912 return(EPERM);
913 if (ncp->nc_parent == NULL)
914 return(EPERM);
915 if ((dvp = ncp->nc_parent->nc_vp) == NULL)
916 return(EPERM);
918 if ((error = vget(dvp, LK_EXCLUSIVE, td)) != 0) {
919 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
920 ncp, ncp->nc_name);
921 return(EAGAIN);
925 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
926 * caches all information required to delete the entry in the
927 * directory inode. We expect a return code of 0 for the DELETE
928 * case (meaning that a vp has been found). The cnp must simulated
929 * a saved-name situation.
931 bzero(&cnp, sizeof(cnp));
932 cnp.cn_nameiop = NAMEI_DELETE;
933 cnp.cn_flags = CNP_LOCKPARENT;
934 cnp.cn_nameptr = ncp->nc_name;
935 cnp.cn_namelen = ncp->nc_nlen;
936 cnp.cn_cred = ap->a_cred;
937 cnp.cn_td = td;
940 * The vnode must be a directory and must not represent the
941 * current directory.
943 vp = NULL;
944 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
945 if (error == 0 && vp->v_type != VDIR)
946 error = ENOTDIR;
947 if (error == 0 && vp == dvp)
948 error = EINVAL;
949 if (error == 0 && (vp->v_flag & VROOT))
950 error = EBUSY;
951 if (error == 0) {
952 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
953 VOP_LEASE(dvp, td, ap->a_cred, LEASE_WRITE);
954 VOP_LEASE(vp, td, ap->a_cred, LEASE_WRITE);
955 error = VOP_OLD_RMDIR(dvp, vp, &cnp);
958 * Note that this invalidation will cause any process
959 * currently CD'd into the directory being removed to be
960 * disconnected from the topology and not be able to ".."
961 * back out.
963 if (error == 0)
964 cache_inval(ncp, CINV_DESTROY);
966 if (vp) {
967 if (dvp == vp)
968 vrele(vp);
969 else
970 vput(vp);
972 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
973 VOP_UNLOCK(dvp, 0, td);
974 vrele(dvp);
975 return (error);
979 * vop_compat_nrename { struct namecache *a_fncp, XXX STOPGAP FUNCTION
980 * struct namecache *a_tncp,
981 * struct ucred *a_cred }
983 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
984 * the source directory and vnode be unlocked and the target directory and
985 * vnode (if it exists) be locked. All arguments will be vrele'd and
986 * the targets will also be unlocked regardless of the return code.
989 vop_compat_nrename(struct vop_nrename_args *ap)
991 struct thread *td = curthread;
992 struct componentname fcnp;
993 struct componentname tcnp;
994 struct namecache *fncp;
995 struct namecache *tncp;
996 struct vnode *fdvp, *fvp;
997 struct vnode *tdvp, *tvp;
998 int error;
1001 * Sanity checks, get referenced vnodes representing the source.
1003 fncp = ap->a_fncp; /* locked namecache node */
1004 if (fncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
1005 return(EPERM);
1006 if (fncp->nc_parent == NULL)
1007 return(EPERM);
1008 if ((fdvp = fncp->nc_parent->nc_vp) == NULL)
1009 return(EPERM);
1012 * Temporarily lock the source directory and lookup in DELETE mode to
1013 * check permissions. XXX delete permissions should have been
1014 * checked by nlookup(), we need to add NLC_DELETE for delete
1015 * checking. It is unclear whether VFS's require the directory setup
1016 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
1017 * since it isn't locked and since UFS always does a relookup of
1018 * the source, it is believed that the only side effect that matters
1019 * is the permissions check.
1021 if ((error = vget(fdvp, LK_EXCLUSIVE, td)) != 0) {
1022 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1023 fncp, fncp->nc_name);
1024 return(EAGAIN);
1027 bzero(&fcnp, sizeof(fcnp));
1028 fcnp.cn_nameiop = NAMEI_DELETE;
1029 fcnp.cn_flags = CNP_LOCKPARENT;
1030 fcnp.cn_nameptr = fncp->nc_name;
1031 fcnp.cn_namelen = fncp->nc_nlen;
1032 fcnp.cn_cred = ap->a_cred;
1033 fcnp.cn_td = td;
1036 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
1037 * fvp.
1039 fvp = NULL;
1040 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
1041 if (error == 0 && (fvp->v_flag & VROOT)) {
1042 vput(fvp); /* as if vop_old_lookup had failed */
1043 error = EBUSY;
1045 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1046 fcnp.cn_flags |= CNP_PDIRUNLOCK;
1047 VOP_UNLOCK(fdvp, 0, td);
1049 if (error) {
1050 vrele(fdvp);
1051 return (error);
1053 VOP_UNLOCK(fvp, 0, td);
1056 * fdvp and fvp are now referenced and unlocked.
1058 * Get a locked directory vnode for the target and lookup the target
1059 * in CREATE mode so it places the required information in the
1060 * directory inode.
1062 tncp = ap->a_tncp; /* locked namecache node */
1063 if (tncp->nc_flag & NCF_MOUNTPT) /* can't cross a mount point! */
1064 error = EPERM;
1065 if (tncp->nc_parent == NULL)
1066 error = EPERM;
1067 if ((tdvp = tncp->nc_parent->nc_vp) == NULL)
1068 error = EPERM;
1069 if (error) {
1070 vrele(fdvp);
1071 vrele(fvp);
1072 return (error);
1074 if ((error = vget(tdvp, LK_EXCLUSIVE, td)) != 0) {
1075 printf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
1076 tncp, tncp->nc_name);
1077 vrele(fdvp);
1078 vrele(fvp);
1079 return(EAGAIN);
1083 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
1084 * caches all information required to create the entry in the
1085 * target directory inode.
1087 bzero(&tcnp, sizeof(tcnp));
1088 tcnp.cn_nameiop = NAMEI_RENAME;
1089 tcnp.cn_flags = CNP_LOCKPARENT;
1090 tcnp.cn_nameptr = tncp->nc_name;
1091 tcnp.cn_namelen = tncp->nc_nlen;
1092 tcnp.cn_cred = ap->a_cred;
1093 tcnp.cn_td = td;
1095 tvp = NULL;
1096 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
1098 if (error == EJUSTRETURN) {
1100 * Target does not exist. tvp should be NULL.
1102 KKASSERT(tvp == NULL);
1103 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1104 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1105 if (error == 0) {
1106 cache_rename(fncp, tncp);
1107 cache_setvp(tncp, fvp);
1109 } else if (error == 0) {
1111 * Target exists. VOP_OLD_RENAME should correctly delete the
1112 * target.
1114 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1115 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
1116 if (error == 0) {
1117 cache_rename(fncp, tncp);
1118 cache_setvp(tncp, fvp);
1120 } else {
1121 vrele(fdvp);
1122 vrele(fvp);
1123 if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1124 vrele(tdvp);
1125 else
1126 vput(tdvp);
1128 return (error);
1131 static int
1132 vop_nolookup(ap)
1133 struct vop_old_lookup_args /* {
1134 struct vnode *a_dvp;
1135 struct vnode **a_vpp;
1136 struct componentname *a_cnp;
1137 } */ *ap;
1140 *ap->a_vpp = NULL;
1141 return (ENOTDIR);
1145 * vop_nostrategy:
1147 * Strategy routine for VFS devices that have none.
1149 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
1150 * routine. Typically this is done for a B_READ strategy call. Typically
1151 * B_INVAL is assumed to already be clear prior to a write and should not
1152 * be cleared manually unless you just made the buffer invalid. B_ERROR
1153 * should be cleared either way.
1156 static int
1157 vop_nostrategy (struct vop_strategy_args *ap)
1159 printf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
1160 vprint("", ap->a_vp);
1161 vprint("", ap->a_bio->bio_buf->b_vp);
1162 ap->a_bio->bio_buf->b_flags |= B_ERROR;
1163 ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1164 biodone(ap->a_bio);
1165 return (EOPNOTSUPP);
1169 vop_stdpathconf(ap)
1170 struct vop_pathconf_args /* {
1171 struct vnode *a_vp;
1172 int a_name;
1173 int *a_retval;
1174 } */ *ap;
1177 switch (ap->a_name) {
1178 case _PC_LINK_MAX:
1179 *ap->a_retval = LINK_MAX;
1180 return (0);
1181 case _PC_MAX_CANON:
1182 *ap->a_retval = MAX_CANON;
1183 return (0);
1184 case _PC_MAX_INPUT:
1185 *ap->a_retval = MAX_INPUT;
1186 return (0);
1187 case _PC_PIPE_BUF:
1188 *ap->a_retval = PIPE_BUF;
1189 return (0);
1190 case _PC_CHOWN_RESTRICTED:
1191 *ap->a_retval = 1;
1192 return (0);
1193 case _PC_VDISABLE:
1194 *ap->a_retval = _POSIX_VDISABLE;
1195 return (0);
1196 default:
1197 return (EINVAL);
1199 /* NOTREACHED */
1203 * Standard lock. The lock is recursive-capable only if the lock was
1204 * initialized with LK_CANRECURSE or that flag is passed in a_flags.
1207 vop_stdlock(ap)
1208 struct vop_lock_args /* {
1209 struct vnode *a_vp;
1210 int a_flags;
1211 struct proc *a_p;
1212 } */ *ap;
1214 int error;
1216 #ifndef DEBUG_LOCKS
1217 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags, NULL, ap->a_td);
1218 #else
1219 error = debuglockmgr(&ap->a_vp->v_lock, ap->a_flags,
1220 NULL, ap->a_td,
1221 "vop_stdlock", ap->a_vp->filename, ap->a_vp->line);
1222 #endif
1223 return(error);
1227 vop_stdunlock(ap)
1228 struct vop_unlock_args /* {
1229 struct vnode *a_vp;
1230 int a_flags;
1231 struct thread *a_td;
1232 } */ *ap;
1234 int error;
1236 error = lockmgr(&ap->a_vp->v_lock, ap->a_flags | LK_RELEASE,
1237 NULL, ap->a_td);
1238 return(error);
1242 vop_stdislocked(ap)
1243 struct vop_islocked_args /* {
1244 struct vnode *a_vp;
1245 struct thread *a_td;
1246 } */ *ap;
1248 return (lockstatus(&ap->a_vp->v_lock, ap->a_td));
1252 * Return true for select/poll.
1255 vop_nopoll(ap)
1256 struct vop_poll_args /* {
1257 struct vnode *a_vp;
1258 int a_events;
1259 struct ucred *a_cred;
1260 struct proc *a_p;
1261 } */ *ap;
1264 * Return true for read/write. If the user asked for something
1265 * special, return POLLNVAL, so that clients have a way of
1266 * determining reliably whether or not the extended
1267 * functionality is present without hard-coding knowledge
1268 * of specific filesystem implementations.
1270 if (ap->a_events & ~POLLSTANDARD)
1271 return (POLLNVAL);
1273 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1277 * Implement poll for local filesystems that support it.
1280 vop_stdpoll(ap)
1281 struct vop_poll_args /* {
1282 struct vnode *a_vp;
1283 int a_events;
1284 struct ucred *a_cred;
1285 struct thread *a_td;
1286 } */ *ap;
1288 if (ap->a_events & ~POLLSTANDARD)
1289 return (vn_pollrecord(ap->a_vp, ap->a_td, ap->a_events));
1290 return (ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
1294 vop_stdbwrite(ap)
1295 struct vop_bwrite_args *ap;
1297 return (bwrite(ap->a_bp));
1301 vop_stdcreatevobject(ap)
1302 struct vop_createvobject_args /* {
1303 struct vnode *a_vp;
1304 struct proc *a_td;
1305 } */ *ap;
1307 struct vnode *vp = ap->a_vp;
1308 struct thread *td = ap->a_td;
1309 struct vattr vat;
1310 vm_object_t object;
1311 int error = 0;
1313 if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE)
1314 return (0);
1316 retry:
1317 if ((object = vp->v_object) == NULL) {
1318 if (vp->v_type == VREG || vp->v_type == VDIR) {
1319 if ((error = VOP_GETATTR(vp, &vat, td)) != 0)
1320 goto retn;
1321 object = vnode_pager_alloc(vp, vat.va_size, 0, 0);
1322 } else if (vp->v_rdev && dev_is_good(vp->v_rdev)) {
1324 * XXX v_rdev uses NULL/non-NULL instead of NODEV
1326 * This simply allocates the biggest object possible
1327 * for a disk vnode. This should be fixed, but doesn't
1328 * cause any problems (yet).
1330 object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0);
1331 } else {
1332 goto retn;
1335 * Dereference the reference we just created. This assumes
1336 * that the object is associated with the vp.
1338 object->ref_count--;
1339 vp->v_usecount--;
1340 } else {
1341 if (object->flags & OBJ_DEAD) {
1342 VOP_UNLOCK(vp, 0, td);
1343 tsleep(object, 0, "vodead", 0);
1344 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1345 goto retry;
1349 KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object"));
1350 vp->v_flag |= VOBJBUF;
1352 retn:
1353 return (error);
1357 vop_stddestroyvobject(ap)
1358 struct vop_destroyvobject_args /* {
1359 struct vnode *vp;
1360 } */ *ap;
1362 struct vnode *vp = ap->a_vp;
1363 vm_object_t obj = vp->v_object;
1365 if (vp->v_object == NULL)
1366 return (0);
1368 if (obj->ref_count == 0) {
1370 * vclean() may be called twice. The first time
1371 * removes the primary reference to the object,
1372 * the second time goes one further and is a
1373 * special-case to terminate the object.
1375 * don't double-terminate the object.
1377 if ((obj->flags & OBJ_DEAD) == 0)
1378 vm_object_terminate(obj);
1379 } else {
1381 * Woe to the process that tries to page now :-).
1383 vm_pager_deallocate(obj);
1385 return (0);
1389 * Return the underlying VM object. This routine may be called with or
1390 * without the vnode interlock held. If called without, the returned
1391 * object is not guarenteed to be valid. The syncer typically gets the
1392 * object without holding the interlock in order to quickly test whether
1393 * it might be dirty before going heavy-weight. vm_object's use zalloc
1394 * and thus stable-storage, so this is safe.
1397 vop_stdgetvobject(ap)
1398 struct vop_getvobject_args /* {
1399 struct vnode *vp;
1400 struct vm_object **objpp;
1401 } */ *ap;
1403 struct vnode *vp = ap->a_vp;
1404 struct vm_object **objpp = ap->a_objpp;
1406 if (objpp)
1407 *objpp = vp->v_object;
1408 return (vp->v_object ? 0 : EINVAL);
1412 * vfs default ops
1413 * used to fill the vfs fucntion table to get reasonable default return values.
1415 int
1416 vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct thread *td)
1418 return (0);
1421 int
1422 vfs_stdunmount(struct mount *mp, int mntflags, struct thread *td)
1424 return (0);
1427 int
1428 vfs_stdroot(struct mount *mp, struct vnode **vpp)
1430 return (EOPNOTSUPP);
1433 int
1434 vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct thread *td)
1436 return (EOPNOTSUPP);
1440 vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
1442 return (EOPNOTSUPP);
1445 int
1446 vfs_stdstart(struct mount *mp, int flags, struct thread *td)
1448 return (0);
1451 int
1452 vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
1453 caddr_t arg, struct thread *td)
1455 return (EOPNOTSUPP);
1458 int
1459 vfs_stdsync(struct mount *mp, int waitfor, struct thread *td)
1461 return (0);
1465 vfs_stdnosync(struct mount *mp, int waitfor, struct thread *td)
1467 return (EOPNOTSUPP);
1470 int
1471 vfs_stdvget(struct mount *mp, ino_t ino, struct vnode **vpp)
1473 return (EOPNOTSUPP);
1476 int
1477 vfs_stdfhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
1479 return (EOPNOTSUPP);
1482 int
1483 vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1484 struct ucred **credanonp)
1486 return (EOPNOTSUPP);
1490 vfs_stdinit(struct vfsconf *vfsp)
1492 return (0);
1496 vfs_stduninit(struct vfsconf *vfsp)
1498 return(0);
1502 vfs_stdextattrctl(struct mount *mp, int cmd, const char *attrname,
1503 caddr_t arg, struct thread *td)
1505 return(EOPNOTSUPP);
1508 /* end of vfs default ops */