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(struct vop_lookup_args *);
122 int afs_nbsd_create(struct vop_create_args *);
123 int afs_nbsd_mknod(struct vop_mknod_args *);
124 int afs_nbsd_open(struct vop_open_args *);
125 int afs_nbsd_close(struct vop_close_args *);
126 int afs_nbsd_access(struct vop_access_args *);
127 int afs_nbsd_getattr(struct vop_getattr_args *);
128 int afs_nbsd_setattr(struct vop_setattr_args *);
129 int afs_nbsd_read(struct vop_read_args *);
130 int afs_nbsd_write(struct vop_write_args *);
131 int afs_nbsd_ioctl(struct vop_ioctl_args *);
132 int afs_nbsd_fsync(struct vop_fsync_args *);
133 int afs_nbsd_remove(struct vop_remove_args *);
134 int afs_nbsd_link(struct vop_link_args *);
135 int afs_nbsd_rename(struct vop_rename_args *);
136 int afs_nbsd_mkdir(struct vop_mkdir_args *);
137 int afs_nbsd_rmdir(struct vop_rmdir_args *);
138 int afs_nbsd_symlink(struct vop_symlink_args *);
139 int afs_nbsd_readdir(struct vop_readdir_args *);
140 int afs_nbsd_readlink(struct vop_readlink_args *);
141 extern int ufs_abortop(struct vop_abortop_args *);
142 int afs_nbsd_inactive(struct vop_inactive_args *);
143 int afs_nbsd_reclaim(struct vop_reclaim_args *);
144 int afs_nbsd_lock(struct vop_lock_args *);
145 int afs_nbsd_unlock(struct vop_unlock_args *);
146 int afs_nbsd_bmap(struct vop_bmap_args *);
147 int afs_nbsd_strategy(struct vop_strategy_args *);
148 int afs_nbsd_print(struct vop_print_args *);
149 int afs_nbsd_islocked(struct vop_islocked_args *);
150 int afs_nbsd_pathconf(struct vop_pathconf_args *);
151 int afs_nbsd_advlock(struct vop_advlock_args *);
153 #define afs_nbsd_opnotsupp \
154 ((int (*) __P((struct vop_reallocblks_args *)))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, seltrue}, /* select */
175 {&vop_select_desc, seltrue}, /* 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 #define vrele afs_nbsd_rele
218 #define VREF afs_nbsd_ref
222 struct vop_lookup_args /* {
223 * struct vnodeop_desc * a_desc;
224 * struct vnode *a_dvp;
225 * struct vnode **a_vpp;
226 * struct componentname *a_cnp;
231 struct vnode *vp, *dvp;
232 int flags = ap->a_cnp->cn_flags;
233 int lockparent; /* 1 => lockparent flag is set */
234 int wantparent; /* 1 => wantparent or lockparent flag */
237 lockparent = flags & LOCKPARENT;
238 wantparent = flags & (LOCKPARENT | WANTPARENT);
240 cnp->cn_flags &= ~PDIRUNLOCK;
243 if (ap->a_dvp->v_type != VDIR) {
249 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
250 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
251 name, dvp->v_usecount);
253 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
256 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
257 && (flags & ISLASTCN) && code == ENOENT)
259 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
260 cnp->cn_flags |= SAVENAME;
265 vp = AFSTOV(vcp); /* always get a node if no error */
268 * The parent directory comes in locked. We unlock it on return
269 * unless the caller wants it left locked.
270 * we also always return the vnode locked.
274 /* they're the same; afs_lookup() already ref'ed the leaf.
275 * It came in locked, so we don't need to ref OR lock it */
276 if (afs_debug & AFSDEB_VNLAYER)
277 printf("ref'ed %p as .\n", dvp);
279 if (!lockparent || !(flags & ISLASTCN)) {
280 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
282 cnp->cn_flags |= PDIRUNLOCK;
285 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
286 if (afs_debug & AFSDEB_VNLAYER)
287 printf("locked ret %p from lookup\n", vp);
291 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
292 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
293 cnp->cn_flags |= SAVENAME;
296 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
297 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
303 struct vop_create_args /* {
304 * struct vnode *a_dvp;
305 * struct vnode **a_vpp;
306 * struct componentname *a_cnp;
307 * struct vattr *a_vap;
312 struct vnode *dvp = ap->a_dvp;
315 if (afs_debug & AFSDEB_VNLAYER)
316 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
318 /* vnode layer handles excl/nonexcl */
322 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
326 VOP_ABORTOP(dvp, cnp);
333 *ap->a_vpp = AFSTOV(vcp);
334 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
338 if ((cnp->cn_flags & SAVESTART) == 0)
339 FREE(cnp->cn_pnbuf, M_NAMEI);
342 if (afs_debug & AFSDEB_VNLAYER)
343 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
349 struct vop_mknod_args /* {
350 * struct vnode *a_dvp;
351 * struct vnode **a_vpp;
352 * struct componentname *a_cnp;
353 * struct vattr *a_vap;
356 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
363 struct vop_open_args /* {
364 * struct vnode *a_vp;
366 * struct ucred *a_cred;
371 struct vcache *vc = VTOAFS(ap->a_vp);
374 code = afs_open(&vc, ap->a_mode, ap->a_cred);
376 if (AFSTOV(vc) != ap->a_vp)
377 panic("AFS open changed vnode!");
385 struct vop_close_args /* {
386 * struct vnode *a_vp;
388 * struct ucred *a_cred;
395 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
402 struct vop_access_args /* {
403 * struct vnode *a_vp;
405 * struct ucred *a_cred;
412 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
419 struct vop_getattr_args /* {
420 * struct vnode *a_vp;
421 * struct vattr *a_vap;
422 * struct ucred *a_cred;
429 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
436 struct vop_setattr_args /* {
437 * struct vnode *a_vp;
438 * struct vattr *a_vap;
439 * struct ucred *a_cred;
446 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
453 struct vop_read_args /* {
454 * struct vnode *a_vp;
457 * struct ucred *a_cred;
464 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
472 struct vop_write_args /* {
473 * struct vnode *a_vp;
476 * struct ucred *a_cred;
482 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
484 vnode_pager_uncache(ap->a_vp);
488 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
495 struct vop_ioctl_args /* {
496 * struct vnode *a_vp;
500 * struct ucred *a_cred;
506 /* in case we ever get in here... */
508 AFS_STATCNT(afs_ioctl);
510 if (((ap->a_command >> 8) & 0xff) == 'V')
511 /* This is a VICEIOCTL call */
513 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
514 (struct afs_ioctl *)ap->a_data);
516 /* No-op call; just return. */
524 struct vop_fsync_args /* {
525 * struct vnode *a_vp;
526 * struct ucred *a_cred;
531 int wait = ap->a_waitfor == MNT_WAIT;
532 struct vnode *vp = ap->a_vp;
537 code = afs_fsync(VTOAFS(vp), ap->a_cred);
544 struct vop_remove_args /* {
545 * struct vnode *a_dvp;
546 * struct vnode *a_vp;
547 * struct componentname *a_cnp;
551 struct vnode *vp = ap->a_vp;
552 struct vnode *dvp = ap->a_dvp;
556 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
563 FREE(cnp->cn_pnbuf, M_NAMEI);
570 struct vop_link_args /* {
571 * struct vnode *a_vp;
572 * struct vnode *a_tdvp;
573 * struct componentname *a_cnp;
577 struct vnode *dvp = ap->a_dvp;
578 struct vnode *vp = ap->a_vp;
581 if (dvp->v_mount != vp->v_mount) {
582 VOP_ABORTOP(vp, cnp);
586 if (vp->v_type == VDIR) {
587 VOP_ABORTOP(vp, cnp);
591 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
592 VOP_ABORTOP(dvp, cnp);
597 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
599 FREE(cnp->cn_pnbuf, M_NAMEI);
601 VOP_UNLOCK(vp, 0, curproc);
611 struct vop_rename_args /* {
612 * struct vnode *a_fdvp;
613 * struct vnode *a_fvp;
614 * struct componentname *a_fcnp;
615 * struct vnode *a_tdvp;
616 * struct vnode *a_tvp;
617 * struct componentname *a_tcnp;
621 struct componentname *fcnp = ap->a_fcnp;
623 struct componentname *tcnp = ap->a_tcnp;
625 struct vnode *tvp = ap->a_tvp;
626 struct vnode *tdvp = ap->a_tdvp;
627 struct vnode *fvp = ap->a_fvp;
628 struct vnode *fdvp = ap->a_fdvp;
631 * Check for cross-device rename.
633 if ((fvp->v_mount != tdvp->v_mount)
634 || (tvp && (fvp->v_mount != tvp->v_mount))) {
637 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
644 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
650 * if fvp == tvp, we're just removing one name of a pair of
651 * directory entries for the same element. convert call into rename.
652 ( (pinched from NetBSD 1.0's ufs_rename())
655 if (fvp->v_type == VDIR) {
660 /* Release destination completely. */
661 VOP_ABORTOP(tdvp, tcnp);
668 fcnp->cn_flags &= ~MODMASK;
669 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
670 if ((fcnp->cn_flags & SAVESTART) == 0)
671 panic("afs_rename: lost from startdir");
672 fcnp->cn_nameiop = DELETE;
673 (void)relookup(fdvp, &fvp, fcnp);
674 return (VOP_REMOVE(fdvp, fvp, fcnp));
677 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
680 MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
681 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
682 fname[fcnp->cn_namelen] = '\0';
683 MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
684 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
685 tname[tcnp->cn_namelen] = '\0';
689 /* XXX use "from" or "to" creds? NFS uses "to" creds */
691 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
694 VOP_UNLOCK(fvp, 0, curproc);
698 goto abortit; /* XXX */
712 struct vop_mkdir_args /* {
713 * struct vnode *a_dvp;
714 * struct vnode **a_vpp;
715 * struct componentname *a_cnp;
716 * struct vattr *a_vap;
719 struct vnode *dvp = ap->a_dvp;
720 struct vattr *vap = ap->a_vap;
726 if ((cnp->cn_flags & HASBUF) == 0)
727 panic("afs_nbsd_mkdir: no name");
730 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
733 VOP_ABORTOP(dvp, cnp);
739 *ap->a_vpp = AFSTOV(vcp);
740 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
744 FREE(cnp->cn_pnbuf, M_NAMEI);
751 struct vop_rmdir_args /* {
752 * struct vnode *a_dvp;
753 * struct vnode *a_vp;
754 * struct componentname *a_cnp;
758 struct vnode *vp = ap->a_vp;
759 struct vnode *dvp = ap->a_dvp;
765 FREE(cnp->cn_pnbuf, M_NAMEI);
771 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
781 struct vop_symlink_args /* {
782 * struct vnode *a_dvp;
783 * struct vnode **a_vpp;
784 * struct componentname *a_cnp;
785 * struct vattr *a_vap;
789 struct vnode *dvp = ap->a_dvp;
791 /* NFS ignores a_vpp; so do we. */
796 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
799 FREE(cnp->cn_pnbuf, M_NAMEI);
806 struct vop_readdir_args /* {
807 * struct vnode *a_vp;
809 * struct ucred *a_cred;
812 * u_long **a_cookies;
818 #ifdef AFS_HAVE_COOKIES
819 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
822 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
823 ap->a_ncookies, ap->a_cookies);
826 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
833 afs_nbsd_readlink(ap)
834 struct vop_readlink_args /* {
835 * struct vnode *a_vp;
837 * struct ucred *a_cred;
843 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
848 extern int prtactive;
851 afs_nbsd_inactive(ap)
852 struct vop_inactive_args /* {
853 * struct vnode *a_vp;
856 struct vnode *vp = ap->a_vp;
857 struct vcache *vc = VTOAFS(vp);
858 int haveGlock = ISAFS_GLOCK();
860 AFS_STATCNT(afs_inactive);
862 if (prtactive && vp->v_usecount != 0)
863 vprint("afs_nbsd_inactive(): pushing active", vp);
867 afs_InactiveVCache(vc, 0); /* decrs ref counts */
871 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
877 struct vop_reclaim_args /* {
878 * struct vnode *a_vp;
882 struct vnode *vp = ap->a_vp;
883 struct vcache *avc = VTOAFS(vp);
884 int haveGlock = ISAFS_GLOCK();
885 int haveVlock = CheckLock(&afs_xvcache);
890 ObtainWriteLock(&afs_xvcache, 901);
891 #ifndef AFS_DISCON_ENV
892 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
894 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
895 code = afs_FlushVS(avc);
898 ReleaseWriteLock(&afs_xvcache);
906 struct vop_lock_args /* {
907 * struct vnode *a_vp;
912 struct vnode *vp = ap->a_vp;
913 struct vcache *vc = VTOAFS(vp);
916 panic("afs_nbsd_lock: null vcache");
917 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock,
923 struct vop_unlock_args /* {
924 * struct vnode *a_vp;
929 struct vnode *vp = ap->a_vp;
930 struct vcache *vc = VTOAFS(vp);
933 panic("afs_nbsd_unlock: null vcache");
934 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
940 struct vop_bmap_args /* {
941 * struct vnode *a_vp;
943 * struct vnode **a_vpp;
948 struct vcache *vcp = VTOAFS(ap->a_vp);
950 AFS_STATCNT(afs_bmap);
952 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
954 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
959 afs_nbsd_strategy(ap)
960 struct vop_strategy_args /* {
964 struct buf *abp = ap->a_bp;
966 struct iovec tiovec[1];
967 struct vcache *tvc = VTOAFS(abp->b_vp);
968 struct ucred *credp = osi_curcred();
969 long len = abp->b_bcount;
972 AFS_STATCNT(afs_strategy);
974 tuio.afsio_iov = tiovec;
975 tuio.afsio_iovcnt = 1;
976 tuio.afsio_seg = AFS_UIOSYS;
977 tuio.afsio_resid = len;
978 tiovec[0].iov_base = abp->b_un.b_addr;
979 tiovec[0].iov_len = len;
982 if ((abp->b_flags & B_READ) == B_READ) {
983 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
984 if (code == 0 && tuio.afsio_resid > 0)
985 bzero(abp->b_un.b_addr + len - tuio.afsio_resid,
988 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
991 ReleaseWriteLock(&tvc->lock);
992 AFS_RELE(AFSTOV(tvc));
998 struct vop_print_args /* {
999 * struct vnode *a_vp;
1002 struct vnode *vp = ap->a_vp;
1003 struct vcache *vc = VTOAFS(ap->a_vp);
1005 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
1006 (int)vc->fid.Fid.Volume, (int)vc->fid.Fid.Vnode,
1007 (int)vc->fid.Fid.Unique);
1008 lockmgr_printinfo(&vc->rwlock);
1014 afs_nbsd_islocked(ap)
1015 struct vop_islocked_args /* {
1016 * struct vnode *a_vp;
1019 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1023 * Return POSIX pathconf information applicable to ufs filesystems.
1026 afs_nbsd_pathconf(ap)
1027 struct vop_pathconf_args /* {
1028 * struct vnode *a_vp;
1033 AFS_STATCNT(afs_cntl);
1034 switch (ap->a_name) {
1036 *ap->a_retval = LINK_MAX;
1039 *ap->a_retval = NAME_MAX;
1042 *ap->a_retval = PATH_MAX;
1044 case _PC_CHOWN_RESTRICTED:
1060 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1061 struct AFS_UCRED *acred, pid_t clid);
1064 * Advisory record locking support (fcntl() POSIX style)
1067 afs_nbsd_advlock(ap)
1068 struct vop_advlock_args /* {
1069 * struct vnode *a_vp;
1072 * struct flock *a_fl;
1080 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),