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 Transarc AFS 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 if (ap->a_dvp->v_type != VDIR) {
256 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
257 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags, name, dvp->v_usecount);
258 error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
260 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
261 (flags & ISLASTCN) && error == ENOENT)
263 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
264 cnp->cn_flags |= SAVENAME;
269 vp = AFSTOV(vcp); /* always get a node if no error */
271 /* The parent directory comes in locked. We unlock it on return
272 unless the caller wants it left locked.
273 we also always return the vnode locked. */
276 /* they're the same; afs_lookup() already ref'ed the leaf.
277 It came in locked, so we don't need to ref OR lock it */
278 if (afs_debug & AFSDEB_VNLAYER)
279 printf("ref'ed %p as .\n", dvp);
281 if (!lockparent || !(flags & ISLASTCN))
282 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
283 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
284 if (afs_debug & AFSDEB_VNLAYER)
285 printf("locked ret %p from lookup\n", vp);
289 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
290 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
291 cnp->cn_flags |= SAVENAME;
294 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
295 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
301 struct vop_create_args /* {
303 struct vnode **a_vpp;
304 struct componentname *a_cnp;
310 struct vnode *dvp = ap->a_dvp;
313 if (afs_debug & AFSDEB_VNLAYER)
314 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
316 /* vnode layer handles excl/nonexcl */
318 error = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
319 ap->a_vap->va_mode, &vcp,
322 VOP_ABORTOP(dvp, cnp);
329 *ap->a_vpp = AFSTOV(vcp);
330 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
334 if ((cnp->cn_flags & SAVESTART) == 0)
335 FREE(cnp->cn_pnbuf, M_NAMEI);
338 if (afs_debug & AFSDEB_VNLAYER)
339 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
345 struct vop_mknod_args /* {
347 struct vnode **a_vpp;
348 struct componentname *a_cnp;
352 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
359 struct vop_open_args /* {
362 struct ucred *a_cred;
367 struct vcache *vc = VTOAFS(ap->a_vp);
369 error = afs_open(&vc, ap->a_mode, ap->a_cred);
371 if (AFSTOV(vc) != ap->a_vp)
372 panic("AFS open changed vnode!");
379 struct vop_close_args /* {
382 struct ucred *a_cred;
386 return afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
391 struct vop_access_args /* {
394 struct ucred *a_cred;
398 return afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
402 struct vop_getattr_args /* {
405 struct ucred *a_cred;
409 return afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
413 struct vop_setattr_args /* {
416 struct ucred *a_cred;
420 return afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
424 struct vop_read_args /* {
428 struct ucred *a_cred;
431 return afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0, 0, 0);
435 struct vop_write_args /* {
439 struct ucred *a_cred;
443 (void) uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
445 vnode_pager_uncache(ap->a_vp);
447 return afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
451 struct vop_ioctl_args /* {
456 struct ucred *a_cred;
460 /* in case we ever get in here... */
462 AFS_STATCNT(afs_ioctl);
463 if (((ap->a_command >> 8) & 0xff) == 'V')
464 /* This is a VICEIOCTL call */
465 return HandleIoctl(VTOAFS(ap->a_vp), ap->a_command, (struct afs_ioctl *) ap->a_data);
467 /* No-op call; just return. */
474 struct vop_select_args /* {
478 struct ucred *a_cred;
483 * We should really check to see if I/O is possible.
490 struct vop_fsync_args /* {
492 struct ucred *a_cred;
497 int wait = ap->a_waitfor == MNT_WAIT;
498 struct vnode *vp = ap->a_vp;
501 return afs_fsync(VTOAFS(vp), ap->a_cred);
506 struct vop_remove_args /* {
509 struct componentname *a_cnp;
513 struct vnode *vp = ap->a_vp;
514 struct vnode *dvp = ap->a_dvp;
517 error = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
523 FREE(cnp->cn_pnbuf, M_NAMEI);
530 struct vop_link_args /* {
532 struct vnode *a_tdvp;
533 struct componentname *a_cnp;
537 struct vnode *dvp = ap->a_dvp;
538 struct vnode *vp = ap->a_vp;
541 if (dvp->v_mount != vp->v_mount) {
542 VOP_ABORTOP(vp, cnp);
546 if (vp->v_type == VDIR) {
547 VOP_ABORTOP(vp, cnp);
551 if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
552 VOP_ABORTOP(dvp, cnp);
556 error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
557 FREE(cnp->cn_pnbuf, M_NAMEI);
559 VOP_UNLOCK(vp, 0, curproc);
569 struct vop_rename_args /* {
570 struct vnode *a_fdvp;
572 struct componentname *a_fcnp;
573 struct vnode *a_tdvp;
575 struct componentname *a_tcnp;
579 struct componentname *fcnp = ap->a_fcnp;
581 struct componentname *tcnp = ap->a_tcnp;
583 struct vnode *tvp = ap->a_tvp;
584 struct vnode *tdvp = ap->a_tdvp;
585 struct vnode *fvp = ap->a_fvp;
586 struct vnode *fdvp = ap->a_fdvp;
589 * Check for cross-device rename.
591 if ((fvp->v_mount != tdvp->v_mount) ||
592 (tvp && (fvp->v_mount != tvp->v_mount))) {
595 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
602 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
608 * if fvp == tvp, we're just removing one name of a pair of
609 * directory entries for the same element. convert call into rename.
610 ( (pinched from NetBSD 1.0's ufs_rename())
613 if (fvp->v_type == VDIR) {
618 /* Release destination completely. */
619 VOP_ABORTOP(tdvp, tcnp);
626 fcnp->cn_flags &= ~MODMASK;
627 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
628 if ((fcnp->cn_flags & SAVESTART) == 0)
629 panic("afs_rename: lost from startdir");
630 fcnp->cn_nameiop = DELETE;
631 (void) relookup(fdvp, &fvp, fcnp);
632 return (VOP_REMOVE(fdvp, fvp, fcnp));
635 if ((error = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
638 MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK);
639 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
640 fname[fcnp->cn_namelen] = '\0';
641 MALLOC(tname, char *, tcnp->cn_namelen+1, M_TEMP, M_WAITOK);
642 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
643 tname[tcnp->cn_namelen] = '\0';
646 /* XXX use "from" or "to" creds? NFS uses "to" creds */
647 error = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
649 VOP_UNLOCK(fvp, 0, curproc);
653 goto abortit; /* XXX */
667 struct vop_mkdir_args /* {
669 struct vnode **a_vpp;
670 struct componentname *a_cnp;
674 struct vnode *dvp = ap->a_dvp;
675 struct vattr *vap = ap->a_vap;
681 if ((cnp->cn_flags & HASBUF) == 0)
682 panic("afs_nbsd_mkdir: no name");
684 error = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
686 VOP_ABORTOP(dvp, cnp);
692 *ap->a_vpp = AFSTOV(vcp);
693 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
697 FREE(cnp->cn_pnbuf, M_NAMEI);
704 struct vop_rmdir_args /* {
707 struct componentname *a_cnp;
711 struct vnode *vp = ap->a_vp;
712 struct vnode *dvp = ap->a_dvp;
718 FREE(cnp->cn_pnbuf, M_NAMEI);
723 error = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
732 struct vop_symlink_args /* {
734 struct vnode **a_vpp;
735 struct componentname *a_cnp;
740 struct vnode *dvp = ap->a_dvp;
742 /* NFS ignores a_vpp; so do we. */
745 error = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
748 FREE(cnp->cn_pnbuf, M_NAMEI);
755 struct vop_readdir_args /* {
758 struct ucred *a_cred;
764 #ifdef AFS_HAVE_COOKIES
765 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
767 return afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
768 ap->a_eofflag, ap->a_ncookies, ap->a_cookies);
770 return afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
775 afs_nbsd_readlink(ap)
776 struct vop_readlink_args /* {
779 struct ucred *a_cred;
782 /* printf("readlink %p\n", ap->a_vp);*/
783 return afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
786 extern int prtactive;
789 afs_nbsd_inactive(ap)
790 struct vop_inactive_args /* {
794 struct vnode *vp = ap->a_vp;
795 struct vcache *vc = VTOAFS(vp);
797 AFS_STATCNT(afs_inactive);
799 if (prtactive && vp->v_usecount != 0)
800 vprint("afs_nbsd_inactive(): pushing active", vp);
802 vc->states &= ~CMAPPED;
803 vc->states &= ~CDirty;
805 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
811 struct vop_reclaim_args /* {
816 struct vnode *vp = ap->a_vp;
817 struct vcache *avc = VTOAFS(vp);
819 cache_purge(vp); /* just in case... */
823 vnode_pager_uncache(vp);
826 #ifndef AFS_DISCON_ENV
827 error = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
829 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
830 error = afs_FlushVS(avc);
832 if (!error && vp->v_data)
833 panic("afs_reclaim: vnode not cleaned");
839 struct vop_lock_args /* {
845 struct vnode *vp = ap->a_vp;
846 struct vcache *vc = VTOAFS(vp);
850 panic("afs_nbsd_lock: null vcache");
852 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock, ap->a_p);
857 struct vop_unlock_args /* {
863 struct vnode *vp = ap->a_vp;
864 struct vcache *vc = VTOAFS(vp);
868 panic("afs_nbsd_unlock: null vcache");
870 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock, ap->a_p);
875 struct vop_bmap_args /* {
878 struct vnode **a_vpp;
883 struct vcache *vcp = VTOAFS(ap->a_vp);
885 AFS_STATCNT(afs_bmap);
887 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
889 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
894 afs_nbsd_strategy(ap)
895 struct vop_strategy_args /* {
899 struct buf *abp = ap->a_bp;
901 struct iovec tiovec[1];
902 struct vcache *tvc = VTOAFS(abp->b_vp);
903 struct ucred *credp = osi_curcred();
904 long len = abp->b_bcount;
907 AFS_STATCNT(afs_strategy);
909 tuio.afsio_iov = tiovec;
910 tuio.afsio_iovcnt = 1;
911 tuio.afsio_seg = AFS_UIOSYS;
912 tuio.afsio_resid = len;
913 tiovec[0].iov_base = abp->b_un.b_addr;
914 tiovec[0].iov_len = len;
916 if ((abp->b_flags & B_READ) == B_READ) {
917 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
918 if (code == 0 && tuio.afsio_resid > 0)
919 bzero(abp->b_un.b_addr + len - tuio.afsio_resid, tuio.afsio_resid);
921 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
923 ReleaseWriteLock(&tvc->lock);
924 AFS_RELE(AFSTOV(tvc));
930 struct vop_print_args /* {
934 struct vnode *vp = ap->a_vp;
935 struct vcache *vc = VTOAFS(ap->a_vp);
937 printf("tag %d, fid: %ld.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
938 (int) vc->fid.Fid.Volume, (int) vc->fid.Fid.Vnode, (int) vc->fid.Fid.Unique);
939 lockmgr_printinfo(&vc->rwlock);
945 afs_nbsd_islocked(ap)
946 struct vop_islocked_args /* {
950 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
954 * Return POSIX pathconf information applicable to ufs filesystems.
957 afs_nbsd_pathconf(ap)
958 struct vop_pathconf_args /* {
964 AFS_STATCNT(afs_cntl);
965 switch (ap->a_name) {
967 *ap->a_retval = LINK_MAX;
970 *ap->a_retval = NAME_MAX;
973 *ap->a_retval = PATH_MAX;
975 case _PC_CHOWN_RESTRICTED:
991 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid);
994 * Advisory record locking support (fcntl() POSIX style)
998 struct vop_advlock_args /* {
1006 return afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),