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 #ifdef AFS_DISCON_ENV
118 extern int afs_FlushVS(struct vcache *tvc);
121 #define M_AFSNODE (M_TEMP-1) /* XXX */
123 int afs_nbsd_lookup(void *);
124 int afs_nbsd_create(void *);
125 int afs_nbsd_mknod(void *);
126 int afs_nbsd_open(void *);
127 int afs_nbsd_close(void *);
128 int afs_nbsd_access(void *);
129 int afs_nbsd_getattr(void *);
130 int afs_nbsd_setattr(void *);
131 int afs_nbsd_read(void *);
132 int afs_nbsd_write(void *);
133 int afs_nbsd_ioctl(void *);
134 int afs_nbsd_select(void *);
135 int afs_nbsd_fsync(void *);
136 int afs_nbsd_remove(void *);
137 int afs_nbsd_link(void *);
138 int afs_nbsd_rename(void *);
139 int afs_nbsd_mkdir(void *);
140 int afs_nbsd_rmdir(void *);
141 int afs_nbsd_symlink(void *);
142 int afs_nbsd_readdir(void *);
143 int afs_nbsd_readlink(void *);
144 int afs_nbsd_inactive(void *);
145 int afs_nbsd_reclaim(void *);
146 int afs_nbsd_lock(void *);
147 int afs_nbsd_unlock(void *);
148 int afs_nbsd_bmap(void *);
149 int afs_nbsd_strategy(void *);
150 int afs_nbsd_print(void *);
151 int afs_nbsd_islocked(void *);
152 int afs_nbsd_pathconf(void *);
153 int afs_nbsd_advlock(void *);
156 int afs_nbsd_getpages(void*);
165 * vop_mmap_desc (mmap'd IO)
175 #define afs_nbsd_opnotsupp \
176 ((int (*) __P((void *)))eopnotsupp)
177 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
179 /* Global vfs data structures for AFS. */
180 int (**afs_vnodeop_p) __P((void *));
181 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
182 {&vop_default_desc, vn_default_error},
183 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
184 {&vop_create_desc, afs_nbsd_create}, /* create */
185 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
186 {&vop_open_desc, afs_nbsd_open}, /* open */
187 {&vop_close_desc, afs_nbsd_close}, /* close */
188 {&vop_access_desc, afs_nbsd_access}, /* access */
189 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
190 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
191 {&vop_read_desc, afs_nbsd_read}, /* read */
192 {&vop_write_desc, afs_nbsd_write}, /* write */
193 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
194 {&vop_poll_desc, afs_nbsd_select}, /* select */
195 {&vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */
196 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
197 {&vop_remove_desc, afs_nbsd_remove}, /* remove */
198 {&vop_link_desc, afs_nbsd_link}, /* link */
199 {&vop_rename_desc, afs_nbsd_rename}, /* rename */
200 {&vop_mkdir_desc, afs_nbsd_mkdir}, /* mkdir */
201 {&vop_rmdir_desc, afs_nbsd_rmdir}, /* rmdir */
202 {&vop_symlink_desc, afs_nbsd_symlink}, /* symlink */
203 {&vop_readdir_desc, afs_nbsd_readdir}, /* readdir */
204 {&vop_readlink_desc, afs_nbsd_readlink}, /* readlink */
205 {&vop_abortop_desc, genfs_abortop}, /* abortop */
206 {&vop_inactive_desc, afs_nbsd_inactive}, /* inactive */
207 {&vop_reclaim_desc, afs_nbsd_reclaim}, /* reclaim */
208 {&vop_lock_desc, afs_nbsd_lock}, /* lock */
209 {&vop_unlock_desc, afs_nbsd_unlock}, /* unlock */
210 {&vop_bmap_desc, afs_nbsd_bmap}, /* bmap */
211 {&vop_strategy_desc, afs_nbsd_strategy}, /* strategy */
212 {&vop_print_desc, afs_nbsd_print}, /* print */
213 {&vop_islocked_desc, afs_nbsd_islocked}, /* islocked */
214 {&vop_pathconf_desc, afs_nbsd_pathconf}, /* pathconf */
215 {&vop_advlock_desc, afs_nbsd_advlock}, /* advlock */
217 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
219 {&vop_bwrite_desc, vn_bwrite}, /* bwrite */
221 { &vop_getpages_desc, ffs_getpages }, /* getpages */
222 { &vop_putpages_desc, genfs_putpages }, /* putpages */
224 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
226 struct vnodeopv_desc afs_vnodeop_opv_desc =
227 { &afs_vnodeop_p, afs_vnodeop_entries };
230 struct componentname *cnp = ap->a_cnp; \
232 name = PNBUF_GET(); \
233 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
234 name[cnp->cn_namelen] = '\0'
236 #define DROPNAME() PNBUF_PUT(name)
237 #define DROPCNP PNBUF_PUT
239 /* toss "stale" pages by shrinking the vnode uobj to a 0-length
240 * region (see uvm_vnp_setsize in uvm_vnode.c) */
241 #define VNP_UNCACHE(vp) \
243 struct uvm_object *uobj = &vp->v_uobj; \
244 simple_lock(&uobj->vmobjlock); \
245 VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
246 simple_unlock(&uobj->vmobjlock); \
249 /* psuedo-vnop, wherein we learn that obsd and nbsd disagree
250 * about vnode refcounting */
252 afs_nbsd_getnewvnode(struct vcache *tvc)
254 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
255 /* no vnodes available, force an alloc (limits be damned)! */
258 afs_warn("afs_nbsd_getnewvnode: vp %lx refs %d (soon to be 1)\n", tvc->v,
260 simple_lock(&tvc->v->v_interlock);
261 tvc->v->v_data = (void *)tvc;
262 tvc->v->v_usecount = 1; /* !locked, and vref w/v_usecount < 1 panics */
263 simple_unlock(&tvc->v->v_interlock);
269 afs_nbsd_lookup(void *v)
271 struct vop_lookup_args /* {
272 * struct vnodeop_desc * a_desc;
273 * struct vnode *a_dvp;
274 * struct vnode **a_vpp;
275 * struct componentname *a_cnp;
279 struct vnode *vp, *dvp;
280 int flags = ap->a_cnp->cn_flags;
281 int lockparent; /* 1 => lockparent flag is set */
283 afs_warn("afs_nbsd_lookup enter\n");
286 lockparent = flags & LOCKPARENT;
287 if (ap->a_dvp->v_type != VDIR) {
293 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
294 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
295 name, dvp->v_usecount);
297 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
300 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
301 && (flags & ISLASTCN) && code == ENOENT)
303 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
304 cnp->cn_flags |= SAVENAME;
309 vp = AFSTOV(vcp); /* always get a node if no error */
312 * The parent directory comes in locked. We unlock it on return
313 * unless the caller wants it left locked.
314 * we also always return the vnode locked.
318 /* they're the same; afs_lookup() already ref'ed the leaf.
319 * It came in locked, so we don't need to ref OR lock it */
320 if (afs_debug & AFSDEB_VNLAYER)
321 printf("ref'ed %p as .\n", dvp);
323 if (!lockparent || !(flags & ISLASTCN)) {
324 VOP_UNLOCK(dvp, 0); /* done with parent. */
327 simple_lock(&vp->v_interlock);
328 vp->v_usecount = (vp->v_usecount < 1) ? 1 : (vp->v_usecount+1);
329 simple_unlock(&vp->v_interlock);
330 if (!VOP_ISLOCKED(vp)) {
331 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
333 /* vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); *//* always return the child locked */
335 afs_warn("lookup: vp %lx is locked\n", vp);
337 afs_warn("lookup: after islocked\n");
338 if (afs_debug & AFSDEB_VNLAYER)
339 printf("locked ret %p from lookup\n", vp);
343 if (((cnp->cn_nameiop == RENAME && (flags & ISLASTCN))
344 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
345 cnp->cn_flags |= SAVENAME;
348 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
349 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
354 afs_nbsd_create(void *v)
356 struct vop_create_args /* {
357 * struct vnode *a_dvp;
358 * struct vnode **a_vpp;
359 * struct componentname *a_cnp;
360 * struct vattr *a_vap;
364 struct vnode *dvp = ap->a_dvp;
367 if (afs_debug & AFSDEB_VNLAYER)
368 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
370 /* vnode layer handles excl/nonexcl */
374 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
378 VOP_ABORTOP(dvp, cnp);
385 *ap->a_vpp = AFSTOV(vcp);
386 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
390 if ((cnp->cn_flags & SAVESTART) == 0)
394 if (afs_debug & AFSDEB_VNLAYER)
395 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
400 afs_nbsd_mknod(void *v)
402 struct vop_mknod_args /* {
403 * struct vnode *a_dvp;
404 * struct vnode **a_vpp;
405 * struct componentname *a_cnp;
406 * struct vattr *a_vap;
414 afs_nbsd_open(void *v)
416 struct vop_open_args /* {
417 * struct vnode *a_vp;
419 * struct ucred *a_cred;
423 struct vcache *vc = VTOAFS(ap->a_vp);
426 code = afs_open(&vc, ap->a_mode, ap->a_cred);
428 if (AFSTOV(vc) != ap->a_vp)
429 panic("AFS open changed vnode!");
436 afs_nbsd_close(void *v)
438 struct vop_close_args /* {
439 * struct vnode *a_vp;
441 * kauth_cred_t a_cred;
447 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
453 afs_nbsd_access(void *v)
455 struct vop_access_args /* {
456 * struct vnode *a_vp;
458 * kauth_cred_t a_cred;
464 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
470 afs_nbsd_getattr(void *v)
472 struct vop_getattr_args /* {
473 * struct vnode *a_vp;
474 * struct vattr *a_vap;
475 * kauth_cred_t a_cred;
481 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
487 afs_nbsd_setattr(void *v)
489 struct vop_setattr_args /* {
490 * struct vnode *a_vp;
491 * struct vattr *a_vap;
492 * kauth_cred_t a_cred;
498 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
504 afs_nbsd_read(void *v)
506 struct vop_read_args /* {
507 * struct vnode *a_vp;
510 * kauth_cred_t a_cred;
516 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
523 afs_nbsd_write(void *v)
525 struct vop_write_args /* {
526 * struct vnode *a_vp;
529 * kauth_cred_t a_cred;
534 /* all pages are really "stale?" */
535 VNP_UNCACHE(ap->a_vp);
537 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
541 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
547 afs_nbsd_ioctl(void *v)
549 struct vop_ioctl_args /* {
550 * struct vnode *a_vp;
554 * kauth_cred_t a_cred;
559 /* in case we ever get in here... */
561 AFS_STATCNT(afs_ioctl);
563 if (((ap->a_command >> 8) & 0xff) == 'V')
564 /* This is a VICEIOCTL call */
566 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
567 (struct afs_ioctl *)ap->a_data);
569 /* No-op call; just return. */
576 afs_nbsd_select(void *v)
582 afs_nbsd_fsync(void *v)
584 struct vop_fsync_args /* {
585 * struct vnode *a_vp;
586 * kauth_cred_t a_cred;
590 struct vnode *vp = ap->a_vp;
593 wait = (ap->a_flags & FSYNC_WAIT) != 0;
597 code = afs_fsync(VTOAFS(vp), ap->a_cred);
604 afs_nbsd_remove(void *v)
606 struct vop_remove_args /* {
607 * struct vnode *a_dvp;
608 * struct vnode *a_vp;
609 * struct componentname *a_cnp;
612 struct vnode *vp = ap->a_vp;
613 struct vnode *dvp = ap->a_dvp;
617 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
630 afs_nbsd_link(void *v)
632 struct vop_link_args /* {
633 * struct vnode *a_vp;
634 * struct vnode *a_tdvp;
635 * struct componentname *a_cnp;
638 struct vnode *dvp = ap->a_dvp;
639 struct vnode *vp = ap->a_vp;
642 if (dvp->v_mount != vp->v_mount) {
643 VOP_ABORTOP(vp, cnp);
647 if (vp->v_type == VDIR) {
648 VOP_ABORTOP(vp, cnp);
652 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) {
653 VOP_ABORTOP(dvp, cnp);
658 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
671 afs_nbsd_rename(void *v)
673 struct vop_rename_args /* {
674 * struct vnode *a_fdvp;
675 * struct vnode *a_fvp;
676 * struct componentname *a_fcnp;
677 * struct vnode *a_tdvp;
678 * struct vnode *a_tvp;
679 * struct componentname *a_tcnp;
682 struct componentname *fcnp = ap->a_fcnp;
684 struct componentname *tcnp = ap->a_tcnp;
686 struct vnode *tvp = ap->a_tvp;
687 struct vnode *tdvp = ap->a_tdvp;
688 struct vnode *fvp = ap->a_fvp;
689 struct vnode *fdvp = ap->a_fdvp;
692 * Check for cross-device rename.
694 if ((fvp->v_mount != tdvp->v_mount)
695 || (tvp && (fvp->v_mount != tvp->v_mount))) {
698 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
705 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
711 * if fvp == tvp, we're just removing one name of a pair of
712 * directory entries for the same element. convert call into rename.
713 ( (pinched from NetBSD 1.0's ufs_rename())
716 if (fvp->v_type == VDIR) {
721 /* Release destination completely. */
722 VOP_ABORTOP(tdvp, tcnp);
729 fcnp->cn_flags &= ~MODMASK;
730 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
731 if ((fcnp->cn_flags & SAVESTART) == 0)
732 panic("afs_rename: lost from startdir");
733 fcnp->cn_nameiop = DELETE;
734 (void)relookup(fdvp, &fvp, fcnp);
735 return (VOP_REMOVE(fdvp, fvp, fcnp));
738 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY)))
741 /* XXX GETNAME() ? */
742 MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
743 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
744 fname[fcnp->cn_namelen] = '\0';
745 MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
746 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
747 tname[tcnp->cn_namelen] = '\0';
751 /* XXX use "from" or "to" creds? NFS uses "to" creds */
753 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname,
761 goto abortit; /* XXX */
774 afs_nbsd_mkdir(void *v)
776 struct vop_mkdir_args /* {
777 * struct vnode *a_dvp;
778 * struct vnode **a_vpp;
779 * struct componentname *a_cnp;
780 * struct vattr *a_vap;
782 struct vnode *dvp = ap->a_dvp;
783 struct vattr *vap = ap->a_vap;
789 if ((cnp->cn_flags & HASBUF) == 0)
790 panic("afs_nbsd_mkdir: no name");
793 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
796 VOP_ABORTOP(dvp, cnp);
802 *ap->a_vpp = AFSTOV(vcp);
803 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
813 afs_nbsd_rmdir(void *v)
815 struct vop_rmdir_args /* {
816 * struct vnode *a_dvp;
817 * struct vnode *a_vp;
818 * struct componentname *a_cnp;
821 struct vnode *vp = ap->a_vp;
822 struct vnode *dvp = ap->a_dvp;
834 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
843 afs_nbsd_symlink(void *v)
845 struct vop_symlink_args /* {
846 * struct vnode *a_dvp;
847 * struct vnode **a_vpp;
848 * struct componentname *a_cnp;
849 * struct vattr *a_vap;
852 struct vnode *dvp = ap->a_dvp;
854 /* NFS ignores a_vpp; so do we. */
859 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
869 afs_nbsd_readdir(void *v)
871 struct vop_readdir_args /* {
872 * struct vnode *a_vp;
874 * kauth_cred_t a_cred;
877 * u_long **a_cookies;
882 #ifdef AFS_HAVE_COOKIES
883 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
886 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
887 ap->a_ncookies, ap->a_cookies);
890 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
897 afs_nbsd_readlink(void *v)
899 struct vop_readlink_args /* {
900 * struct vnode *a_vp;
902 * kauth_cred_t a_cred;
907 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
912 extern int prtactive;
915 afs_nbsd_inactive(void *v)
917 struct vop_inactive_args /* {
918 * struct vnode *a_vp;
920 struct vnode *vp = ap->a_vp;
921 struct vcache *vc = VTOAFS(vp);
922 int haveGlock = ISAFS_GLOCK();
924 AFS_STATCNT(afs_inactive);
926 if (prtactive && vp->v_usecount != 0)
927 vprint("afs_nbsd_inactive(): pushing active", vp);
931 afs_InactiveVCache(vc, 0); /* decrs ref counts */
935 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
940 afs_nbsd_reclaim(void *v)
942 struct vop_reclaim_args /* {
943 * struct vnode *a_vp;
946 struct vnode *vp = ap->a_vp;
947 struct vcache *avc = VTOAFS(vp);
948 int haveGlock = ISAFS_GLOCK();
949 int haveVlock = CheckLock(&afs_xvcache);
952 printf("reclaim usecount %d\n", vp->v_usecount);
953 /* OK, there are no internal vrefCounts, so there shouldn't
954 * be any more refs here. */
955 vp->v_data = NULL; /* remove from vnode */
956 avc->v = NULL; /* also drop the ptr to vnode */
962 ObtainWriteLock(&afs_xvcache, 901);
963 #ifndef AFS_DISCON_ENV
964 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
966 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
967 code = afs_FlushVS(avc);
970 ReleaseWriteLock(&afs_xvcache);
978 afs_nbsd_lock(void *v)
980 struct vop_lock_args /* {
981 * struct vnode *a_vp;
986 return (genfs_lock(v));
990 afs_nbsd_unlock(void *v)
992 struct vop_unlock_args /* {
993 * struct vnode *a_vp;
998 return (genfs_unlock(v));
1002 afs_nbsd_bmap(void *v)
1004 struct vop_bmap_args /* {
1005 * struct vnode *a_vp;
1007 * struct vnode **a_vpp;
1011 struct vcache *vcp = VTOAFS(ap->a_vp);
1013 AFS_STATCNT(afs_bmap);
1015 /* borrowed from DARWIN--why notyet? */
1017 *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE);
1020 *ap->a_vpp = ap->a_vp;
1022 if (ap->a_runp != NULL)
1025 if (ap->a_runb != NULL)
1033 afs_nbsd_strategy(void *v)
1035 struct vop_strategy_args /* {
1038 struct buf *abp = ap->a_bp;
1040 struct iovec tiovec[1];
1041 struct vcache *tvc = VTOAFS(abp->b_vp);
1042 afs_ucred_t credp = osi_curcred();
1043 long len = abp->b_bcount;
1046 AFS_STATCNT(afs_strategy);
1048 tuio.afsio_iov = tiovec;
1049 tuio.afsio_iovcnt = 1;
1050 tuio.afsio_resid = len;
1051 tiovec[0].iov_base = abp->b_un.b_addr;
1052 tiovec[0].iov_len = len;
1053 UIO_SETUP_SYSSPACE(&tuio);
1056 if ((abp->b_flags & B_READ) == B_READ) {
1057 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1058 if (code == 0 && tuio.afsio_resid > 0)
1059 bzero(abp->b_un.b_addr + len - tuio.afsio_resid,
1062 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1065 ReleaseWriteLock(&tvc->lock);
1066 AFS_RELE(AFSTOV(tvc));
1071 afs_nbsd_print(void *v)
1073 struct vop_print_args /* {
1074 * struct vnode *a_vp;
1076 struct vnode *vp = ap->a_vp;
1077 struct vcache *vc = VTOAFS(ap->a_vp);
1079 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1080 (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
1081 (int)vc->f.fid.Fid.Unique);
1082 lockmgr_printinfo(&vc->rwlock);
1088 afs_nbsd_islocked(void *v)
1090 struct vop_islocked_args /* {
1091 * struct vnode *a_vp;
1093 return (genfs_islocked(v));
1097 * Return POSIX pathconf information applicable to ufs filesystems.
1100 afs_nbsd_pathconf(void *v)
1102 struct vop_pathconf_args /* {
1103 * struct vnode *a_vp;
1107 AFS_STATCNT(afs_cntl);
1108 switch (ap->a_name) {
1110 *ap->a_retval = LINK_MAX;
1113 *ap->a_retval = NAME_MAX;
1116 *ap->a_retval = PATH_MAX;
1118 case _PC_CHOWN_RESTRICTED:
1134 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1135 afs_ucred_t *acred, pid_t clid);
1138 * Advisory record locking support (fcntl() POSIX style)
1141 afs_nbsd_advlock(void *v)
1143 struct vop_advlock_args /* {
1144 * struct vnode *a_vp;
1147 * struct flock *a_fl;
1154 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),