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"
103 #include "afs/sysincludes.h" /* Standard vendor system headers */
104 #include "afs/afsincludes.h" /* Afs-based standard headers */
105 #include "afs/afs_stats.h" /* statistics */
107 #include <sys/malloc.h>
108 #include <sys/namei.h>
109 #include <sys/pool.h>
110 #include <miscfs/genfs/genfs.h>
113 #include "afs/afs_cbqueue.h"
114 #include "afs/nfsclient.h"
115 #include "afs/afs_osidnlc.h"
117 extern int afs_FlushVS(struct vcache *tvc);
119 #define M_AFSNODE (M_TEMP-1) /* XXX */
121 int afs_nbsd_lookup(void *);
122 int afs_nbsd_create(void *);
123 int afs_nbsd_mknod(void *);
124 int afs_nbsd_open(void *);
125 int afs_nbsd_close(void *);
126 int afs_nbsd_access(void *);
127 int afs_nbsd_getattr(void *);
128 int afs_nbsd_setattr(void *);
129 int afs_nbsd_read(void *);
130 int afs_nbsd_write(void *);
131 int afs_nbsd_ioctl(void *);
132 int afs_nbsd_select(void *);
133 int afs_nbsd_fsync(void *);
134 int afs_nbsd_remove(void *);
135 int afs_nbsd_link(void *);
136 int afs_nbsd_rename(void *);
137 int afs_nbsd_mkdir(void *);
138 int afs_nbsd_rmdir(void *);
139 int afs_nbsd_symlink(void *);
140 int afs_nbsd_readdir(void *);
141 int afs_nbsd_readlink(void *);
142 int afs_nbsd_inactive(void *);
143 int afs_nbsd_reclaim(void *);
144 int afs_nbsd_lock(void *);
145 int afs_nbsd_unlock(void *);
146 int afs_nbsd_bmap(void *);
147 int afs_nbsd_strategy(void *);
148 int afs_nbsd_print(void *);
149 int afs_nbsd_islocked(void *);
150 int afs_nbsd_pathconf(void *);
151 int afs_nbsd_advlock(void *);
154 int afs_nbsd_getpages(void*);
163 * vop_mmap_desc (mmap'd IO)
173 #define afs_nbsd_opnotsupp \
174 ((int (*) __P((void *)))eopnotsupp)
175 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
177 /* Global vfs data structures for AFS. */
178 int (**afs_vnodeop_p) __P((void *));
179 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
180 {&vop_default_desc, vn_default_error},
181 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
182 {&vop_create_desc, afs_nbsd_create}, /* create */
183 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
184 {&vop_open_desc, afs_nbsd_open}, /* open */
185 {&vop_close_desc, afs_nbsd_close}, /* close */
186 {&vop_access_desc, afs_nbsd_access}, /* access */
187 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
188 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
189 {&vop_read_desc, afs_nbsd_read}, /* read */
190 {&vop_write_desc, afs_nbsd_write}, /* write */
191 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
192 {&vop_poll_desc, afs_nbsd_select}, /* select */
193 {&vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */
194 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
195 {&vop_remove_desc, afs_nbsd_remove}, /* remove */
196 {&vop_link_desc, afs_nbsd_link}, /* link */
197 {&vop_rename_desc, afs_nbsd_rename}, /* rename */
198 {&vop_mkdir_desc, afs_nbsd_mkdir}, /* mkdir */
199 {&vop_rmdir_desc, afs_nbsd_rmdir}, /* rmdir */
200 {&vop_symlink_desc, afs_nbsd_symlink}, /* symlink */
201 {&vop_readdir_desc, afs_nbsd_readdir}, /* readdir */
202 {&vop_readlink_desc, afs_nbsd_readlink}, /* readlink */
203 {&vop_abortop_desc, genfs_abortop}, /* abortop */
204 {&vop_inactive_desc, afs_nbsd_inactive}, /* inactive */
205 {&vop_reclaim_desc, afs_nbsd_reclaim}, /* reclaim */
206 {&vop_lock_desc, afs_nbsd_lock}, /* lock */
207 {&vop_unlock_desc, afs_nbsd_unlock}, /* unlock */
208 {&vop_bmap_desc, afs_nbsd_bmap}, /* bmap */
209 {&vop_strategy_desc, afs_nbsd_strategy}, /* strategy */
210 {&vop_print_desc, afs_nbsd_print}, /* print */
211 {&vop_islocked_desc, afs_nbsd_islocked}, /* islocked */
212 {&vop_pathconf_desc, afs_nbsd_pathconf}, /* pathconf */
213 {&vop_advlock_desc, afs_nbsd_advlock}, /* advlock */
215 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
217 {&vop_bwrite_desc, vn_bwrite}, /* bwrite */
219 { &vop_getpages_desc, ffs_getpages }, /* getpages */
220 { &vop_putpages_desc, genfs_putpages }, /* putpages */
222 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
224 struct vnodeopv_desc afs_vnodeop_opv_desc =
225 { &afs_vnodeop_p, afs_vnodeop_entries };
228 struct componentname *cnp = ap->a_cnp; \
230 name = PNBUF_GET(); \
231 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
232 name[cnp->cn_namelen] = '\0'
234 #define DROPNAME() PNBUF_PUT(name)
235 #define DROPCNP PNBUF_PUT
237 /* toss "stale" pages by shrinking the vnode uobj to a 0-length
238 * region (see uvm_vnp_setsize in uvm_vnode.c) */
239 #define VNP_UNCACHE(vp) \
241 struct uvm_object *uobj = &vp->v_uobj; \
242 simple_lock(&uobj->vmobjlock); \
243 VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
244 simple_unlock(&uobj->vmobjlock); \
247 /* psuedo-vnop, wherein we learn that obsd and nbsd disagree
248 * about vnode refcounting */
250 afs_nbsd_getnewvnode(struct vcache *tvc)
252 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
253 /* no vnodes available, force an alloc (limits be damned)! */
256 afs_warn("afs_nbsd_getnewvnode: vp %lx refs %d (soon to be 1)\n", tvc->v,
258 simple_lock(&tvc->v->v_interlock);
259 tvc->v->v_data = (void *)tvc;
260 tvc->v->v_usecount = 1; /* !locked, and vref w/v_usecount < 1 panics */
261 simple_unlock(&tvc->v->v_interlock);
267 afs_nbsd_lookup(void *v)
269 struct vop_lookup_args /* {
270 * struct vnodeop_desc * a_desc;
271 * struct vnode *a_dvp;
272 * struct vnode **a_vpp;
273 * struct componentname *a_cnp;
277 struct vnode *vp, *dvp;
278 int flags = ap->a_cnp->cn_flags;
279 int lockparent; /* 1 => lockparent flag is set */
281 afs_warn("afs_nbsd_lookup enter\n");
284 lockparent = flags & LOCKPARENT;
285 if (ap->a_dvp->v_type != VDIR) {
291 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
292 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
293 name, dvp->v_usecount);
295 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
298 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
299 && (flags & ISLASTCN) && code == ENOENT)
301 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
302 cnp->cn_flags |= SAVENAME;
307 vp = AFSTOV(vcp); /* always get a node if no error */
310 * The parent directory comes in locked. We unlock it on return
311 * unless the caller wants it left locked.
312 * we also always return the vnode locked.
316 /* they're the same; afs_lookup() already ref'ed the leaf.
317 * It came in locked, so we don't need to ref OR lock it */
318 if (afs_debug & AFSDEB_VNLAYER)
319 printf("ref'ed %p as .\n", dvp);
321 if (!lockparent || !(flags & ISLASTCN)) {
322 VOP_UNLOCK(dvp, 0); /* done with parent. */
325 simple_lock(&vp->v_interlock);
326 vp->v_usecount = (vp->v_usecount < 1) ? 1 : (vp->v_usecount+1);
327 simple_unlock(&vp->v_interlock);
328 if (!VOP_ISLOCKED(vp)) {
329 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
331 /* vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); *//* always return the child locked */
333 afs_warn("lookup: vp %lx is locked\n", vp);
335 afs_warn("lookup: after islocked\n");
336 if (afs_debug & AFSDEB_VNLAYER)
337 printf("locked ret %p from lookup\n", vp);
341 if (((cnp->cn_nameiop == RENAME && (flags & ISLASTCN))
342 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
343 cnp->cn_flags |= SAVENAME;
346 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
347 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
352 afs_nbsd_create(void *v)
354 struct vop_create_args /* {
355 * struct vnode *a_dvp;
356 * struct vnode **a_vpp;
357 * struct componentname *a_cnp;
358 * struct vattr *a_vap;
362 struct vnode *dvp = ap->a_dvp;
365 if (afs_debug & AFSDEB_VNLAYER)
366 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
368 /* vnode layer handles excl/nonexcl */
372 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
376 VOP_ABORTOP(dvp, cnp);
383 *ap->a_vpp = AFSTOV(vcp);
384 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
388 if ((cnp->cn_flags & SAVESTART) == 0)
392 if (afs_debug & AFSDEB_VNLAYER)
393 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
398 afs_nbsd_mknod(void *v)
400 struct vop_mknod_args /* {
401 * struct vnode *a_dvp;
402 * struct vnode **a_vpp;
403 * struct componentname *a_cnp;
404 * struct vattr *a_vap;
412 afs_nbsd_open(void *v)
414 struct vop_open_args /* {
415 * struct vnode *a_vp;
417 * struct ucred *a_cred;
421 struct vcache *vc = VTOAFS(ap->a_vp);
424 code = afs_open(&vc, ap->a_mode, ap->a_cred);
426 if (AFSTOV(vc) != ap->a_vp)
427 panic("AFS open changed vnode!");
434 afs_nbsd_close(void *v)
436 struct vop_close_args /* {
437 * struct vnode *a_vp;
439 * kauth_cred_t a_cred;
445 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
451 afs_nbsd_access(void *v)
453 struct vop_access_args /* {
454 * struct vnode *a_vp;
456 * kauth_cred_t a_cred;
462 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
468 afs_nbsd_getattr(void *v)
470 struct vop_getattr_args /* {
471 * struct vnode *a_vp;
472 * struct vattr *a_vap;
473 * kauth_cred_t a_cred;
479 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
485 afs_nbsd_setattr(void *v)
487 struct vop_setattr_args /* {
488 * struct vnode *a_vp;
489 * struct vattr *a_vap;
490 * kauth_cred_t a_cred;
496 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
502 afs_nbsd_read(void *v)
504 struct vop_read_args /* {
505 * struct vnode *a_vp;
508 * kauth_cred_t a_cred;
514 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
521 afs_nbsd_write(void *v)
523 struct vop_write_args /* {
524 * struct vnode *a_vp;
527 * kauth_cred_t a_cred;
532 /* all pages are really "stale?" */
533 VNP_UNCACHE(ap->a_vp);
535 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
539 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
545 afs_nbsd_ioctl(void *v)
547 struct vop_ioctl_args /* {
548 * struct vnode *a_vp;
552 * kauth_cred_t a_cred;
557 /* in case we ever get in here... */
559 AFS_STATCNT(afs_ioctl);
561 if (((ap->a_command >> 8) & 0xff) == 'V')
562 /* This is a VICEIOCTL call */
564 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
565 (struct afs_ioctl *)ap->a_data);
567 /* No-op call; just return. */
574 afs_nbsd_select(void *v)
580 afs_nbsd_fsync(void *v)
582 struct vop_fsync_args /* {
583 * struct vnode *a_vp;
584 * kauth_cred_t a_cred;
588 struct vnode *vp = ap->a_vp;
591 wait = (ap->a_flags & FSYNC_WAIT) != 0;
595 code = afs_fsync(VTOAFS(vp), ap->a_cred);
602 afs_nbsd_remove(void *v)
604 struct vop_remove_args /* {
605 * struct vnode *a_dvp;
606 * struct vnode *a_vp;
607 * struct componentname *a_cnp;
610 struct vnode *vp = ap->a_vp;
611 struct vnode *dvp = ap->a_dvp;
615 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
628 afs_nbsd_link(void *v)
630 struct vop_link_args /* {
631 * struct vnode *a_vp;
632 * struct vnode *a_tdvp;
633 * struct componentname *a_cnp;
636 struct vnode *dvp = ap->a_dvp;
637 struct vnode *vp = ap->a_vp;
640 if (dvp->v_mount != vp->v_mount) {
641 VOP_ABORTOP(vp, cnp);
645 if (vp->v_type == VDIR) {
646 VOP_ABORTOP(vp, cnp);
650 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) {
651 VOP_ABORTOP(dvp, cnp);
656 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
669 afs_nbsd_rename(void *v)
671 struct vop_rename_args /* {
672 * struct vnode *a_fdvp;
673 * struct vnode *a_fvp;
674 * struct componentname *a_fcnp;
675 * struct vnode *a_tdvp;
676 * struct vnode *a_tvp;
677 * struct componentname *a_tcnp;
680 struct componentname *fcnp = ap->a_fcnp;
682 struct componentname *tcnp = ap->a_tcnp;
684 struct vnode *tvp = ap->a_tvp;
685 struct vnode *tdvp = ap->a_tdvp;
686 struct vnode *fvp = ap->a_fvp;
687 struct vnode *fdvp = ap->a_fdvp;
690 * Check for cross-device rename.
692 if ((fvp->v_mount != tdvp->v_mount)
693 || (tvp && (fvp->v_mount != tvp->v_mount))) {
696 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
703 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
709 * if fvp == tvp, we're just removing one name of a pair of
710 * directory entries for the same element. convert call into rename.
711 ( (pinched from NetBSD 1.0's ufs_rename())
714 if (fvp->v_type == VDIR) {
719 /* Release destination completely. */
720 VOP_ABORTOP(tdvp, tcnp);
727 fcnp->cn_flags &= ~MODMASK;
728 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
729 if ((fcnp->cn_flags & SAVESTART) == 0)
730 panic("afs_rename: lost from startdir");
731 fcnp->cn_nameiop = DELETE;
732 (void)relookup(fdvp, &fvp, fcnp);
733 return (VOP_REMOVE(fdvp, fvp, fcnp));
736 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY)))
739 /* XXX GETNAME() ? */
740 MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
741 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
742 fname[fcnp->cn_namelen] = '\0';
743 MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
744 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
745 tname[tcnp->cn_namelen] = '\0';
749 /* XXX use "from" or "to" creds? NFS uses "to" creds */
751 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname,
759 goto abortit; /* XXX */
772 afs_nbsd_mkdir(void *v)
774 struct vop_mkdir_args /* {
775 * struct vnode *a_dvp;
776 * struct vnode **a_vpp;
777 * struct componentname *a_cnp;
778 * struct vattr *a_vap;
780 struct vnode *dvp = ap->a_dvp;
781 struct vattr *vap = ap->a_vap;
787 if ((cnp->cn_flags & HASBUF) == 0)
788 panic("afs_nbsd_mkdir: no name");
791 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
794 VOP_ABORTOP(dvp, cnp);
800 *ap->a_vpp = AFSTOV(vcp);
801 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
811 afs_nbsd_rmdir(void *v)
813 struct vop_rmdir_args /* {
814 * struct vnode *a_dvp;
815 * struct vnode *a_vp;
816 * struct componentname *a_cnp;
819 struct vnode *vp = ap->a_vp;
820 struct vnode *dvp = ap->a_dvp;
832 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
841 afs_nbsd_symlink(void *v)
843 struct vop_symlink_args /* {
844 * struct vnode *a_dvp;
845 * struct vnode **a_vpp;
846 * struct componentname *a_cnp;
847 * struct vattr *a_vap;
850 struct vnode *dvp = ap->a_dvp;
852 /* NFS ignores a_vpp; so do we. */
857 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
867 afs_nbsd_readdir(void *v)
869 struct vop_readdir_args /* {
870 * struct vnode *a_vp;
872 * kauth_cred_t a_cred;
875 * u_long **a_cookies;
880 #ifdef AFS_HAVE_COOKIES
881 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
884 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
885 ap->a_ncookies, ap->a_cookies);
888 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
895 afs_nbsd_readlink(void *v)
897 struct vop_readlink_args /* {
898 * struct vnode *a_vp;
900 * kauth_cred_t a_cred;
905 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
910 extern int prtactive;
913 afs_nbsd_inactive(void *v)
915 struct vop_inactive_args /* {
916 * struct vnode *a_vp;
918 struct vnode *vp = ap->a_vp;
919 struct vcache *vc = VTOAFS(vp);
920 int haveGlock = ISAFS_GLOCK();
922 AFS_STATCNT(afs_inactive);
924 if (prtactive && vp->v_usecount != 0)
925 vprint("afs_nbsd_inactive(): pushing active", vp);
929 afs_InactiveVCache(vc, 0); /* decrs ref counts */
933 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
938 afs_nbsd_reclaim(void *v)
940 struct vop_reclaim_args /* {
941 * struct vnode *a_vp;
944 struct vnode *vp = ap->a_vp;
945 struct vcache *avc = VTOAFS(vp);
946 int haveGlock = ISAFS_GLOCK();
947 int haveVlock = CheckLock(&afs_xvcache);
950 printf("reclaim usecount %d\n", vp->v_usecount);
951 /* OK, there are no internal vrefCounts, so there shouldn't
952 * be any more refs here. */
953 vp->v_data = NULL; /* remove from vnode */
954 avc->v = NULL; /* also drop the ptr to vnode */
960 ObtainWriteLock(&afs_xvcache, 901);
961 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
962 code = afs_FlushVS(avc);
964 ReleaseWriteLock(&afs_xvcache);
972 afs_nbsd_lock(void *v)
974 struct vop_lock_args /* {
975 * struct vnode *a_vp;
980 return (genfs_lock(v));
984 afs_nbsd_unlock(void *v)
986 struct vop_unlock_args /* {
987 * struct vnode *a_vp;
992 return (genfs_unlock(v));
996 afs_nbsd_bmap(void *v)
998 struct vop_bmap_args /* {
999 * struct vnode *a_vp;
1001 * struct vnode **a_vpp;
1005 struct vcache *vcp = VTOAFS(ap->a_vp);
1007 AFS_STATCNT(afs_bmap);
1009 /* borrowed from DARWIN--why notyet? */
1011 *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE);
1014 *ap->a_vpp = ap->a_vp;
1016 if (ap->a_runp != NULL)
1019 if (ap->a_runb != NULL)
1027 afs_nbsd_strategy(void *v)
1029 struct vop_strategy_args /* {
1032 struct buf *abp = ap->a_bp;
1034 struct iovec tiovec[1];
1035 struct vcache *tvc = VTOAFS(abp->b_vp);
1036 afs_ucred_t credp = osi_curcred();
1037 long len = abp->b_bcount;
1040 AFS_STATCNT(afs_strategy);
1042 tuio.afsio_iov = tiovec;
1043 tuio.afsio_iovcnt = 1;
1044 tuio.afsio_resid = len;
1045 tiovec[0].iov_base = abp->b_un.b_addr;
1046 tiovec[0].iov_len = len;
1047 UIO_SETUP_SYSSPACE(&tuio);
1050 if ((abp->b_flags & B_READ) == B_READ) {
1051 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1052 if (code == 0 && tuio.afsio_resid > 0)
1053 bzero(abp->b_un.b_addr + len - tuio.afsio_resid,
1056 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1059 ReleaseWriteLock(&tvc->lock);
1060 AFS_RELE(AFSTOV(tvc));
1065 afs_nbsd_print(void *v)
1067 struct vop_print_args /* {
1068 * struct vnode *a_vp;
1070 struct vnode *vp = ap->a_vp;
1071 struct vcache *vc = VTOAFS(ap->a_vp);
1073 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1074 (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
1075 (int)vc->f.fid.Fid.Unique);
1076 lockmgr_printinfo(&vc->rwlock);
1082 afs_nbsd_islocked(void *v)
1084 struct vop_islocked_args /* {
1085 * struct vnode *a_vp;
1087 return (genfs_islocked(v));
1091 * Return POSIX pathconf information applicable to ufs filesystems.
1094 afs_nbsd_pathconf(void *v)
1096 struct vop_pathconf_args /* {
1097 * struct vnode *a_vp;
1101 AFS_STATCNT(afs_cntl);
1102 switch (ap->a_name) {
1104 *ap->a_retval = LINK_MAX;
1107 *ap->a_retval = NAME_MAX;
1110 *ap->a_retval = PATH_MAX;
1112 case _PC_CHOWN_RESTRICTED:
1128 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1129 afs_ucred_t *acred, pid_t clid);
1132 * Advisory record locking support (fcntl() POSIX style)
1135 afs_nbsd_advlock(void *v)
1137 struct vop_advlock_args /* {
1138 * struct vnode *a_vp;
1141 * struct flock *a_fl;
1148 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),