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>
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"
104 #include "afs/sysincludes.h" /* Standard vendor system headers */
105 #include "afs/afsincludes.h" /* Afs-based standard headers */
106 #include "afs/afs_stats.h" /* statistics */
108 #include <sys/malloc.h>
109 #include <sys/namei.h>
111 #include "afs/afs_cbqueue.h"
112 #include "afs/nfsclient.h"
113 #include "afs/afs_osidnlc.h"
115 #ifdef AFS_DISCON_ENV
116 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 *);
153 #define afs_nbsd_opnotsupp \
154 ((int (*) __P((void *)))eopnotsupp)
155 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
157 /* Global vfs data structures for AFS. */
158 int (**afs_vnodeop_p) __P((void *));
159 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
160 {&vop_default_desc, vn_default_error},
161 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
162 {&vop_create_desc, afs_nbsd_create}, /* create */
163 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
164 {&vop_open_desc, afs_nbsd_open}, /* open */
165 {&vop_close_desc, afs_nbsd_close}, /* close */
166 {&vop_access_desc, afs_nbsd_access}, /* access */
167 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
168 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
169 {&vop_read_desc, afs_nbsd_read}, /* read */
170 {&vop_write_desc, afs_nbsd_write}, /* write */
171 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
172 #ifdef AFS_OBSD35_ENV
173 {&vop_poll_desc, afs_nbsd_select}, /* select */
175 {&vop_select_desc, afs_nbsd_select}, /* select */
177 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
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, vop_generic_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 */
197 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
198 {&vop_bwrite_desc, vop_generic_bwrite},
199 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
201 struct vnodeopv_desc afs_vnodeop_opv_desc =
202 { &afs_vnodeop_p, afs_vnodeop_entries };
205 struct componentname *cnp = ap->a_cnp; \
207 MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
208 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
209 name[cnp->cn_namelen] = '\0'
211 #define DROPNAME() FREE(name, M_TEMP)
216 afs_nbsd_lookup(void *v)
218 struct vop_lookup_args /* {
219 * struct vnodeop_desc * a_desc;
220 * struct vnode *a_dvp;
221 * struct vnode **a_vpp;
222 * struct componentname *a_cnp;
226 struct vnode *vp, *dvp;
227 int flags = ap->a_cnp->cn_flags;
228 int lockparent; /* 1 => lockparent flag is set */
229 int wantparent; /* 1 => wantparent or lockparent flag */
232 lockparent = flags & LOCKPARENT;
233 wantparent = flags & (LOCKPARENT | WANTPARENT);
235 cnp->cn_flags &= ~PDIRUNLOCK;
238 if (ap->a_dvp->v_type != VDIR) {
244 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
245 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
246 name, dvp->v_usecount);
248 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
251 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
252 && (flags & ISLASTCN) && code == ENOENT)
254 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
255 cnp->cn_flags |= SAVENAME;
260 vp = AFSTOV(vcp); /* always get a node if no error */
263 * The parent directory comes in locked. We unlock it on return
264 * unless the caller wants it left locked.
265 * we also always return the vnode locked.
269 /* they're the same; afs_lookup() already ref'ed the leaf.
270 * It came in locked, so we don't need to ref OR lock it */
271 if (afs_debug & AFSDEB_VNLAYER)
272 printf("ref'ed %p as .\n", dvp);
274 if (!lockparent || !(flags & ISLASTCN)) {
275 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
277 cnp->cn_flags |= PDIRUNLOCK;
280 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
281 if (afs_debug & AFSDEB_VNLAYER)
282 printf("locked ret %p from lookup\n", vp);
286 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
287 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
288 cnp->cn_flags |= SAVENAME;
291 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
292 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
297 afs_nbsd_create(void *v)
299 struct vop_create_args /* {
300 * struct vnode *a_dvp;
301 * struct vnode **a_vpp;
302 * struct componentname *a_cnp;
303 * struct vattr *a_vap;
307 struct vnode *dvp = ap->a_dvp;
310 if (afs_debug & AFSDEB_VNLAYER)
311 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
313 /* vnode layer handles excl/nonexcl */
317 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
321 VOP_ABORTOP(dvp, cnp);
328 *ap->a_vpp = AFSTOV(vcp);
329 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
333 if ((cnp->cn_flags & SAVESTART) == 0)
334 FREE(cnp->cn_pnbuf, M_NAMEI);
337 if (afs_debug & AFSDEB_VNLAYER)
338 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
343 afs_nbsd_mknod(void *v)
345 struct vop_mknod_args /* {
346 * struct vnode *a_dvp;
347 * struct vnode **a_vpp;
348 * struct componentname *a_cnp;
349 * struct vattr *a_vap;
351 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
357 afs_nbsd_open(void *v)
359 struct vop_open_args /* {
360 * struct vnode *a_vp;
362 * struct ucred *a_cred;
366 struct vcache *vc = VTOAFS(ap->a_vp);
369 code = afs_open(&vc, ap->a_mode, ap->a_cred);
371 if (AFSTOV(vc) != ap->a_vp)
372 panic("AFS open changed vnode!");
379 afs_nbsd_close(void *v)
381 struct vop_close_args /* {
382 * struct vnode *a_vp;
384 * struct ucred *a_cred;
390 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
396 afs_nbsd_access(void *v)
398 struct vop_access_args /* {
399 * struct vnode *a_vp;
401 * struct ucred *a_cred;
407 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
413 afs_nbsd_getattr(void *v)
415 struct vop_getattr_args /* {
416 * struct vnode *a_vp;
417 * struct vattr *a_vap;
418 * struct ucred *a_cred;
424 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
430 afs_nbsd_setattr(void *v)
432 struct vop_setattr_args /* {
433 * struct vnode *a_vp;
434 * struct vattr *a_vap;
435 * struct ucred *a_cred;
441 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
447 afs_nbsd_read(void *v)
449 struct vop_read_args /* {
450 * struct vnode *a_vp;
453 * struct ucred *a_cred;
459 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
466 afs_nbsd_write(void *v)
468 struct vop_write_args /* {
469 * struct vnode *a_vp;
472 * struct ucred *a_cred;
477 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
479 vnode_pager_uncache(ap->a_vp);
483 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
489 afs_nbsd_ioctl(void *v)
491 struct vop_ioctl_args /* {
492 * struct vnode *a_vp;
496 * struct ucred *a_cred;
501 /* in case we ever get in here... */
503 AFS_STATCNT(afs_ioctl);
505 if (((ap->a_command >> 8) & 0xff) == 'V')
506 /* This is a VICEIOCTL call */
508 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
509 (struct afs_ioctl *)ap->a_data);
511 /* No-op call; just return. */
518 afs_nbsd_select(void *v)
524 afs_nbsd_fsync(void *v)
526 struct vop_fsync_args /* {
527 * struct vnode *a_vp;
528 * struct ucred *a_cred;
532 int wait = ap->a_waitfor == MNT_WAIT;
533 struct vnode *vp = ap->a_vp;
538 code = afs_fsync(VTOAFS(vp), ap->a_cred);
544 afs_nbsd_remove(void *v)
546 struct vop_remove_args /* {
547 * struct vnode *a_dvp;
548 * struct vnode *a_vp;
549 * struct componentname *a_cnp;
552 struct vnode *vp = ap->a_vp;
553 struct vnode *dvp = ap->a_dvp;
557 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
564 FREE(cnp->cn_pnbuf, M_NAMEI);
570 afs_nbsd_link(void *v)
572 struct vop_link_args /* {
573 * struct vnode *a_vp;
574 * struct vnode *a_tdvp;
575 * struct componentname *a_cnp;
578 struct vnode *dvp = ap->a_dvp;
579 struct vnode *vp = ap->a_vp;
582 if (dvp->v_mount != vp->v_mount) {
583 VOP_ABORTOP(vp, cnp);
587 if (vp->v_type == VDIR) {
588 VOP_ABORTOP(vp, cnp);
592 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
593 VOP_ABORTOP(dvp, cnp);
598 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
600 FREE(cnp->cn_pnbuf, M_NAMEI);
602 VOP_UNLOCK(vp, 0, curproc);
611 afs_nbsd_rename(void *v)
613 struct vop_rename_args /* {
614 * struct vnode *a_fdvp;
615 * struct vnode *a_fvp;
616 * struct componentname *a_fcnp;
617 * struct vnode *a_tdvp;
618 * struct vnode *a_tvp;
619 * struct componentname *a_tcnp;
622 struct componentname *fcnp = ap->a_fcnp;
624 struct componentname *tcnp = ap->a_tcnp;
626 struct vnode *tvp = ap->a_tvp;
627 struct vnode *tdvp = ap->a_tdvp;
628 struct vnode *fvp = ap->a_fvp;
629 struct vnode *fdvp = ap->a_fdvp;
632 * Check for cross-device rename.
634 if ((fvp->v_mount != tdvp->v_mount)
635 || (tvp && (fvp->v_mount != tvp->v_mount))) {
638 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
645 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
651 * if fvp == tvp, we're just removing one name of a pair of
652 * directory entries for the same element. convert call into rename.
653 ( (pinched from NetBSD 1.0's ufs_rename())
656 if (fvp->v_type == VDIR) {
661 /* Release destination completely. */
662 VOP_ABORTOP(tdvp, tcnp);
669 fcnp->cn_flags &= ~MODMASK;
670 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
671 if ((fcnp->cn_flags & SAVESTART) == 0)
672 panic("afs_rename: lost from startdir");
673 fcnp->cn_nameiop = DELETE;
674 (void)relookup(fdvp, &fvp, fcnp);
675 return (VOP_REMOVE(fdvp, fvp, fcnp));
678 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
681 MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
682 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
683 fname[fcnp->cn_namelen] = '\0';
684 MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
685 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
686 tname[tcnp->cn_namelen] = '\0';
690 /* XXX use "from" or "to" creds? NFS uses "to" creds */
692 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
695 VOP_UNLOCK(fvp, 0, curproc);
699 goto abortit; /* XXX */
712 afs_nbsd_mkdir(void *v)
714 struct vop_mkdir_args /* {
715 * struct vnode *a_dvp;
716 * struct vnode **a_vpp;
717 * struct componentname *a_cnp;
718 * struct vattr *a_vap;
720 struct vnode *dvp = ap->a_dvp;
721 struct vattr *vap = ap->a_vap;
727 if ((cnp->cn_flags & HASBUF) == 0)
728 panic("afs_nbsd_mkdir: no name");
731 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
734 VOP_ABORTOP(dvp, cnp);
740 *ap->a_vpp = AFSTOV(vcp);
741 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
745 FREE(cnp->cn_pnbuf, M_NAMEI);
751 afs_nbsd_rmdir(void *v)
753 struct vop_rmdir_args /* {
754 * struct vnode *a_dvp;
755 * struct vnode *a_vp;
756 * struct componentname *a_cnp;
759 struct vnode *vp = ap->a_vp;
760 struct vnode *dvp = ap->a_dvp;
766 FREE(cnp->cn_pnbuf, M_NAMEI);
772 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
781 afs_nbsd_symlink(void *v)
783 struct vop_symlink_args /* {
784 * struct vnode *a_dvp;
785 * struct vnode **a_vpp;
786 * struct componentname *a_cnp;
787 * struct vattr *a_vap;
790 struct vnode *dvp = ap->a_dvp;
792 /* NFS ignores a_vpp; so do we. */
797 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
800 FREE(cnp->cn_pnbuf, M_NAMEI);
806 afs_nbsd_readdir(void *v)
808 struct vop_readdir_args /* {
809 * struct vnode *a_vp;
811 * struct ucred *a_cred;
814 * u_long **a_cookies;
819 #ifdef AFS_HAVE_COOKIES
820 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
823 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
824 ap->a_ncookies, ap->a_cookies);
827 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
834 afs_nbsd_readlink(void *v)
836 struct vop_readlink_args /* {
837 * struct vnode *a_vp;
839 * struct ucred *a_cred;
844 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
849 extern int prtactive;
852 afs_nbsd_inactive(void *v)
854 struct vop_inactive_args /* {
855 * struct vnode *a_vp;
857 struct vnode *vp = ap->a_vp;
858 struct vcache *vc = VTOAFS(vp);
859 int haveGlock = ISAFS_GLOCK();
861 AFS_STATCNT(afs_inactive);
863 if (prtactive && vp->v_usecount != 0)
864 vprint("afs_nbsd_inactive(): pushing active", vp);
868 afs_InactiveVCache(vc, 0); /* decrs ref counts */
872 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
877 afs_nbsd_reclaim(void *v)
879 struct vop_reclaim_args /* {
880 * struct vnode *a_vp;
883 struct vnode *vp = ap->a_vp;
884 struct vcache *avc = VTOAFS(vp);
885 int haveGlock = ISAFS_GLOCK();
886 int haveVlock = CheckLock(&afs_xvcache);
891 ObtainWriteLock(&afs_xvcache, 901);
892 #ifndef AFS_DISCON_ENV
893 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
895 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
896 code = afs_FlushVS(avc);
899 ReleaseWriteLock(&afs_xvcache);
906 afs_nbsd_lock(void *v)
908 struct vop_lock_args /* {
909 * struct vnode *a_vp;
913 struct vnode *vp = ap->a_vp;
914 struct vcache *vc = VTOAFS(vp);
917 panic("afs_nbsd_lock: null vcache");
918 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock,
923 afs_nbsd_unlock(void *v)
925 struct vop_unlock_args /* {
926 * struct vnode *a_vp;
930 struct vnode *vp = ap->a_vp;
931 struct vcache *vc = VTOAFS(vp);
934 panic("afs_nbsd_unlock: null vcache");
935 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
940 afs_nbsd_bmap(void *v)
942 struct vop_bmap_args /* {
943 * struct vnode *a_vp;
945 * struct vnode **a_vpp;
949 struct vcache *vcp = VTOAFS(ap->a_vp);
951 AFS_STATCNT(afs_bmap);
953 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
955 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
960 afs_nbsd_strategy(void *v)
962 struct vop_strategy_args /* {
965 struct buf *abp = ap->a_bp;
967 struct iovec tiovec[1];
968 struct vcache *tvc = VTOAFS(abp->b_vp);
969 struct ucred *credp = osi_curcred();
970 long len = abp->b_bcount;
973 AFS_STATCNT(afs_strategy);
975 tuio.afsio_iov = tiovec;
976 tuio.afsio_iovcnt = 1;
977 tuio.afsio_seg = AFS_UIOSYS;
978 tuio.afsio_resid = len;
979 tiovec[0].iov_base = abp->b_un.b_addr;
980 tiovec[0].iov_len = len;
983 if ((abp->b_flags & B_READ) == B_READ) {
984 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
985 if (code == 0 && tuio.afsio_resid > 0)
986 bzero(abp->b_un.b_addr + len - tuio.afsio_resid,
989 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
992 ReleaseWriteLock(&tvc->lock);
993 AFS_RELE(AFSTOV(tvc));
998 afs_nbsd_print(void *v)
1000 struct vop_print_args /* {
1001 * struct vnode *a_vp;
1003 struct vnode *vp = ap->a_vp;
1004 struct vcache *vc = VTOAFS(ap->a_vp);
1006 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
1007 (int)vc->fid.Fid.Volume, (int)vc->fid.Fid.Vnode,
1008 (int)vc->fid.Fid.Unique);
1009 lockmgr_printinfo(&vc->rwlock);
1015 afs_nbsd_islocked(void *v)
1017 struct vop_islocked_args /* {
1018 * struct vnode *a_vp;
1020 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1024 * Return POSIX pathconf information applicable to ufs filesystems.
1027 afs_nbsd_pathconf(void *v)
1029 struct vop_pathconf_args /* {
1030 * struct vnode *a_vp;
1034 AFS_STATCNT(afs_cntl);
1035 switch (ap->a_name) {
1037 *ap->a_retval = LINK_MAX;
1040 *ap->a_retval = NAME_MAX;
1043 *ap->a_retval = PATH_MAX;
1045 case _PC_CHOWN_RESTRICTED:
1061 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1062 struct AFS_UCRED *acred, pid_t clid);
1065 * Advisory record locking support (fcntl() POSIX style)
1068 afs_nbsd_advlock(void *v)
1070 struct vop_advlock_args /* {
1071 * struct vnode *a_vp;
1074 * struct flock *a_fl;
1081 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),