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);
259 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
262 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
263 (flags & ISLASTCN) && code == ENOENT)
265 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
266 cnp->cn_flags |= SAVENAME;
271 vp = AFSTOV(vcp); /* always get a node if no error */
273 /* The parent directory comes in locked. We unlock it on return
274 unless the caller wants it left locked.
275 we also always return the vnode locked. */
278 /* they're the same; afs_lookup() already ref'ed the leaf.
279 It came in locked, so we don't need to ref OR lock it */
280 if (afs_debug & AFSDEB_VNLAYER)
281 printf("ref'ed %p as .\n", dvp);
283 if (!lockparent || !(flags & ISLASTCN))
284 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
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 /* {
305 struct vnode **a_vpp;
306 struct componentname *a_cnp;
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 */
321 code = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
322 ap->a_vap->va_mode, &vcp,
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 /* {
351 struct vnode **a_vpp;
352 struct componentname *a_cnp;
356 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
363 struct vop_open_args /* {
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 /* {
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 /* {
405 struct ucred *a_cred;
412 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
419 struct vop_getattr_args /* {
422 struct ucred *a_cred;
429 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
436 struct vop_setattr_args /* {
439 struct ucred *a_cred;
446 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
453 struct vop_read_args /* {
457 struct ucred *a_cred;
463 code = afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0, 0, 0);
470 struct vop_write_args /* {
474 struct ucred *a_cred;
480 (void) uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
482 vnode_pager_uncache(ap->a_vp);
485 code = afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
492 struct vop_ioctl_args /* {
497 struct ucred *a_cred;
503 /* in case we ever get in here... */
505 AFS_STATCNT(afs_ioctl);
507 if (((ap->a_command >> 8) & 0xff) == 'V')
508 /* This is a VICEIOCTL call */
509 code = HandleIoctl(VTOAFS(ap->a_vp), ap->a_command, (struct afs_ioctl *) ap->a_data);
511 /* No-op call; just return. */
520 struct vop_select_args /* {
524 struct ucred *a_cred;
529 * We should really check to see if I/O is possible.
536 struct vop_fsync_args /* {
538 struct ucred *a_cred;
543 int wait = ap->a_waitfor == MNT_WAIT;
544 struct vnode *vp = ap->a_vp;
549 code = afs_fsync(VTOAFS(vp), ap->a_cred);
556 struct vop_remove_args /* {
559 struct componentname *a_cnp;
563 struct vnode *vp = ap->a_vp;
564 struct vnode *dvp = ap->a_dvp;
568 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
575 FREE(cnp->cn_pnbuf, M_NAMEI);
582 struct vop_link_args /* {
584 struct vnode *a_tdvp;
585 struct componentname *a_cnp;
589 struct vnode *dvp = ap->a_dvp;
590 struct vnode *vp = ap->a_vp;
593 if (dvp->v_mount != vp->v_mount) {
594 VOP_ABORTOP(vp, cnp);
598 if (vp->v_type == VDIR) {
599 VOP_ABORTOP(vp, cnp);
603 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
604 VOP_ABORTOP(dvp, cnp);
609 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
611 FREE(cnp->cn_pnbuf, M_NAMEI);
613 VOP_UNLOCK(vp, 0, curproc);
623 struct vop_rename_args /* {
624 struct vnode *a_fdvp;
626 struct componentname *a_fcnp;
627 struct vnode *a_tdvp;
629 struct componentname *a_tcnp;
633 struct componentname *fcnp = ap->a_fcnp;
635 struct componentname *tcnp = ap->a_tcnp;
637 struct vnode *tvp = ap->a_tvp;
638 struct vnode *tdvp = ap->a_tdvp;
639 struct vnode *fvp = ap->a_fvp;
640 struct vnode *fdvp = ap->a_fdvp;
643 * Check for cross-device rename.
645 if ((fvp->v_mount != tdvp->v_mount) ||
646 (tvp && (fvp->v_mount != tvp->v_mount))) {
649 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
656 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
662 * if fvp == tvp, we're just removing one name of a pair of
663 * directory entries for the same element. convert call into rename.
664 ( (pinched from NetBSD 1.0's ufs_rename())
667 if (fvp->v_type == VDIR) {
672 /* Release destination completely. */
673 VOP_ABORTOP(tdvp, tcnp);
680 fcnp->cn_flags &= ~MODMASK;
681 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
682 if ((fcnp->cn_flags & SAVESTART) == 0)
683 panic("afs_rename: lost from startdir");
684 fcnp->cn_nameiop = DELETE;
685 (void) relookup(fdvp, &fvp, fcnp);
686 return (VOP_REMOVE(fdvp, fvp, fcnp));
689 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
692 MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK);
693 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
694 fname[fcnp->cn_namelen] = '\0';
695 MALLOC(tname, char *, tcnp->cn_namelen+1, M_TEMP, M_WAITOK);
696 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
697 tname[tcnp->cn_namelen] = '\0';
701 /* XXX use "from" or "to" creds? NFS uses "to" creds */
702 code = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
705 VOP_UNLOCK(fvp, 0, curproc);
709 goto abortit; /* XXX */
723 struct vop_mkdir_args /* {
725 struct vnode **a_vpp;
726 struct componentname *a_cnp;
730 struct vnode *dvp = ap->a_dvp;
731 struct vattr *vap = ap->a_vap;
737 if ((cnp->cn_flags & HASBUF) == 0)
738 panic("afs_nbsd_mkdir: no name");
741 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
744 VOP_ABORTOP(dvp, cnp);
750 *ap->a_vpp = AFSTOV(vcp);
751 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
755 FREE(cnp->cn_pnbuf, M_NAMEI);
762 struct vop_rmdir_args /* {
765 struct componentname *a_cnp;
769 struct vnode *vp = ap->a_vp;
770 struct vnode *dvp = ap->a_dvp;
776 FREE(cnp->cn_pnbuf, M_NAMEI);
782 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
792 struct vop_symlink_args /* {
794 struct vnode **a_vpp;
795 struct componentname *a_cnp;
800 struct vnode *dvp = ap->a_dvp;
802 /* NFS ignores a_vpp; so do we. */
806 code = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
810 FREE(cnp->cn_pnbuf, M_NAMEI);
817 struct vop_readdir_args /* {
820 struct ucred *a_cred;
829 #ifdef AFS_HAVE_COOKIES
830 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
832 code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
833 ap->a_eofflag, ap->a_ncookies, ap->a_cookies);
835 code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
842 afs_nbsd_readlink(ap)
843 struct vop_readlink_args /* {
846 struct ucred *a_cred;
852 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
857 extern int prtactive;
860 afs_nbsd_inactive(ap)
861 struct vop_inactive_args /* {
865 struct vnode *vp = ap->a_vp;
866 struct vcache *vc = VTOAFS(vp);
868 AFS_STATCNT(afs_inactive);
870 if (prtactive && vp->v_usecount != 0)
871 vprint("afs_nbsd_inactive(): pushing active", vp);
873 vc->states &= ~CMAPPED;
874 vc->states &= ~CDirty;
876 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
882 struct vop_reclaim_args /* {
887 struct vnode *vp = ap->a_vp;
888 struct vcache *avc = VTOAFS(vp);
890 cache_purge(vp); /* just in case... */
894 vnode_pager_uncache(vp);
898 #ifndef AFS_DISCON_ENV
899 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
901 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
902 code = afs_FlushVS(avc);
905 if (!code && vp->v_data)
906 panic("afs_reclaim: vnode not cleaned");
912 struct vop_lock_args /* {
918 struct vnode *vp = ap->a_vp;
919 struct vcache *vc = VTOAFS(vp);
923 panic("afs_nbsd_lock: null vcache");
925 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock, ap->a_p);
930 struct vop_unlock_args /* {
936 struct vnode *vp = ap->a_vp;
937 struct vcache *vc = VTOAFS(vp);
941 panic("afs_nbsd_unlock: null vcache");
943 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock, ap->a_p);
948 struct vop_bmap_args /* {
951 struct vnode **a_vpp;
956 struct vcache *vcp = VTOAFS(ap->a_vp);
958 AFS_STATCNT(afs_bmap);
960 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
962 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
967 afs_nbsd_strategy(ap)
968 struct vop_strategy_args /* {
972 struct buf *abp = ap->a_bp;
974 struct iovec tiovec[1];
975 struct vcache *tvc = VTOAFS(abp->b_vp);
976 struct ucred *credp = osi_curcred();
977 long len = abp->b_bcount;
980 AFS_STATCNT(afs_strategy);
982 tuio.afsio_iov = tiovec;
983 tuio.afsio_iovcnt = 1;
984 tuio.afsio_seg = AFS_UIOSYS;
985 tuio.afsio_resid = len;
986 tiovec[0].iov_base = abp->b_un.b_addr;
987 tiovec[0].iov_len = len;
990 if ((abp->b_flags & B_READ) == B_READ) {
991 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
992 if (code == 0 && tuio.afsio_resid > 0)
993 bzero(abp->b_un.b_addr + len - tuio.afsio_resid, tuio.afsio_resid);
995 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
998 ReleaseWriteLock(&tvc->lock);
999 AFS_RELE(AFSTOV(tvc));
1005 struct vop_print_args /* {
1009 struct vnode *vp = ap->a_vp;
1010 struct vcache *vc = VTOAFS(ap->a_vp);
1012 printf("tag %d, fid: %ld.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
1013 (int) vc->fid.Fid.Volume, (int) vc->fid.Fid.Vnode, (int) vc->fid.Fid.Unique);
1014 lockmgr_printinfo(&vc->rwlock);
1020 afs_nbsd_islocked(ap)
1021 struct vop_islocked_args /* {
1025 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1029 * Return POSIX pathconf information applicable to ufs filesystems.
1032 afs_nbsd_pathconf(ap)
1033 struct vop_pathconf_args /* {
1039 AFS_STATCNT(afs_cntl);
1040 switch (ap->a_name) {
1042 *ap->a_retval = LINK_MAX;
1045 *ap->a_retval = NAME_MAX;
1048 *ap->a_retval = PATH_MAX;
1050 case _PC_CHOWN_RESTRICTED:
1066 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid);
1069 * Advisory record locking support (fcntl() POSIX style)
1072 afs_nbsd_advlock(ap)
1073 struct vop_advlock_args /* {
1084 code = afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),