2 * OpenBSD specific vnodeops + other misc interface glue
3 * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
4 * OpenBSD version by Jim Rees <rees@umich.edu>
6 * $Id: osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $
11 the regents of the university of michigan
14 permission is granted to use, copy, create derivative works
15 and redistribute this software and such derivative works
16 for any purpose, so long as the name of the university of
17 michigan is not used in any advertising or publicity
18 pertaining to the use or distribution of this software
19 without specific, written prior authorization. if the
20 above copyright notice or any other identification of the
21 university of michigan is included in any copy of any
22 portion of this software, then the disclaimer below must
25 this software is provided as is, without representation
26 from the university of michigan as to its fitness for any
27 purpose, and without warranty by the university of
28 michigan of any kind, either express or implied, including
29 without limitation the implied warranties of
30 merchantability and fitness for a particular purpose. the
31 regents of the university of michigan shall not be liable
32 for any damages, including special, indirect, incidental, or
33 consequential damages, with respect to any claim arising
34 out of or in connection with the use of the software, even
35 if it has been or is hereafter advised of the possibility of
40 Copyright 1995 Massachusetts Institute of Technology. All Rights
43 You are hereby granted a worldwide, irrevocable, paid-up, right and
44 license to use, execute, display, modify, copy and distribute MIT's
45 Modifications, provided that (i) you abide by the terms and conditions
46 of your OpenAFS License Agreement, and (ii) you do not use the name
47 of MIT in any advertising or publicity without the prior written consent
48 of MIT. MIT disclaims all liability for your use of MIT's
49 Modifications. MIT's Modifications are provided "AS IS" WITHOUT
50 WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
51 ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
56 * A bunch of code cribbed from NetBSD ufs_vnops.c, ffs_vnops.c, and
57 * nfs_vnops.c which carry this copyright:
60 * Copyright (c) 1982, 1986, 1989, 1993
61 * The Regents of the University of California. All rights reserved.
62 * (c) UNIX System Laboratories, Inc.
63 * All or some portions of this file are derived from material licensed
64 * to the University of California by American Telephone and Telegraph
65 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
66 * the permission of UNIX System Laboratories, Inc.
68 * Redistribution and use in source and binary forms, with or without
69 * modification, are permitted provided that the following conditions
71 * 1. Redistributions of source code must retain the above copyright
72 * notice, this list of conditions and the following disclaimer.
73 * 2. Redistributions in binary form must reproduce the above copyright
74 * notice, this list of conditions and the following disclaimer in the
75 * documentation and/or other materials provided with the distribution.
76 * 3. All advertising materials mentioning features or use of this software
77 * must display the following acknowledgement:
78 * This product includes software developed by the University of
79 * California, Berkeley and its contributors.
80 * 4. Neither the name of the University nor the names of its contributors
81 * may be used to endorse or promote products derived from this software
82 * without specific prior written permission.
84 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
85 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
86 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
87 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
90 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
92 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
93 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98 #include <afsconfig.h>
99 #include "afs/param.h"
101 #include "afs/sysincludes.h" /* Standard vendor system headers */
102 #include "afs/afsincludes.h" /* Afs-based standard headers */
103 #include "afs/afs_stats.h" /* statistics */
105 #include <sys/malloc.h>
106 #include <sys/namei.h>
107 #include <sys/pool.h>
108 #include <miscfs/genfs/genfs.h>
110 #include "afs/afs_cbqueue.h"
111 #include "afs/nfsclient.h"
112 #include "afs/afs_osidnlc.h"
114 int afs_nbsd_lookup(void *);
115 int afs_nbsd_create(void *);
116 int afs_nbsd_mknod(void *);
117 int afs_nbsd_open(void *);
118 int afs_nbsd_close(void *);
119 int afs_nbsd_access(void *);
120 int afs_nbsd_getattr(void *);
121 int afs_nbsd_setattr(void *);
122 int afs_nbsd_read(void *);
123 int afs_nbsd_write(void *);
124 int afs_nbsd_ioctl(void *);
125 int afs_nbsd_fsync(void *);
126 int afs_nbsd_remove(void *);
127 int afs_nbsd_link(void *);
128 int afs_nbsd_rename(void *);
129 int afs_nbsd_mkdir(void *);
130 int afs_nbsd_rmdir(void *);
131 int afs_nbsd_symlink(void *);
132 int afs_nbsd_readdir(void *);
133 int afs_nbsd_readlink(void *);
134 int afs_nbsd_inactive(void *);
135 int afs_nbsd_reclaim(void *);
136 int afs_nbsd_lock(void *);
137 int afs_nbsd_unlock(void *);
138 int afs_nbsd_bmap(void *);
139 int afs_nbsd_strategy(void *);
140 int afs_nbsd_print(void *);
141 int afs_nbsd_islocked(void *);
142 int afs_nbsd_pathconf(void *);
143 int afs_nbsd_advlock(void *);
153 /* Global vfs data structures for AFS. */
154 int (**afs_vnodeop_p
) __P((void *));
155 const struct vnodeopv_entry_desc afs_vnodeop_entries
[] = {
156 {&vop_default_desc
, vn_default_error
},
157 {&vop_lookup_desc
, afs_nbsd_lookup
}, /* lookup */
158 {&vop_create_desc
, afs_nbsd_create
}, /* create */
159 {&vop_mknod_desc
, afs_nbsd_mknod
}, /* mknod */
160 {&vop_open_desc
, afs_nbsd_open
}, /* open */
161 {&vop_close_desc
, afs_nbsd_close
}, /* close */
162 {&vop_access_desc
, afs_nbsd_access
}, /* access */
163 {&vop_getattr_desc
, afs_nbsd_getattr
}, /* getattr */
164 {&vop_setattr_desc
, afs_nbsd_setattr
}, /* setattr */
165 {&vop_read_desc
, afs_nbsd_read
}, /* read */
166 {&vop_write_desc
, afs_nbsd_write
}, /* write */
168 {&vop_ioctl_desc
, afs_nbsd_ioctl
}, /* XXX ioctl */
170 {&vop_ioctl_desc
, genfs_enoioctl
}, /* ioctl */
172 {&vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
173 {&vop_poll_desc
, genfs_poll
}, /* poll */
174 {&vop_kqfilter_desc
, genfs_kqfilter
}, /* kqfilter */
175 {&vop_mmap_desc
, genfs_mmap
}, /* mmap */
176 {&vop_fsync_desc
, afs_nbsd_fsync
}, /* fsync */
177 {&vop_seek_desc
, genfs_seek
}, /* seek */
178 {&vop_remove_desc
, afs_nbsd_remove
}, /* remove */
179 {&vop_link_desc
, afs_nbsd_link
}, /* link */
180 {&vop_rename_desc
, afs_nbsd_rename
}, /* rename */
181 {&vop_mkdir_desc
, afs_nbsd_mkdir
}, /* mkdir */
182 {&vop_rmdir_desc
, afs_nbsd_rmdir
}, /* rmdir */
183 {&vop_symlink_desc
, afs_nbsd_symlink
}, /* symlink */
184 {&vop_readdir_desc
, afs_nbsd_readdir
}, /* readdir */
185 {&vop_readlink_desc
, afs_nbsd_readlink
}, /* readlink */
186 {&vop_abortop_desc
, genfs_abortop
}, /* abortop */
187 {&vop_inactive_desc
, afs_nbsd_inactive
}, /* inactive */
188 {&vop_reclaim_desc
, afs_nbsd_reclaim
}, /* reclaim */
189 {&vop_lock_desc
, afs_nbsd_lock
}, /* lock */
190 {&vop_unlock_desc
, afs_nbsd_unlock
}, /* unlock */
191 {&vop_bmap_desc
, afs_nbsd_bmap
}, /* bmap */
192 {&vop_strategy_desc
, afs_nbsd_strategy
}, /* strategy */
193 {&vop_print_desc
, afs_nbsd_print
}, /* print */
194 {&vop_islocked_desc
, afs_nbsd_islocked
}, /* islocked */
195 {&vop_pathconf_desc
, afs_nbsd_pathconf
}, /* pathconf */
196 {&vop_advlock_desc
, afs_nbsd_advlock
}, /* advlock */
198 {&vop_reallocblks_desc
, afs_nbsd_reallocblks
}, /* reallocblks */
200 {&vop_bwrite_desc
, vn_bwrite
}, /* bwrite */
201 {&vop_getpages_desc
, genfs_getpages
}, /* getpages */
202 {&vop_putpages_desc
, genfs_putpages
}, /* putpages */
205 const struct vnodeopv_desc afs_vnodeop_opv_desc
=
206 { &afs_vnodeop_p
, afs_vnodeop_entries
};
209 afs_nbsd_gop_size(struct vnode
*vp
, off_t size
, off_t
*eobp
, int flags
)
212 *eobp
= MAX(size
, vp
->v_size
);
216 afs_nbsd_gop_alloc(struct vnode
*vp
, off_t off
, off_t len
, int flags
,
223 static const struct genfs_ops afs_genfsops
= {
224 .gop_size
= afs_nbsd_gop_size
,
225 .gop_alloc
= afs_nbsd_gop_alloc
,
226 .gop_write
= genfs_gop_write
,
229 extern void cpu_Debugger(void);
232 cnstrdup(const struct componentname
*cnp
)
236 string
= PNBUF_GET();
237 memcpy(string
, cnp
->cn_nameptr
, cnp
->cn_namelen
);
238 string
[cnp
->cn_namelen
] = '\0';
244 cnstrfree(char *string
)
249 /* toss "stale" pages by shrinking the vnode uobj to a 0-length
250 * region (see uvm_vnp_setsize in uvm_vnode.c) */
251 #ifdef AFS_NBSD50_ENV
252 #define VNP_UNCACHE(vp) \
254 struct uvm_object *uobj = &vp->v_uobj; \
255 mutex_enter(&uobj->vmobjlock); \
256 VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
257 mutex_exit(&uobj->vmobjlock); \
260 #define VNP_UNCACHE(vp) \
262 struct uvm_object *uobj = &vp->v_uobj; \
263 simple_lock(&uobj->vmobjlock); \
264 VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
265 simple_unlock(&uobj->vmobjlock); \
269 /* psuedo-vnop, wherein we learn that obsd and nbsd disagree
270 * about vnode refcounting */
272 afs_nbsd_getnewvnode(struct vcache
*tvc
)
276 KASSERT(AFSTOV(tvc
) == NULL
);
277 while (getnewvnode(VT_AFS
, afs_globalVFS
, afs_vnodeop_p
, &AFSTOV(tvc
))) {
278 /* no vnodes available, force an alloc (limits be damned)! */
279 printf("afs: upping desiredvnodes\n");
283 vd
= kmem_zalloc(sizeof(*vd
), KM_SLEEP
);
284 #ifdef AFS_NBSD50_ENV
285 mutex_enter(&AFSTOV(tvc
)->v_interlock
);
287 simple_lock(&AFSTOV(tvc
)->v_interlock
);
290 AFSTOV(tvc
)->v_data
= vd
;
291 genfs_node_init(AFSTOV(tvc
), &afs_genfsops
);
292 #ifdef AFS_NBSD50_ENV
293 mutex_exit(&AFSTOV(tvc
)->v_interlock
);
295 simple_unlock(&AFSTOV(tvc
)->v_interlock
);
297 uvm_vnp_setsize(AFSTOV(tvc
), 0);
301 afs_nbsd_lookup(void *v
)
303 struct vop_lookup_args
/* {
304 * struct vnodeop_desc * a_desc;
305 * struct vnode *a_dvp;
306 * struct vnode **a_vpp;
307 * struct componentname *a_cnp;
309 struct vnode
*dvp
, *vp
;
311 struct componentname
*cnp
;
315 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
316 printf("nbsd_lookup a_cnp->cn_nameptr %s cred %p a_dvp %p\n",
317 ap
->a_cnp
->cn_nameptr
, ap
->a_cnp
->cn_cred
, ap
->a_dvp
);
319 KASSERT(VOP_ISLOCKED(ap
->a_dvp
));
323 vp
= *ap
->a_vpp
= NULL
;
326 #if AFS_USE_NBSD_NAMECACHE
327 code
= cache_lookup(dvp
, ap
->a_vpp
, cnp
);
334 if (dvp
->v_type
!= VDIR
) {
339 name
= cnstrdup(cnp
);
341 code
= afs_lookup(VTOAFS(dvp
), name
, &vcp
, cnp
->cn_cred
);
343 cnstrfree(name
); name
= NULL
;
346 && (cnp
->cn_nameiop
== CREATE
|| cnp
->cn_nameiop
== RENAME
)
347 && (cnp
->cn_flags
& ISLASTCN
)) {
350 #if !defined(AFS_NBSD60_ENV)
351 cnp
->cn_flags
|= SAVENAME
;
357 vp
= *ap
->a_vpp
= AFSTOV(vcp
);
358 if (cnp
->cn_flags
& ISDOTDOT
) {
359 #if defined(AFS_NBSD60_ENV)
364 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
365 vn_lock(dvp
, LK_EXCLUSIVE
| LK_RETRY
);
366 } else if (vp
== dvp
) {
369 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
373 #if AFS_USE_NBSD_NAMECACHE
374 if ((cnp
->cn_flags
& MAKEENTRY
) && cnp
->cn_nameiop
!= CREATE
) {
375 cache_enter(dvp
, *ap
->a_vpp
, cnp
);
381 #ifdef AFS_NBSD50_ENV
382 if ((afs_debug
& AFSDEB_VNLAYER
) != 0 && (dvp
->v_vflag
& VV_ROOT
) != 0)
384 if ((afs_debug
& AFSDEB_VNLAYER
) != 0 && (dvp
->v_flag
& VROOT
) != 0)
387 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
388 printf("nbsd_lookup done dvp %p cnt %d\n", dvp
, dvp
->v_usecount
);
391 if (code
== 0 && afs_debug
== 0) {
392 KASSERT(VOP_ISLOCKED(*ap
->a_vpp
));
399 afs_nbsd_create(void *v
)
401 struct vop_create_args
/* {
402 * struct vnode *a_dvp;
403 * struct vnode **a_vpp;
404 * struct componentname *a_cnp;
405 * struct vattr *a_vap;
409 struct vnode
*dvp
= ap
->a_dvp
;
410 struct componentname
*cnp
= ap
->a_cnp
;
413 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
414 /* printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount); */
415 printf("nbsd_create a_cnp->cn_nameptr %s cred %p a_dvp %p\n",
416 ap
->a_cnp
->cn_nameptr
, ap
->a_cnp
->cn_cred
, ap
->a_dvp
);
417 /* printf("name: %d %s\n", ap->a_cnp->cn_namelen, name); */
420 /* vnode layer handles excl/nonexcl */
422 name
= cnstrdup(cnp
);
425 afs_create(VTOAFS(dvp
), name
, ap
->a_vap
, NONEXCL
, ap
->a_vap
->va_mode
,
430 VOP_ABORTOP(dvp
, cnp
);
436 *ap
->a_vpp
= AFSTOV(vcp
);
437 vn_lock(AFSTOV(vcp
), LK_EXCLUSIVE
| LK_RETRY
);
441 #if !defined(AFS_NBSD60_ENV)
442 if (code
|| (cnp
->cn_flags
& SAVESTART
) == 0) {
443 PNBUF_PUT(cnp
->cn_pnbuf
);
447 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
448 printf("nbsd_create done dvp %p cnt %d\n", dvp
, dvp
->v_usecount
);
454 afs_nbsd_mknod(void *v
)
456 struct vop_mknod_args
/* {
457 * struct vnode *a_dvp;
458 * struct vnode **a_vpp;
459 * struct componentname *a_cnp;
460 * struct vattr *a_vap;
463 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
464 printf("nbsd_mknod: enter %p dvp %p\n", ap
, ap
->a_dvp
);
468 #if !defined(AFS_NBSD60_ENV)
469 PNBUF_PUT(ap
->a_cnp
->cn_pnbuf
);
473 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
474 printf("nbsd_mknod: exit ap %p\n", ap
);
481 afs_nbsd_open(void *v
)
483 struct vop_open_args
/* {
484 * struct vnode *a_vp;
486 * struct ucred *a_cred;
490 struct vnode
*vp
= ap
->a_vp
;
491 struct vcache
*vc
= VTOAFS(vp
);
493 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
494 printf("nbsd_open: enter %p vp %p vc %p\n", ap
, ap
->a_vp
, vc
);
498 code
= afs_open(&vc
, ap
->a_mode
, ap
->a_cred
);
500 if (AFSTOV(vc
) != ap
->a_vp
)
501 panic("nbsd_open: AFS open changed vnode!");
505 uvm_vnp_setsize(ap
->a_vp
, VTOAFS(ap
->a_vp
)->f
.m
.Length
);
507 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
508 printf("nbsd_open: exit vp %p vc %p\n", vp
, vc
);
515 afs_nbsd_close(void *v
)
517 struct vop_close_args
/* {
518 * struct vnode *a_vp;
520 * kauth_cred_t a_cred;
524 struct vnode
*vp
= ap
->a_vp
;
525 struct vcache
*vc
= VTOAFS(vp
);
527 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
528 printf("nbsd_close: enter %p vp %p vc %p\n", ap
, ap
->a_vp
, vc
);
532 code
= afs_close(VTOAFS(ap
->a_vp
), ap
->a_fflag
, ap
->a_cred
);
535 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
536 printf("nbsd_close: exit vp %p vc %p\n", vp
, vc
);
543 afs_nbsd_access(void *v
)
545 struct vop_access_args
/* {
546 * struct vnode *a_vp;
548 * kauth_cred_t a_cred;
552 struct vnode
*vp
= ap
->a_vp
;
553 struct vcache
*vc
= VTOAFS(vp
);
555 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
556 printf("nbsd_access: enter %p vp %p vc %p mode %d\n", ap
, ap
->a_vp
, vc
, ap
->a_mode
);
560 code
= afs_access(VTOAFS(ap
->a_vp
), ap
->a_mode
, ap
->a_cred
);
563 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
564 printf("nbsd_access: exit vp %p vc %p mode %d\n", vp
, vc
, ap
->a_mode
);
571 afs_nbsd_getattr(void *v
)
573 struct vop_getattr_args
/* {
574 * struct vnode *a_vp;
575 * struct vattr *a_vap;
576 * kauth_cred_t a_cred;
580 struct vnode
*vp
= ap
->a_vp
;
581 struct vcache
*vc
= VTOAFS(vp
);
583 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
584 printf("nbsd_getattr: enter %p vp %p vc %p acred %p\n",
585 ap
, ap
->a_vp
, vc
, ap
->a_cred
);
589 code
= afs_getattr(VTOAFS(ap
->a_vp
), ap
->a_vap
, ap
->a_cred
);
592 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
593 printf("nbsd_getattr: exit vp %p vc %p acred %p\n", vp
, vc
,
601 afs_nbsd_setattr(void *v
)
603 struct vop_setattr_args
/* {
604 * struct vnode *a_vp;
605 * struct vattr *a_vap;
606 * kauth_cred_t a_cred;
611 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
612 printf("nbsd_setattr: enter %p vp %p\n", ap
, ap
->a_vp
);
616 code
= afs_setattr(VTOAFS(ap
->a_vp
), ap
->a_vap
, ap
->a_cred
);
619 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
620 printf("nbsd_setattr: exit %p\n", ap
);
627 afs_nbsd_read(void *v
)
629 struct vop_read_args
/* {
630 * struct vnode *a_vp;
633 * kauth_cred_t a_cred;
637 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
638 printf("nbsd_read enter %p vp %p\n", ap
, ap
->a_vp
);
642 if (ap
->a_uio
->uio_offset
> ap
->a_vp
->v_size
) {
647 code
= afs_read(VTOAFS(ap
->a_vp
), ap
->a_uio
, ap
->a_cred
, 0);
650 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
651 printf("nbsd_read exit %p\n", ap
);
658 afs_nbsd_write(void *v
)
660 struct vop_write_args
/* {
661 * struct vnode *a_vp;
664 * kauth_cred_t a_cred;
668 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
669 printf("nbsd_write enter %p vp %p\n", ap
, ap
->a_vp
);
673 /* osi_FlushPages(VTOAFS(ap->a_vp), ap->a_cred); */
675 afs_write(VTOAFS(ap
->a_vp
), ap
->a_uio
, ap
->a_ioflag
, ap
->a_cred
, 0);
678 if (ap
->a_vp
->v_size
< ap
->a_uio
->uio_offset
) {
679 uvm_vnp_setsize(ap
->a_vp
, ap
->a_uio
->uio_offset
);
682 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
683 printf("nbsd_write exit %p\n", ap
);
690 afs_nbsd_ioctl(void *v
)
692 struct vop_ioctl_args
/* {
693 * struct vnode *a_vp;
697 * kauth_cred_t a_cred;
702 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
703 printf("nbsd_ioctl: enter %p vp %p\n", ap
, ap
->a_vp
);
706 /* in case we ever get in here... */
708 AFS_STATCNT(afs_ioctl
);
710 if (((ap
->a_command
>> 8) & 0xff) == 'V')
711 /* This is a VICEIOCTL call */
713 HandleIoctl(VTOAFS(ap
->a_vp
), ap
->a_command
,
714 (struct afs_ioctl
*)ap
->a_data
);
716 /* No-op call; just return. */
720 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
721 printf("nbsd_ioctl: exit %p\n", ap
);
728 afs_nbsd_fsync(void *v
)
730 struct vop_fsync_args
/* {
731 * struct vnode *a_vp;
732 * kauth_cred_t a_cred;
736 struct vnode
*vp
= ap
->a_vp
;
739 if (afs_debug
& AFSDEB_VNLAYER
)
740 printf("nbsd_fsync: enter %p vp %p\n", ap
, ap
->a_vp
);
742 wait
= (ap
->a_flags
& FSYNC_WAIT
) != 0;
746 code
= afs_fsync(VTOAFS(vp
), ap
->a_cred
);
749 if (afs_debug
& AFSDEB_VNLAYER
)
750 printf("nbsd_fsync: exit %p\n", ap
);
756 afs_nbsd_remove(void *v
)
758 struct vop_remove_args
/* {
759 * struct vnode *a_dvp;
760 * struct vnode *a_vp;
761 * struct componentname *a_cnp;
764 struct vnode
*vp
= ap
->a_vp
;
765 struct vnode
*dvp
= ap
->a_dvp
;
766 struct componentname
*cnp
= ap
->a_cnp
;
769 if (afs_debug
& AFSDEB_VNLAYER
)
770 printf("nbsd_remove: enter %p vp %p\n", ap
, ap
->a_vp
);
772 name
= cnstrdup(cnp
);
774 code
= afs_remove(VTOAFS(dvp
), name
, cnp
->cn_cred
);
776 cnstrfree(name
); name
= NULL
;
783 if (afs_debug
& AFSDEB_VNLAYER
)
784 printf("nbsd_remove: exit %p\n", ap
);
790 afs_nbsd_link(void *v
)
792 struct vop_link_args
/* {
793 * struct vnode *a_vp;
794 * struct vnode *a_tdvp;
795 * struct componentname *a_cnp;
798 struct vnode
*dvp
= ap
->a_dvp
;
799 struct vnode
*vp
= ap
->a_vp
;
800 struct componentname
*cnp
= ap
->a_cnp
;
803 if (afs_debug
& AFSDEB_VNLAYER
)
804 printf("nbsd_link: enter %p vp %p\n", ap
, ap
->a_vp
);
806 if (dvp
->v_mount
!= vp
->v_mount
) {
807 VOP_ABORTOP(vp
, cnp
);
811 if (vp
->v_type
== VDIR
) {
812 VOP_ABORTOP(vp
, cnp
);
817 if ((code
= vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
))) {
818 VOP_ABORTOP(dvp
, cnp
);
823 name
= cnstrdup(cnp
);
825 code
= afs_link(VTOAFS(vp
), VTOAFS(dvp
), name
, cnp
->cn_cred
);
827 cnstrfree(name
); name
= NULL
;
829 #if defined(AFS_NBSD60_ENV)
839 if (afs_debug
& AFSDEB_VNLAYER
)
840 printf("nbsd_link: exit %p\n", ap
);
846 afs_nbsd_rename(void *v
)
848 struct vop_rename_args
/* {
849 * struct vnode *a_fdvp;
850 * struct vnode *a_fvp;
851 * struct componentname *a_fcnp;
852 * struct vnode *a_tdvp;
853 * struct vnode *a_tvp;
854 * struct componentname *a_tcnp;
857 struct componentname
*fcnp
= ap
->a_fcnp
;
859 struct componentname
*tcnp
= ap
->a_tcnp
;
861 struct vnode
*tvp
= ap
->a_tvp
;
862 struct vnode
*tdvp
= ap
->a_tdvp
;
863 struct vnode
*fvp
= ap
->a_fvp
;
864 struct vnode
*fdvp
= ap
->a_fdvp
;
866 if (afs_debug
& AFSDEB_VNLAYER
)
867 printf("nbsd_rename: enter %p\n", ap
);
870 * Check for cross-device rename.
872 if ((fvp
->v_mount
!= tdvp
->v_mount
)
873 || (tvp
&& (fvp
->v_mount
!= tvp
->v_mount
))) {
876 VOP_ABORTOP(tdvp
, tcnp
); /* XXX, why not in NFS? */
883 VOP_ABORTOP(fdvp
, fcnp
); /* XXX, why not in NFS? */
889 * if fvp == tvp, we're just removing one name of a pair of
890 * directory entries for the same element. convert call into rename.
891 ( (pinched from NetBSD 1.0's ufs_rename())
894 if (fvp
->v_type
== VDIR
) {
899 /* Release destination completely. */
900 VOP_ABORTOP(tdvp
, tcnp
);
907 fcnp
->cn_flags
&= ~MODMASK
;
908 fcnp
->cn_flags
|= LOCKPARENT
| LOCKLEAF
;
909 fcnp
->cn_nameiop
= DELETE
;
910 #if !defined(AFS_NBSD60_ENV)
911 if ((fcnp
->cn_flags
& SAVESTART
) == 0)
912 panic("afs_rename: lost from startdir");
913 (void)relookup(fdvp
, &fvp
, fcnp
);
915 (void)relookup(fdvp
, &fvp
, fcnp
, 0);
917 code
= VOP_REMOVE(fdvp
, fvp
, fcnp
);
921 if ((code
= vn_lock(fvp
, LK_EXCLUSIVE
| LK_RETRY
)))
924 fname
= cnstrdup(fcnp
);
925 tname
= cnstrdup(tcnp
);
928 /* XXX use "from" or "to" creds? NFS uses "to" creds */
929 code
= afs_rename(VTOAFS(fdvp
), fname
, VTOAFS(tdvp
), tname
, tcnp
->cn_cred
);
932 cnstrfree(fname
); fname
= NULL
;
933 cnstrfree(tname
); tname
= NULL
;
935 goto abortit
; /* XXX */
946 if (afs_debug
& AFSDEB_VNLAYER
)
947 printf("nbsd_rename: exit %p\n", ap
);
953 afs_nbsd_mkdir(void *v
)
955 struct vop_mkdir_args
/* {
956 * struct vnode *a_dvp;
957 * struct vnode **a_vpp;
958 * struct componentname *a_cnp;
959 * struct vattr *a_vap;
961 struct vnode
*dvp
= ap
->a_dvp
;
962 struct vattr
*vap
= ap
->a_vap
;
963 struct componentname
*cnp
= ap
->a_cnp
;
969 if (afs_debug
& AFSDEB_VNLAYER
)
970 printf("nbsd_mkdir: enter %p dvp %p\n", ap
, ap
->a_dvp
);
972 #if !defined(AFS_NBSD60_ENV)
974 if ((cnp
->cn_flags
& HASBUF
) == 0)
975 panic("afs_nbsd_mkdir: no name");
979 name
= cnstrdup(cnp
);
981 code
= afs_mkdir(VTOAFS(dvp
), name
, vap
, &vcp
, cnp
->cn_cred
);
983 cnstrfree(name
); name
= NULL
;
985 VOP_ABORTOP(dvp
, cnp
);
990 *ap
->a_vpp
= AFSTOV(vcp
);
991 vn_lock(AFSTOV(vcp
), LK_EXCLUSIVE
| LK_RETRY
);
994 #if !defined(AFS_NBSD60_ENV)
995 if (code
|| (cnp
->cn_flags
& SAVESTART
) == 0) {
996 PNBUF_PUT(cnp
->cn_pnbuf
);
1002 if (afs_debug
& AFSDEB_VNLAYER
)
1003 printf("nbsd_mkdir: exit %p\n", ap
);
1009 afs_nbsd_rmdir(void *v
)
1011 struct vop_rmdir_args
/* {
1012 * struct vnode *a_dvp;
1013 * struct vnode *a_vp;
1014 * struct componentname *a_cnp;
1017 struct vnode
*vp
= ap
->a_vp
;
1018 struct vnode
*dvp
= ap
->a_dvp
;
1019 struct componentname
*cnp
= ap
->a_cnp
;
1023 if (afs_debug
& AFSDEB_VNLAYER
)
1024 printf("nbsd_rmdir: enter %p vp %p\n", ap
, ap
->a_vp
);
1033 name
= cnstrdup(cnp
);
1035 code
= afs_rmdir(VTOAFS(dvp
), name
, cnp
->cn_cred
);
1037 cnstrfree(name
); name
= NULL
;
1039 #if AFS_USE_NBSD_NAMECACHE
1049 if (afs_debug
& AFSDEB_VNLAYER
)
1050 printf("nbsd_rmdir: exit %p\n", ap
);
1056 afs_nbsd_symlink(void *v
)
1058 struct vop_symlink_args
/* {
1059 * struct vnode *a_dvp;
1060 * struct vnode **a_vpp;
1061 * struct componentname *a_cnp;
1062 * struct vattr *a_vap;
1065 struct vnode
*dvp
= ap
->a_dvp
;
1066 struct vnode
*nvp
= NULL
;
1068 struct componentname
*cnp
= ap
->a_cnp
;
1071 /* NFS ignores a_vpp; so do we. */
1073 if (afs_debug
& AFSDEB_VNLAYER
)
1074 printf("nbsd_symlink: enter %p dvp %p\n", ap
, ap
->a_dvp
);
1076 name
= cnstrdup(cnp
);
1079 afs_symlink(VTOAFS(dvp
), name
, ap
->a_vap
, ap
->a_target
, NULL
,
1082 code
= afs_lookup(VTOAFS(dvp
), name
, &vcp
, cnp
->cn_cred
);
1085 vn_lock(nvp
, LK_EXCLUSIVE
| LK_RETRY
);
1089 cnstrfree(name
); name
= NULL
;
1090 #if !defined(AFS_NBSD60_ENV)
1091 if (code
|| (cnp
->cn_flags
& SAVESTART
) == 0) {
1092 PNBUF_PUT(cnp
->cn_pnbuf
);
1100 if (afs_debug
& AFSDEB_VNLAYER
)
1101 printf("nbsd_symlink: exit %p\n", ap
);
1107 afs_nbsd_readdir(void *v
)
1109 struct vop_readdir_args
/* {
1110 * struct vnode *a_vp;
1111 * struct uio *a_uio;
1112 * kauth_cred_t a_cred;
1115 * u_long **a_cookies;
1118 struct vnode
*vp
= ap
->a_vp
;
1119 struct vcache
*vc
= VTOAFS(vp
);
1121 if (afs_debug
& AFSDEB_VNLAYER
)
1122 printf("nbsd_readdir: enter %p vp %p vc %p acred %p auio %p\n", ap
,
1123 vp
, vc
, ap
->a_cred
, ap
->a_uio
);
1126 #ifdef AFS_HAVE_COOKIES
1127 printf("readdir %p cookies %p ncookies %d\n", ap
->a_vp
, ap
->a_cookies
,
1130 afs_readdir(vc
, ap
->a_uio
, ap
->a_cred
, ap
->a_eofflag
,
1131 ap
->a_ncookies
, ap
->a_cookies
);
1134 afs_readdir(vc
, ap
->a_uio
, ap
->a_cred
, ap
->a_eofflag
);
1138 if (afs_debug
& AFSDEB_VNLAYER
)
1139 printf("nbsd_readdir: exit %p eofflag %d\n", ap
, *ap
->a_eofflag
);
1145 afs_nbsd_readlink(void *v
)
1147 struct vop_readlink_args
/* {
1148 * struct vnode *a_vp;
1149 * struct uio *a_uio;
1150 * kauth_cred_t a_cred;
1154 if (afs_debug
& AFSDEB_VNLAYER
)
1155 printf("nbsd_readlink: enter %p vp %p\n", ap
, ap
->a_vp
);
1158 code
= afs_readlink(VTOAFS(ap
->a_vp
), ap
->a_uio
, ap
->a_cred
);
1161 if (afs_debug
& AFSDEB_VNLAYER
)
1162 printf("nbsd_readlink: exit %p\n", ap
);
1167 extern int prtactive
;
1170 afs_nbsd_inactive(void *v
)
1172 struct vop_inactive_args
/* {
1173 * struct vnode *a_vp;
1175 struct vnode
*vp
= ap
->a_vp
;
1176 struct vcache
*vc
= VTOAFS(vp
);
1177 int haveGlock
= ISAFS_GLOCK();
1179 AFS_STATCNT(afs_inactive
);
1181 if (afs_debug
& AFSDEB_VNLAYER
)
1182 printf("nbsd_inactive: enter %p vp %p\n", ap
, ap
->a_vp
);
1184 if (prtactive
&& vp
->v_usecount
!= 0)
1185 vprint("afs_nbsd_inactive: pushing active", vp
);
1189 afs_InactiveVCache(vc
, NULL
); /* decrs ref counts */
1193 *ap
->a_recycle
= (vc
->f
.states
& CUnlinked
) != 0;
1195 #if defined(AFS_NBSD60_ENV)
1201 if (afs_debug
& AFSDEB_VNLAYER
)
1202 printf("nbsd_inactive: exit %p\n", ap
);
1208 afs_nbsd_reclaim(void *v
)
1210 struct vop_reclaim_args
/* {
1211 * struct vnode *a_vp;
1214 struct vnode
*vp
= ap
->a_vp
;
1215 struct vcache
*avc
= VTOAFS(vp
);
1216 int haveGlock
= ISAFS_GLOCK();
1217 int haveVlock
= CheckLock(&afs_xvcache
);
1219 if (afs_debug
& AFSDEB_VNLAYER
)
1220 printf("nbsd_reclaim: enter %p vp %p\n", ap
, vp
);
1225 ObtainWriteLock(&afs_xvcache
, 901);
1226 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
1227 code
= afs_FlushVCache(avc
, &slept
);
1230 if (avc
->f
.states
& CVInit
) {
1231 avc
->f
.states
&= ~CVInit
;
1232 afs_osi_Wakeup(&avc
->f
.states
);
1237 ReleaseWriteLock(&afs_xvcache
);
1241 if (vp
->v_tag
!= VT_AFS
) {
1242 vprint("afs reclaim", vp
);
1244 KASSERT(vp
->v_tag
== VT_AFS
);
1246 if (vp
->v_data
!= NULL
) {
1247 genfs_node_destroy(vp
);
1248 kmem_free(vp
->v_data
, sizeof(struct nbvdata
));
1249 vp
->v_data
= NULL
; /* remove from vnode */
1250 avc
->v
= NULL
; /* also drop the ptr to vnode */
1252 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1253 vprint("reclaim", vp
);
1257 #if AFS_USE_NBSD_NAMECACHE
1261 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1262 printf("nbsd_reclaim: exit %p\n", ap
);
1269 afs_nbsd_lock(void *v
)
1271 struct vop_lock_args
/* {
1272 * struct vnode *a_vp;
1278 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1279 printf("nbsd_lock: enter %p vp %p\n", ap
, ap
->a_vp
);
1282 KASSERT(VTOAFS(ap
->a_vp
) != NULL
);
1284 code
= genfs_lock(v
);
1286 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1287 printf("nbsd_lock: exit %p\n", ap
);
1294 afs_nbsd_unlock(void *v
)
1296 struct vop_unlock_args
/* {
1297 * struct vnode *a_vp;
1303 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1304 printf("nbsd_unlock: enter %p vp %p\n", ap
, ap
->a_vp
);
1307 KASSERT(VTOAFS(ap
->a_vp
) != NULL
);
1309 code
= genfs_unlock(v
);
1311 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1312 printf("nbsd_unlock: exit %p\n", ap
);
1319 afs_nbsd_islocked(void *v
)
1321 struct vop_islocked_args
/* {
1322 * struct vnode *a_vp;
1327 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1328 printf("nbsd_islocked: enter %p vp %p\n", ap
, ap
->a_vp
);
1331 code
= genfs_islocked(v
);
1333 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1334 printf("nbsd_islocked: exit %p\n", ap
);
1342 afs_nbsd_bmap(void *v
)
1344 struct vop_bmap_args
/* {
1345 * struct vnode *a_vp;
1347 * struct vnode **a_vpp;
1352 AFS_STATCNT(afs_bmap
);
1354 if (afs_debug
& AFSDEB_VNLAYER
)
1355 printf("nbsd_bmap: enter %p vp %p\n", ap
, ap
->a_vp
);
1358 *ap
->a_bnp
= ap
->a_bn
;
1360 *ap
->a_vpp
= ap
->a_vp
;
1361 if (ap
->a_runp
!= NULL
)
1362 *ap
->a_runp
= 1024 * 1024; /* XXX */
1364 if (ap
->a_runb
!= NULL
)
1369 if (afs_debug
& AFSDEB_VNLAYER
)
1370 printf("nbsd_bmap: exit %p\n", ap
);
1377 afs_nbsd_strategy(void *v
)
1379 struct vop_strategy_args
/* {
1384 AFS_STATCNT(afs_strategy
);
1386 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1387 printf("nbsd_strategy: enter %p vp %p\n", ap
, ap
->a_vp
);
1391 code
= afs_ustrategy(ap
->a_bp
, osi_curcred());
1394 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1395 printf("nbsd_strategy: exit %p vp %p\n", ap
, ap
->a_vp
);
1402 afs_nbsd_print(void *v
)
1404 struct vop_print_args
/* {
1405 * struct vnode *a_vp;
1407 struct vnode
*vp
= ap
->a_vp
;
1408 struct vcache
*vc
= VTOAFS(ap
->a_vp
);
1410 printf("tag %d, fid: %d.%x.%x.%x, ", vp
->v_tag
, vc
->f
.fid
.Cell
,
1411 vc
->f
.fid
.Fid
.Volume
, vc
->f
.fid
.Fid
.Vnode
,
1412 vc
->f
.fid
.Fid
.Unique
);
1413 #ifdef AFS_NBSD50_ENV
1414 #if defined(DDB) && defined(LOCKDEBUG)
1415 lockdebug_lock_print(&vc
->rwlock
, printf
);
1418 lockmgr_printinfo(&vc
->rwlock
);
1425 * Return POSIX pathconf information applicable to ufs filesystems.
1428 afs_nbsd_pathconf(void *v
)
1430 struct vop_pathconf_args
/* {
1431 * struct vnode *a_vp;
1437 AFS_STATCNT(afs_cntl
);
1439 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1440 printf("nbsd_pathconf: enter %p vp %p\n", ap
, ap
->a_vp
);
1443 switch (ap
->a_name
) {
1445 *ap
->a_retval
= LINK_MAX
;
1448 *ap
->a_retval
= NAME_MAX
;
1451 *ap
->a_retval
= PATH_MAX
;
1453 case _PC_CHOWN_RESTRICTED
:
1469 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1470 printf("nbsd_pathconf: exit %p\n", ap
);
1477 afs_lockctl(struct vcache
*avc
, struct AFS_FLOCK
*af
, int acmd
,
1478 afs_ucred_t
*acred
, pid_t clid
);
1481 * Advisory record locking support (fcntl() POSIX style)
1484 afs_nbsd_advlock(void *v
)
1486 struct vop_advlock_args
/* {
1487 * struct vnode *a_vp;
1490 * struct flock *a_fl;
1495 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1496 printf("nbsd_pathconf: enter %p vp %p\n", ap
, ap
->a_vp
);
1500 code
= afs_lockctl(VTOAFS(ap
->a_vp
), ap
->a_fl
, ap
->a_op
, osi_curcred(),
1501 (uintptr_t)ap
->a_id
);
1504 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
1505 printf("nbsd_pathconf: exit %p\n", ap
);