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"
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>
110 #include "afs/afs_cbqueue.h"
111 #include "afs/nfsclient.h"
112 #include "afs/afs_osidnlc.h"
114 #ifdef AFS_DISCON_ENV
115 extern int afs_FlushVS(struct vcache *tvc);
118 #define M_AFSNODE (M_TEMP-1) /* XXX */
120 int afs_nbsd_lookup(struct vop_lookup_args *);
121 int afs_nbsd_create(struct vop_create_args *);
122 int afs_nbsd_mknod(struct vop_mknod_args *);
123 int afs_nbsd_open(struct vop_open_args *);
124 int afs_nbsd_close(struct vop_close_args *);
125 int afs_nbsd_access(struct vop_access_args *);
126 int afs_nbsd_getattr(struct vop_getattr_args *);
127 int afs_nbsd_setattr(struct vop_setattr_args *);
128 int afs_nbsd_read(struct vop_read_args *);
129 int afs_nbsd_write(struct vop_write_args *);
130 int afs_nbsd_ioctl(struct vop_ioctl_args *);
131 int afs_nbsd_select(struct vop_select_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 { &vop_select_desc, afs_nbsd_select }, /* select */
173 { &vop_fsync_desc, afs_nbsd_fsync }, /* fsync */
174 { &vop_remove_desc, afs_nbsd_remove }, /* remove */
175 { &vop_link_desc, afs_nbsd_link }, /* link */
176 { &vop_rename_desc, afs_nbsd_rename }, /* rename */
177 { &vop_mkdir_desc, afs_nbsd_mkdir }, /* mkdir */
178 { &vop_rmdir_desc, afs_nbsd_rmdir }, /* rmdir */
179 { &vop_symlink_desc, afs_nbsd_symlink }, /* symlink */
180 { &vop_readdir_desc, afs_nbsd_readdir }, /* readdir */
181 { &vop_readlink_desc, afs_nbsd_readlink }, /* readlink */
182 { &vop_abortop_desc, vop_generic_abortop }, /* abortop */
183 { &vop_inactive_desc, afs_nbsd_inactive }, /* inactive */
184 { &vop_reclaim_desc, afs_nbsd_reclaim }, /* reclaim */
185 { &vop_lock_desc, afs_nbsd_lock }, /* lock */
186 { &vop_unlock_desc, afs_nbsd_unlock }, /* unlock */
187 { &vop_bmap_desc, afs_nbsd_bmap }, /* bmap */
188 { &vop_strategy_desc, afs_nbsd_strategy }, /* strategy */
189 { &vop_print_desc, afs_nbsd_print }, /* print */
190 { &vop_islocked_desc, afs_nbsd_islocked }, /* islocked */
191 { &vop_pathconf_desc, afs_nbsd_pathconf }, /* pathconf */
192 { &vop_advlock_desc, afs_nbsd_advlock }, /* advlock */
193 { &vop_reallocblks_desc, afs_nbsd_reallocblks }, /* reallocblks */
194 { &vop_bwrite_desc, vop_generic_bwrite },
195 { (struct vnodeop_desc *) NULL, (int (*) __P((void *))) NULL}
197 struct vnodeopv_desc afs_vnodeop_opv_desc =
198 { &afs_vnodeop_p, afs_vnodeop_entries };
201 struct componentname *cnp = ap->a_cnp; \
203 MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
204 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
205 name[cnp->cn_namelen] = '\0'
207 #define DROPNAME() FREE(name, M_TEMP)
212 #define vrele afs_nbsd_rele
214 #define VREF afs_nbsd_ref
216 extern int afs_lookup();
217 extern int afs_open();
218 extern int afs_close();
219 extern int HandleIoctl(struct vcache *avc, afs_int32 acom, struct afs_ioctl *adata);
220 extern int afs_fsync();
221 extern int afs_remove();
222 extern int afs_link();
223 extern int afs_rename();
224 extern int afs_mkdir();
225 extern int afs_rmdir();
226 extern int afs_symlink();
227 extern int afs_readdir();
228 extern int afs_readlink();
232 struct vop_lookup_args /* {
233 struct vnodeop_desc * a_desc;
235 struct vnode **a_vpp;
236 struct componentname *a_cnp;
241 struct vnode *vp, *dvp;
242 int flags = ap->a_cnp->cn_flags;
243 int lockparent; /* 1 => lockparent flag is set */
244 int wantparent; /* 1 => wantparent or lockparent flag */
247 lockparent = flags & LOCKPARENT;
248 wantparent = flags & (LOCKPARENT|WANTPARENT);
250 cnp->cn_flags &= ~PDIRUNLOCK;
253 if (ap->a_dvp->v_type != VDIR) {
259 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
260 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags, name, dvp->v_usecount);
262 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
265 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
266 (flags & ISLASTCN) && code == ENOENT)
268 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
269 cnp->cn_flags |= SAVENAME;
274 vp = AFSTOV(vcp); /* always get a node if no error */
277 * The parent directory comes in locked. We unlock it on return
278 * unless the caller wants it left locked.
279 * we also always return the vnode locked.
283 /* they're the same; afs_lookup() already ref'ed the leaf.
284 It came in locked, so we don't need to ref OR lock it */
285 if (afs_debug & AFSDEB_VNLAYER)
286 printf("ref'ed %p as .\n", dvp);
288 if (!lockparent || !(flags & ISLASTCN)) {
289 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
291 cnp->cn_flags |= PDIRUNLOCK;
294 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
295 if (afs_debug & AFSDEB_VNLAYER)
296 printf("locked ret %p from lookup\n", vp);
300 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
301 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
302 cnp->cn_flags |= SAVENAME;
305 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
306 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
312 struct vop_create_args /* {
314 struct vnode **a_vpp;
315 struct componentname *a_cnp;
321 struct vnode *dvp = ap->a_dvp;
324 if (afs_debug & AFSDEB_VNLAYER)
325 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
327 /* vnode layer handles excl/nonexcl */
330 code = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
331 ap->a_vap->va_mode, &vcp,
335 VOP_ABORTOP(dvp, cnp);
342 *ap->a_vpp = AFSTOV(vcp);
343 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
347 if ((cnp->cn_flags & SAVESTART) == 0)
348 FREE(cnp->cn_pnbuf, M_NAMEI);
351 if (afs_debug & AFSDEB_VNLAYER)
352 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
358 struct vop_mknod_args /* {
360 struct vnode **a_vpp;
361 struct componentname *a_cnp;
365 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
372 struct vop_open_args /* {
375 struct ucred *a_cred;
380 struct vcache *vc = VTOAFS(ap->a_vp);
383 code = afs_open(&vc, ap->a_mode, ap->a_cred);
385 if (AFSTOV(vc) != ap->a_vp)
386 panic("AFS open changed vnode!");
394 struct vop_close_args /* {
397 struct ucred *a_cred;
404 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
411 struct vop_access_args /* {
414 struct ucred *a_cred;
421 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
428 struct vop_getattr_args /* {
431 struct ucred *a_cred;
438 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
445 struct vop_setattr_args /* {
448 struct ucred *a_cred;
455 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
462 struct vop_read_args /* {
466 struct ucred *a_cred;
472 code = afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t)0, NULL, 0);
479 struct vop_write_args /* {
483 struct ucred *a_cred;
489 (void) uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
491 vnode_pager_uncache(ap->a_vp);
494 code = afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
501 struct vop_ioctl_args /* {
506 struct ucred *a_cred;
512 /* in case we ever get in here... */
514 AFS_STATCNT(afs_ioctl);
516 if (((ap->a_command >> 8) & 0xff) == 'V')
517 /* This is a VICEIOCTL call */
518 code = HandleIoctl(VTOAFS(ap->a_vp), ap->a_command, (struct afs_ioctl *) ap->a_data);
520 /* No-op call; just return. */
529 struct vop_select_args /* {
533 struct ucred *a_cred;
538 * We should really check to see if I/O is possible.
545 struct vop_fsync_args /* {
547 struct ucred *a_cred;
552 int wait = ap->a_waitfor == MNT_WAIT;
553 struct vnode *vp = ap->a_vp;
558 code = afs_fsync(VTOAFS(vp), ap->a_cred);
565 struct vop_remove_args /* {
568 struct componentname *a_cnp;
572 struct vnode *vp = ap->a_vp;
573 struct vnode *dvp = ap->a_dvp;
577 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
584 FREE(cnp->cn_pnbuf, M_NAMEI);
591 struct vop_link_args /* {
593 struct vnode *a_tdvp;
594 struct componentname *a_cnp;
598 struct vnode *dvp = ap->a_dvp;
599 struct vnode *vp = ap->a_vp;
602 if (dvp->v_mount != vp->v_mount) {
603 VOP_ABORTOP(vp, cnp);
607 if (vp->v_type == VDIR) {
608 VOP_ABORTOP(vp, cnp);
612 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
613 VOP_ABORTOP(dvp, cnp);
618 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
620 FREE(cnp->cn_pnbuf, M_NAMEI);
622 VOP_UNLOCK(vp, 0, curproc);
632 struct vop_rename_args /* {
633 struct vnode *a_fdvp;
635 struct componentname *a_fcnp;
636 struct vnode *a_tdvp;
638 struct componentname *a_tcnp;
642 struct componentname *fcnp = ap->a_fcnp;
644 struct componentname *tcnp = ap->a_tcnp;
646 struct vnode *tvp = ap->a_tvp;
647 struct vnode *tdvp = ap->a_tdvp;
648 struct vnode *fvp = ap->a_fvp;
649 struct vnode *fdvp = ap->a_fdvp;
652 * Check for cross-device rename.
654 if ((fvp->v_mount != tdvp->v_mount) ||
655 (tvp && (fvp->v_mount != tvp->v_mount))) {
658 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
665 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
671 * if fvp == tvp, we're just removing one name of a pair of
672 * directory entries for the same element. convert call into rename.
673 ( (pinched from NetBSD 1.0's ufs_rename())
676 if (fvp->v_type == VDIR) {
681 /* Release destination completely. */
682 VOP_ABORTOP(tdvp, tcnp);
689 fcnp->cn_flags &= ~MODMASK;
690 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
691 if ((fcnp->cn_flags & SAVESTART) == 0)
692 panic("afs_rename: lost from startdir");
693 fcnp->cn_nameiop = DELETE;
694 (void) relookup(fdvp, &fvp, fcnp);
695 return (VOP_REMOVE(fdvp, fvp, fcnp));
698 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
701 MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK);
702 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
703 fname[fcnp->cn_namelen] = '\0';
704 MALLOC(tname, char *, tcnp->cn_namelen+1, M_TEMP, M_WAITOK);
705 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
706 tname[tcnp->cn_namelen] = '\0';
710 /* XXX use "from" or "to" creds? NFS uses "to" creds */
711 code = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
714 VOP_UNLOCK(fvp, 0, curproc);
718 goto abortit; /* XXX */
732 struct vop_mkdir_args /* {
734 struct vnode **a_vpp;
735 struct componentname *a_cnp;
739 struct vnode *dvp = ap->a_dvp;
740 struct vattr *vap = ap->a_vap;
746 if ((cnp->cn_flags & HASBUF) == 0)
747 panic("afs_nbsd_mkdir: no name");
750 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
753 VOP_ABORTOP(dvp, cnp);
759 *ap->a_vpp = AFSTOV(vcp);
760 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
764 FREE(cnp->cn_pnbuf, M_NAMEI);
771 struct vop_rmdir_args /* {
774 struct componentname *a_cnp;
778 struct vnode *vp = ap->a_vp;
779 struct vnode *dvp = ap->a_dvp;
785 FREE(cnp->cn_pnbuf, M_NAMEI);
791 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
801 struct vop_symlink_args /* {
803 struct vnode **a_vpp;
804 struct componentname *a_cnp;
809 struct vnode *dvp = ap->a_dvp;
811 /* NFS ignores a_vpp; so do we. */
815 code = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
819 FREE(cnp->cn_pnbuf, M_NAMEI);
826 struct vop_readdir_args /* {
829 struct ucred *a_cred;
838 #ifdef AFS_HAVE_COOKIES
839 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
841 code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
842 ap->a_eofflag, ap->a_ncookies, ap->a_cookies);
844 code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
851 afs_nbsd_readlink(ap)
852 struct vop_readlink_args /* {
855 struct ucred *a_cred;
861 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
866 extern int prtactive;
869 afs_nbsd_inactive(ap)
870 struct vop_inactive_args /* {
874 struct vnode *vp = ap->a_vp;
875 struct vcache *vc = VTOAFS(vp);
876 int haveGlock = ISAFS_GLOCK();
878 AFS_STATCNT(afs_inactive);
880 if (prtactive && vp->v_usecount != 0)
881 vprint("afs_nbsd_inactive(): pushing active", vp);
885 afs_InactiveVCache(vc, 0); /* decrs ref counts */
889 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
895 struct vop_reclaim_args /* {
900 struct vnode *vp = ap->a_vp;
901 struct vcache *avc = VTOAFS(vp);
902 int haveGlock = ISAFS_GLOCK();
903 int haveVlock = CheckLock(&afs_xvcache);
908 ObtainWriteLock(&afs_xvcache, 901);
909 #ifndef AFS_DISCON_ENV
910 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
912 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
913 code = afs_FlushVS(avc);
916 ReleaseWriteLock(&afs_xvcache);
924 struct vop_lock_args /* {
930 struct vnode *vp = ap->a_vp;
931 struct vcache *vc = VTOAFS(vp);
934 panic("afs_nbsd_lock: null vcache");
935 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock, ap->a_p);
940 struct vop_unlock_args /* {
946 struct vnode *vp = ap->a_vp;
947 struct vcache *vc = VTOAFS(vp);
950 panic("afs_nbsd_unlock: null vcache");
951 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock, ap->a_p);
956 struct vop_bmap_args /* {
959 struct vnode **a_vpp;
964 struct vcache *vcp = VTOAFS(ap->a_vp);
966 AFS_STATCNT(afs_bmap);
968 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
970 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
975 afs_nbsd_strategy(ap)
976 struct vop_strategy_args /* {
980 struct buf *abp = ap->a_bp;
982 struct iovec tiovec[1];
983 struct vcache *tvc = VTOAFS(abp->b_vp);
984 struct ucred *credp = osi_curcred();
985 long len = abp->b_bcount;
988 AFS_STATCNT(afs_strategy);
990 tuio.afsio_iov = tiovec;
991 tuio.afsio_iovcnt = 1;
992 tuio.afsio_seg = AFS_UIOSYS;
993 tuio.afsio_resid = len;
994 tiovec[0].iov_base = abp->b_un.b_addr;
995 tiovec[0].iov_len = len;
998 if ((abp->b_flags & B_READ) == B_READ) {
999 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1000 if (code == 0 && tuio.afsio_resid > 0)
1001 bzero(abp->b_un.b_addr + len - tuio.afsio_resid, tuio.afsio_resid);
1003 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1006 ReleaseWriteLock(&tvc->lock);
1007 AFS_RELE(AFSTOV(tvc));
1013 struct vop_print_args /* {
1017 struct vnode *vp = ap->a_vp;
1018 struct vcache *vc = VTOAFS(ap->a_vp);
1020 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
1021 (int) vc->fid.Fid.Volume, (int) vc->fid.Fid.Vnode, (int) vc->fid.Fid.Unique);
1022 lockmgr_printinfo(&vc->rwlock);
1028 afs_nbsd_islocked(ap)
1029 struct vop_islocked_args /* {
1033 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1037 * Return POSIX pathconf information applicable to ufs filesystems.
1040 afs_nbsd_pathconf(ap)
1041 struct vop_pathconf_args /* {
1047 AFS_STATCNT(afs_cntl);
1048 switch (ap->a_name) {
1050 *ap->a_retval = LINK_MAX;
1053 *ap->a_retval = NAME_MAX;
1056 *ap->a_retval = PATH_MAX;
1058 case _PC_CHOWN_RESTRICTED:
1074 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid);
1077 * Advisory record locking support (fcntl() POSIX style)
1080 afs_nbsd_advlock(ap)
1081 struct vop_advlock_args /* {
1092 code = afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),