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"
102 #include "afs/sysincludes.h" /* Standard vendor system headers */
103 #include "afs/afsincludes.h" /* Afs-based standard headers */
104 #include "afs/afs_stats.h" /* statistics */
106 #include <sys/malloc.h>
107 #include <sys/namei.h>
108 #ifdef AFS_OBSD36_ENV
109 #include <sys/pool.h>
112 #include "afs/afs_cbqueue.h"
113 #include "afs/nfsclient.h"
114 #include "afs/afs_osidnlc.h"
116 #ifdef AFS_DISCON_ENV
117 extern int afs_FlushVS(struct vcache *tvc);
120 #define M_AFSNODE (M_TEMP-1) /* XXX */
122 int afs_nbsd_lookup(void *);
123 int afs_nbsd_create(void *);
124 int afs_nbsd_mknod(void *);
125 int afs_nbsd_open(void *);
126 int afs_nbsd_close(void *);
127 int afs_nbsd_access(void *);
128 int afs_nbsd_getattr(void *);
129 int afs_nbsd_setattr(void *);
130 int afs_nbsd_read(void *);
131 int afs_nbsd_write(void *);
132 int afs_nbsd_ioctl(void *);
133 int afs_nbsd_select(void *);
134 int afs_nbsd_fsync(void *);
135 int afs_nbsd_remove(void *);
136 int afs_nbsd_link(void *);
137 int afs_nbsd_rename(void *);
138 int afs_nbsd_mkdir(void *);
139 int afs_nbsd_rmdir(void *);
140 int afs_nbsd_symlink(void *);
141 int afs_nbsd_readdir(void *);
142 int afs_nbsd_readlink(void *);
143 int afs_nbsd_inactive(void *);
144 int afs_nbsd_reclaim(void *);
145 int afs_nbsd_lock(void *);
146 int afs_nbsd_unlock(void *);
147 int afs_nbsd_bmap(void *);
148 int afs_nbsd_strategy(void *);
149 int afs_nbsd_print(void *);
150 int afs_nbsd_islocked(void *);
151 int afs_nbsd_pathconf(void *);
152 int afs_nbsd_advlock(void *);
154 #define afs_nbsd_opnotsupp \
155 ((int (*) __P((void *)))eopnotsupp)
156 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
158 /* Global vfs data structures for AFS. */
159 int (**afs_vnodeop_p) __P((void *));
160 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
161 #ifdef AFS_OBSD44_ENV /* feel free to zero in on this */
162 {&vop_default_desc, eopnotsupp},
164 {&vop_default_desc, vn_default_error},
166 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
167 {&vop_create_desc, afs_nbsd_create}, /* create */
168 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
169 {&vop_open_desc, afs_nbsd_open}, /* open */
170 {&vop_close_desc, afs_nbsd_close}, /* close */
171 {&vop_access_desc, afs_nbsd_access}, /* access */
172 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
173 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
174 {&vop_read_desc, afs_nbsd_read}, /* read */
175 {&vop_write_desc, afs_nbsd_write}, /* write */
176 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
177 #ifdef AFS_OBSD35_ENV
178 {&vop_poll_desc, afs_nbsd_select}, /* select */
180 {&vop_select_desc, afs_nbsd_select}, /* select */
182 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
183 {&vop_remove_desc, afs_nbsd_remove}, /* remove */
184 {&vop_link_desc, afs_nbsd_link}, /* link */
185 {&vop_rename_desc, afs_nbsd_rename}, /* rename */
186 {&vop_mkdir_desc, afs_nbsd_mkdir}, /* mkdir */
187 {&vop_rmdir_desc, afs_nbsd_rmdir}, /* rmdir */
188 {&vop_symlink_desc, afs_nbsd_symlink}, /* symlink */
189 {&vop_readdir_desc, afs_nbsd_readdir}, /* readdir */
190 {&vop_readlink_desc, afs_nbsd_readlink}, /* readlink */
191 {&vop_abortop_desc, vop_generic_abortop}, /* abortop */
192 {&vop_inactive_desc, afs_nbsd_inactive}, /* inactive */
193 {&vop_reclaim_desc, afs_nbsd_reclaim}, /* reclaim */
194 {&vop_lock_desc, afs_nbsd_lock}, /* lock */
195 {&vop_unlock_desc, afs_nbsd_unlock}, /* unlock */
196 {&vop_bmap_desc, afs_nbsd_bmap}, /* bmap */
197 {&vop_strategy_desc, afs_nbsd_strategy}, /* strategy */
198 {&vop_print_desc, afs_nbsd_print}, /* print */
199 {&vop_islocked_desc, afs_nbsd_islocked}, /* islocked */
200 {&vop_pathconf_desc, afs_nbsd_pathconf}, /* pathconf */
201 {&vop_advlock_desc, afs_nbsd_advlock}, /* advlock */
202 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
203 {&vop_bwrite_desc, vop_generic_bwrite},
204 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
206 struct vnodeopv_desc afs_vnodeop_opv_desc =
207 { &afs_vnodeop_p, afs_vnodeop_entries };
210 struct componentname *cnp = ap->a_cnp; \
212 BSD_KMALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
213 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
214 name[cnp->cn_namelen] = '\0'
216 #define DROPNAME() BSD_KFREE(name, M_TEMP)
218 #ifdef AFS_OBSD36_ENV
219 #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
221 #define DROPCNP(cnp) FREE((cnp)->cn_pnbuf, M_NAMEI)
227 afs_nbsd_lookup(void *v)
229 struct vop_lookup_args /* {
230 * struct vnodeop_desc * a_desc;
231 * struct vnode *a_dvp;
232 * struct vnode **a_vpp;
233 * struct componentname *a_cnp;
237 struct vnode *vp, *dvp;
238 int flags = ap->a_cnp->cn_flags;
239 int lockparent; /* 1 => lockparent flag is set */
240 int wantparent; /* 1 => wantparent or lockparent flag */
243 lockparent = flags & LOCKPARENT;
244 wantparent = flags & (LOCKPARENT | WANTPARENT);
246 cnp->cn_flags &= ~PDIRUNLOCK;
249 if (ap->a_dvp->v_type != VDIR) {
255 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
256 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
257 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 */
274 * The parent directory comes in locked. We unlock it on return
275 * unless the caller wants it left locked.
276 * we also always return the vnode locked.
280 /* they're the same; afs_lookup() already ref'ed the leaf.
281 * It came in locked, so we don't need to ref OR lock it */
282 if (afs_debug & AFSDEB_VNLAYER)
283 printf("ref'ed %p as .\n", dvp);
285 if (!lockparent || !(flags & ISLASTCN)) {
286 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
288 cnp->cn_flags |= PDIRUNLOCK;
291 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
292 if (afs_debug & AFSDEB_VNLAYER)
293 printf("locked ret %p from lookup\n", vp);
297 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
298 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
299 cnp->cn_flags |= SAVENAME;
302 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
303 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
308 afs_nbsd_create(void *v)
310 struct vop_create_args /* {
311 * struct vnode *a_dvp;
312 * struct vnode **a_vpp;
313 * struct componentname *a_cnp;
314 * struct vattr *a_vap;
318 struct vnode *dvp = ap->a_dvp;
321 if (afs_debug & AFSDEB_VNLAYER)
322 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
324 /* vnode layer handles excl/nonexcl */
328 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
332 VOP_ABORTOP(dvp, cnp);
339 *ap->a_vpp = AFSTOV(vcp);
340 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
344 if ((cnp->cn_flags & SAVESTART) == 0)
348 if (afs_debug & AFSDEB_VNLAYER)
349 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
354 afs_nbsd_mknod(void *v)
356 struct vop_mknod_args /* {
357 * struct vnode *a_dvp;
358 * struct vnode **a_vpp;
359 * struct componentname *a_cnp;
360 * struct vattr *a_vap;
368 afs_nbsd_open(void *v)
370 struct vop_open_args /* {
371 * struct vnode *a_vp;
373 * struct ucred *a_cred;
377 struct vcache *vc = VTOAFS(ap->a_vp);
380 code = afs_open(&vc, ap->a_mode, ap->a_cred);
382 if (AFSTOV(vc) != ap->a_vp)
383 panic("AFS open changed vnode!");
390 afs_nbsd_close(void *v)
392 struct vop_close_args /* {
393 * struct vnode *a_vp;
395 * struct ucred *a_cred;
401 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
407 afs_nbsd_access(void *v)
409 struct vop_access_args /* {
410 * struct vnode *a_vp;
412 * struct ucred *a_cred;
418 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
424 afs_nbsd_getattr(void *v)
426 struct vop_getattr_args /* {
427 * struct vnode *a_vp;
428 * struct vattr *a_vap;
429 * struct ucred *a_cred;
435 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
441 afs_nbsd_setattr(void *v)
443 struct vop_setattr_args /* {
444 * struct vnode *a_vp;
445 * struct vattr *a_vap;
446 * struct ucred *a_cred;
452 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
458 afs_nbsd_read(void *v)
460 struct vop_read_args /* {
461 * struct vnode *a_vp;
464 * struct ucred *a_cred;
470 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
477 afs_nbsd_write(void *v)
479 struct vop_write_args /* {
480 * struct vnode *a_vp;
483 * struct ucred *a_cred;
488 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
490 vnode_pager_uncache(ap->a_vp);
494 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
500 afs_nbsd_ioctl(void *v)
502 struct vop_ioctl_args /* {
503 * struct vnode *a_vp;
507 * 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 */
519 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
520 (struct afs_ioctl *)ap->a_data);
522 /* No-op call; just return. */
529 afs_nbsd_select(void *v)
535 afs_nbsd_fsync(void *v)
537 struct vop_fsync_args /* {
538 * struct vnode *a_vp;
539 * 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);
555 afs_nbsd_remove(void *v)
557 struct vop_remove_args /* {
558 * struct vnode *a_dvp;
559 * struct vnode *a_vp;
560 * 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);
581 afs_nbsd_link(void *v)
583 struct vop_link_args /* {
584 * struct vnode *a_vp;
585 * struct vnode *a_tdvp;
586 * 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);
613 VOP_UNLOCK(vp, 0, curproc);
622 afs_nbsd_rename(void *v)
624 struct vop_rename_args /* {
625 * struct vnode *a_fdvp;
626 * struct vnode *a_fvp;
627 * struct componentname *a_fcnp;
628 * struct vnode *a_tdvp;
629 * struct vnode *a_tvp;
630 * 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 BSD_KMALLOC(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 BSD_KMALLOC(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 */
703 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
706 VOP_UNLOCK(fvp, 0, curproc);
707 BSD_KFREE(fname, M_TEMP);
708 BSD_KFREE(tname, M_TEMP);
710 goto abortit; /* XXX */
723 afs_nbsd_mkdir(void *v)
725 struct vop_mkdir_args /* {
726 * struct vnode *a_dvp;
727 * struct vnode **a_vpp;
728 * struct componentname *a_cnp;
729 * struct vattr *a_vap;
731 struct vnode *dvp = ap->a_dvp;
732 struct vattr *vap = ap->a_vap;
738 if ((cnp->cn_flags & HASBUF) == 0)
739 panic("afs_nbsd_mkdir: no name");
742 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
745 VOP_ABORTOP(dvp, cnp);
751 *ap->a_vpp = AFSTOV(vcp);
752 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
762 afs_nbsd_rmdir(void *v)
764 struct vop_rmdir_args /* {
765 * struct vnode *a_dvp;
766 * struct vnode *a_vp;
767 * struct componentname *a_cnp;
770 struct vnode *vp = ap->a_vp;
771 struct vnode *dvp = ap->a_dvp;
783 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
792 afs_nbsd_symlink(void *v)
794 struct vop_symlink_args /* {
795 * struct vnode *a_dvp;
796 * struct vnode **a_vpp;
797 * struct componentname *a_cnp;
798 * struct vattr *a_vap;
801 struct vnode *dvp = ap->a_dvp;
803 /* NFS ignores a_vpp; so do we. */
808 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
817 afs_nbsd_readdir(void *v)
819 struct vop_readdir_args /* {
820 * struct vnode *a_vp;
822 * struct ucred *a_cred;
825 * u_long **a_cookies;
830 #ifdef AFS_HAVE_COOKIES
831 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
834 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
835 ap->a_ncookies, ap->a_cookies);
838 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
845 afs_nbsd_readlink(void *v)
847 struct vop_readlink_args /* {
848 * struct vnode *a_vp;
850 * struct ucred *a_cred;
855 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
860 extern int prtactive;
863 afs_nbsd_inactive(void *v)
865 struct vop_inactive_args /* {
866 * struct vnode *a_vp;
868 struct vnode *vp = ap->a_vp;
869 struct vcache *vc = VTOAFS(vp);
870 int haveGlock = ISAFS_GLOCK();
872 AFS_STATCNT(afs_inactive);
874 if (prtactive && vp->v_usecount != 0)
875 vprint("afs_nbsd_inactive(): pushing active", vp);
879 afs_InactiveVCache(vc, 0); /* decrs ref counts */
883 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
888 afs_nbsd_reclaim(void *v)
890 struct vop_reclaim_args /* {
891 * struct vnode *a_vp;
894 struct vnode *vp = ap->a_vp;
895 struct vcache *avc = VTOAFS(vp);
896 int haveGlock = ISAFS_GLOCK();
897 int haveVlock = CheckLock(&afs_xvcache);
900 printf("reclaim usecount %d\n", vp->v_usecount);
901 /* OK, there are no internal vrefCounts, so there shouldn't
902 * be any more refs here. */
903 vp->v_data = NULL; /* remove from vnode */
904 avc->v = NULL; /* also drop the ptr to vnode */
910 ObtainWriteLock(&afs_xvcache, 901);
911 #ifndef AFS_DISCON_ENV
912 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
914 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
915 code = afs_FlushVS(avc);
918 ReleaseWriteLock(&afs_xvcache);
925 #ifdef AFS_OBSD42_ENV
926 #define VP_INTERLOCK NULL
928 #define VP_INTERLOCK (&vp->v_interlock)
932 afs_nbsd_lock(void *v)
934 struct vop_lock_args /* {
935 * struct vnode *a_vp;
939 struct vnode *vp = ap->a_vp;
940 struct vcache *vc = VTOAFS(vp);
943 panic("afs_nbsd_lock: null vcache");
944 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, VP_INTERLOCK, ap->a_p);
948 afs_nbsd_unlock(void *v)
950 struct vop_unlock_args /* {
951 * struct vnode *a_vp;
955 struct vnode *vp = ap->a_vp;
956 struct vcache *vc = VTOAFS(vp);
959 panic("afs_nbsd_unlock: null vcache");
960 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, VP_INTERLOCK, ap->a_p);
964 afs_nbsd_bmap(void *v)
966 struct vop_bmap_args /* {
967 * struct vnode *a_vp;
969 * struct vnode **a_vpp;
973 struct vcache *vcp = VTOAFS(ap->a_vp);
975 AFS_STATCNT(afs_bmap);
977 *ap->a_bnp = ap->a_bn * btodb(8192);
979 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
984 afs_nbsd_strategy(void *v)
986 struct vop_strategy_args /* {
989 struct buf *abp = ap->a_bp;
991 struct iovec tiovec[1];
992 struct vcache *tvc = VTOAFS(abp->b_vp);
993 struct ucred *credp = osi_curcred();
994 long len = abp->b_bcount;
997 AFS_STATCNT(afs_strategy);
999 tuio.afsio_iov = tiovec;
1000 tuio.afsio_iovcnt = 1;
1001 tuio.afsio_seg = AFS_UIOSYS;
1002 tuio.afsio_resid = len;
1003 tiovec[0].iov_base = abp->b_data;
1004 tiovec[0].iov_len = len;
1007 if ((abp->b_flags & B_READ) == B_READ) {
1008 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1009 if (code == 0 && tuio.afsio_resid > 0)
1010 bzero(abp->b_data + len - tuio.afsio_resid, tuio.afsio_resid);
1012 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1015 ReleaseWriteLock(&tvc->lock);
1016 AFS_RELE(AFSTOV(tvc));
1021 afs_nbsd_print(void *v)
1023 struct vop_print_args /* {
1024 * struct vnode *a_vp;
1026 struct vnode *vp = ap->a_vp;
1027 struct vcache *vc = VTOAFS(ap->a_vp);
1029 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1030 (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
1031 (int)vc->f.fid.Fid.Unique);
1032 lockmgr_printinfo(&vc->rwlock);
1038 afs_nbsd_islocked(void *v)
1040 struct vop_islocked_args /* {
1041 * struct vnode *a_vp;
1043 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1047 * Return POSIX pathconf information applicable to ufs filesystems.
1050 afs_nbsd_pathconf(void *v)
1052 struct vop_pathconf_args /* {
1053 * struct vnode *a_vp;
1057 AFS_STATCNT(afs_cntl);
1058 switch (ap->a_name) {
1060 *ap->a_retval = LINK_MAX;
1063 *ap->a_retval = NAME_MAX;
1066 *ap->a_retval = PATH_MAX;
1068 case _PC_CHOWN_RESTRICTED:
1084 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1085 afs_ucred_t *acred, pid_t clid);
1088 * Advisory record locking support (fcntl() POSIX style)
1091 afs_nbsd_advlock(void *v)
1093 struct vop_advlock_args /* {
1094 * struct vnode *a_vp;
1097 * struct flock *a_fl;
1104 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),