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 #define M_AFSNODE (M_TEMP-1) /* XXX */
118 int afs_obsd_lookup(void *);
119 int afs_obsd_create(void *);
120 int afs_obsd_mknod(void *);
121 int afs_obsd_open(void *);
122 int afs_obsd_close(void *);
123 int afs_obsd_access(void *);
124 int afs_obsd_getattr(void *);
125 int afs_obsd_setattr(void *);
126 int afs_obsd_read(void *);
127 int afs_obsd_write(void *);
128 int afs_obsd_ioctl(void *);
129 int afs_obsd_select(void *);
130 int afs_obsd_fsync(void *);
131 int afs_obsd_remove(void *);
132 int afs_obsd_link(void *);
133 int afs_obsd_rename(void *);
134 int afs_obsd_mkdir(void *);
135 int afs_obsd_rmdir(void *);
136 int afs_obsd_symlink(void *);
137 int afs_obsd_readdir(void *);
138 int afs_obsd_readlink(void *);
139 int afs_obsd_inactive(void *);
140 int afs_obsd_reclaim(void *);
141 int afs_obsd_lock(void *);
142 int afs_obsd_unlock(void *);
143 int afs_obsd_bmap(void *);
144 int afs_obsd_strategy(void *);
145 int afs_obsd_print(void *);
146 int afs_obsd_islocked(void *);
147 int afs_obsd_pathconf(void *);
148 int afs_obsd_advlock(void *);
150 #define afs_obsd_opnotsupp \
151 ((int (*) __P((void *)))eopnotsupp)
152 #define afs_obsd_reallocblks afs_obsd_opnotsupp
154 /* Global vfs data structures for AFS. */
155 int (**afs_vnodeop_p) __P((void *));
156 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
157 #ifdef AFS_OBSD44_ENV /* feel free to zero in on this */
158 {&vop_default_desc, eopnotsupp},
160 {&vop_default_desc, vn_default_error},
162 {&vop_lookup_desc, afs_obsd_lookup}, /* lookup */
163 {&vop_create_desc, afs_obsd_create}, /* create */
164 {&vop_mknod_desc, afs_obsd_mknod}, /* mknod */
165 {&vop_open_desc, afs_obsd_open}, /* open */
166 {&vop_close_desc, afs_obsd_close}, /* close */
167 {&vop_access_desc, afs_obsd_access}, /* access */
168 {&vop_getattr_desc, afs_obsd_getattr}, /* getattr */
169 {&vop_setattr_desc, afs_obsd_setattr}, /* setattr */
170 {&vop_read_desc, afs_obsd_read}, /* read */
171 {&vop_write_desc, afs_obsd_write}, /* write */
172 {&vop_ioctl_desc, afs_obsd_ioctl}, /* XXX ioctl */
173 #ifdef AFS_OBSD35_ENV
174 {&vop_poll_desc, afs_obsd_select}, /* select */
176 {&vop_select_desc, afs_obsd_select}, /* select */
178 {&vop_fsync_desc, afs_obsd_fsync}, /* fsync */
179 {&vop_remove_desc, afs_obsd_remove}, /* remove */
180 {&vop_link_desc, afs_obsd_link}, /* link */
181 {&vop_rename_desc, afs_obsd_rename}, /* rename */
182 {&vop_mkdir_desc, afs_obsd_mkdir}, /* mkdir */
183 {&vop_rmdir_desc, afs_obsd_rmdir}, /* rmdir */
184 {&vop_symlink_desc, afs_obsd_symlink}, /* symlink */
185 {&vop_readdir_desc, afs_obsd_readdir}, /* readdir */
186 {&vop_readlink_desc, afs_obsd_readlink}, /* readlink */
187 {&vop_abortop_desc, vop_generic_abortop}, /* abortop */
188 {&vop_inactive_desc, afs_obsd_inactive}, /* inactive */
189 {&vop_reclaim_desc, afs_obsd_reclaim}, /* reclaim */
190 {&vop_lock_desc, afs_obsd_lock}, /* lock */
191 {&vop_unlock_desc, afs_obsd_unlock}, /* unlock */
192 {&vop_bmap_desc, afs_obsd_bmap}, /* bmap */
193 {&vop_strategy_desc, afs_obsd_strategy}, /* strategy */
194 {&vop_print_desc, afs_obsd_print}, /* print */
195 {&vop_islocked_desc, afs_obsd_islocked}, /* islocked */
196 {&vop_pathconf_desc, afs_obsd_pathconf}, /* pathconf */
197 {&vop_advlock_desc, afs_obsd_advlock}, /* advlock */
198 {&vop_reallocblks_desc, afs_obsd_reallocblks}, /* reallocblks */
199 {&vop_bwrite_desc, vop_generic_bwrite},
200 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
202 struct vnodeopv_desc afs_vnodeop_opv_desc =
203 { &afs_vnodeop_p, afs_vnodeop_entries };
206 struct componentname *cnp = ap->a_cnp; \
208 BSD_KMALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
209 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
210 name[cnp->cn_namelen] = '\0'
212 #define DROPNAME() BSD_KFREE(name, M_TEMP)
214 #ifdef AFS_OBSD36_ENV
215 #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
217 #define DROPCNP(cnp) FREE((cnp)->cn_pnbuf, M_NAMEI)
223 afs_obsd_lookup(void *v)
225 struct vop_lookup_args /* {
226 * struct vnodeop_desc * a_desc;
227 * struct vnode *a_dvp;
228 * struct vnode **a_vpp;
229 * struct componentname *a_cnp;
233 struct vnode *vp, *dvp;
234 int flags = ap->a_cnp->cn_flags;
235 int lockparent; /* 1 => lockparent flag is set */
236 int wantparent; /* 1 => wantparent or lockparent flag */
239 lockparent = flags & LOCKPARENT;
240 wantparent = flags & (LOCKPARENT | WANTPARENT);
242 cnp->cn_flags &= ~PDIRUNLOCK;
245 if (ap->a_dvp->v_type != VDIR) {
251 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
252 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
253 name, dvp->v_usecount);
255 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
258 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
259 && (flags & ISLASTCN) && code == ENOENT)
261 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
262 cnp->cn_flags |= SAVENAME;
267 vp = AFSTOV(vcp); /* always get a node if no error */
270 * The parent directory comes in locked. We unlock it on return
271 * unless the caller wants it left locked.
272 * 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. */
284 cnp->cn_flags |= PDIRUNLOCK;
287 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
288 if (afs_debug & AFSDEB_VNLAYER)
289 printf("locked ret %p from lookup\n", vp);
293 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
294 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
295 cnp->cn_flags |= SAVENAME;
298 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
299 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
304 afs_obsd_create(void *v)
306 struct vop_create_args /* {
307 * struct vnode *a_dvp;
308 * struct vnode **a_vpp;
309 * struct componentname *a_cnp;
310 * struct vattr *a_vap;
314 struct vnode *dvp = ap->a_dvp;
317 if (afs_debug & AFSDEB_VNLAYER)
318 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
320 /* vnode layer handles excl/nonexcl */
324 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
328 VOP_ABORTOP(dvp, cnp);
335 *ap->a_vpp = AFSTOV(vcp);
336 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
340 if ((cnp->cn_flags & SAVESTART) == 0)
344 if (afs_debug & AFSDEB_VNLAYER)
345 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
350 afs_obsd_mknod(void *v)
352 struct vop_mknod_args /* {
353 * struct vnode *a_dvp;
354 * struct vnode **a_vpp;
355 * struct componentname *a_cnp;
356 * struct vattr *a_vap;
364 afs_obsd_open(void *v)
366 struct vop_open_args /* {
367 * struct vnode *a_vp;
369 * struct ucred *a_cred;
373 struct vcache *vc = VTOAFS(ap->a_vp);
376 code = afs_open(&vc, ap->a_mode, ap->a_cred);
378 if (AFSTOV(vc) != ap->a_vp)
379 panic("AFS open changed vnode!");
386 afs_obsd_close(void *v)
388 struct vop_close_args /* {
389 * struct vnode *a_vp;
391 * struct ucred *a_cred;
397 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
403 afs_obsd_access(void *v)
405 struct vop_access_args /* {
406 * struct vnode *a_vp;
408 * struct ucred *a_cred;
414 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
420 afs_obsd_getattr(void *v)
422 struct vop_getattr_args /* {
423 * struct vnode *a_vp;
424 * struct vattr *a_vap;
425 * struct ucred *a_cred;
431 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
437 afs_obsd_setattr(void *v)
439 struct vop_setattr_args /* {
440 * struct vnode *a_vp;
441 * struct vattr *a_vap;
442 * struct ucred *a_cred;
448 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
454 afs_obsd_read(void *v)
456 struct vop_read_args /* {
457 * struct vnode *a_vp;
460 * struct ucred *a_cred;
466 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
473 afs_obsd_write(void *v)
475 struct vop_write_args /* {
476 * struct vnode *a_vp;
479 * struct ucred *a_cred;
484 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
486 vnode_pager_uncache(ap->a_vp);
490 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
496 afs_obsd_ioctl(void *v)
498 struct vop_ioctl_args /* {
499 * struct vnode *a_vp;
503 * struct ucred *a_cred;
508 /* in case we ever get in here... */
510 AFS_STATCNT(afs_ioctl);
512 if (((ap->a_command >> 8) & 0xff) == 'V')
513 /* This is a VICEIOCTL call */
515 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
516 (struct afs_ioctl *)ap->a_data);
518 /* No-op call; just return. */
525 afs_obsd_select(void *v)
531 afs_obsd_fsync(void *v)
533 struct vop_fsync_args /* {
534 * struct vnode *a_vp;
535 * struct ucred *a_cred;
539 int wait = ap->a_waitfor == MNT_WAIT;
540 struct vnode *vp = ap->a_vp;
545 code = afs_fsync(VTOAFS(vp), ap->a_cred);
551 afs_obsd_remove(void *v)
553 struct vop_remove_args /* {
554 * struct vnode *a_dvp;
555 * struct vnode *a_vp;
556 * struct componentname *a_cnp;
559 struct vnode *vp = ap->a_vp;
560 struct vnode *dvp = ap->a_dvp;
564 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
577 afs_obsd_link(void *v)
579 struct vop_link_args /* {
580 * struct vnode *a_vp;
581 * struct vnode *a_tdvp;
582 * struct componentname *a_cnp;
585 struct vnode *dvp = ap->a_dvp;
586 struct vnode *vp = ap->a_vp;
589 if (dvp->v_mount != vp->v_mount) {
590 VOP_ABORTOP(vp, cnp);
594 if (vp->v_type == VDIR) {
595 VOP_ABORTOP(vp, cnp);
599 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
600 VOP_ABORTOP(dvp, cnp);
605 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
609 VOP_UNLOCK(vp, 0, curproc);
618 afs_obsd_rename(void *v)
620 struct vop_rename_args /* {
621 * struct vnode *a_fdvp;
622 * struct vnode *a_fvp;
623 * struct componentname *a_fcnp;
624 * struct vnode *a_tdvp;
625 * struct vnode *a_tvp;
626 * struct componentname *a_tcnp;
629 struct componentname *fcnp = ap->a_fcnp;
631 struct componentname *tcnp = ap->a_tcnp;
633 struct vnode *tvp = ap->a_tvp;
634 struct vnode *tdvp = ap->a_tdvp;
635 struct vnode *fvp = ap->a_fvp;
636 struct vnode *fdvp = ap->a_fdvp;
639 * Check for cross-device rename.
641 if ((fvp->v_mount != tdvp->v_mount)
642 || (tvp && (fvp->v_mount != tvp->v_mount))) {
645 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
652 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
658 * if fvp == tvp, we're just removing one name of a pair of
659 * directory entries for the same element. convert call into rename.
660 ( (pinched from NetBSD 1.0's ufs_rename())
663 if (fvp->v_type == VDIR) {
668 /* Release destination completely. */
669 VOP_ABORTOP(tdvp, tcnp);
676 fcnp->cn_flags &= ~MODMASK;
677 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
678 if ((fcnp->cn_flags & SAVESTART) == 0)
679 panic("afs_rename: lost from startdir");
680 fcnp->cn_nameiop = DELETE;
681 (void)relookup(fdvp, &fvp, fcnp);
682 return (VOP_REMOVE(fdvp, fvp, fcnp));
685 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
688 BSD_KMALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
689 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
690 fname[fcnp->cn_namelen] = '\0';
691 BSD_KMALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
692 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
693 tname[tcnp->cn_namelen] = '\0';
697 /* XXX use "from" or "to" creds? NFS uses "to" creds */
699 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
702 VOP_UNLOCK(fvp, 0, curproc);
703 BSD_KFREE(fname, M_TEMP);
704 BSD_KFREE(tname, M_TEMP);
706 goto abortit; /* XXX */
719 afs_obsd_mkdir(void *v)
721 struct vop_mkdir_args /* {
722 * struct vnode *a_dvp;
723 * struct vnode **a_vpp;
724 * struct componentname *a_cnp;
725 * struct vattr *a_vap;
727 struct vnode *dvp = ap->a_dvp;
728 struct vattr *vap = ap->a_vap;
734 if ((cnp->cn_flags & HASBUF) == 0)
735 panic("afs_obsd_mkdir: no name");
738 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
741 VOP_ABORTOP(dvp, cnp);
747 *ap->a_vpp = AFSTOV(vcp);
748 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
758 afs_obsd_rmdir(void *v)
760 struct vop_rmdir_args /* {
761 * struct vnode *a_dvp;
762 * struct vnode *a_vp;
763 * struct componentname *a_cnp;
766 struct vnode *vp = ap->a_vp;
767 struct vnode *dvp = ap->a_dvp;
779 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
788 afs_obsd_symlink(void *v)
790 struct vop_symlink_args /* {
791 * struct vnode *a_dvp;
792 * struct vnode **a_vpp;
793 * struct componentname *a_cnp;
794 * struct vattr *a_vap;
797 struct vnode *dvp = ap->a_dvp;
799 /* NFS ignores a_vpp; so do we. */
804 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
813 afs_obsd_readdir(void *v)
815 struct vop_readdir_args /* {
816 * struct vnode *a_vp;
818 * struct ucred *a_cred;
821 * u_long **a_cookies;
826 #ifdef AFS_HAVE_COOKIES
827 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
830 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
831 ap->a_ncookies, ap->a_cookies);
834 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
841 afs_obsd_readlink(void *v)
843 struct vop_readlink_args /* {
844 * struct vnode *a_vp;
846 * struct ucred *a_cred;
851 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
856 extern int prtactive;
859 afs_obsd_inactive(void *v)
861 struct vop_inactive_args /* {
862 * struct vnode *a_vp;
864 struct vnode *vp = ap->a_vp;
865 struct vcache *vc = VTOAFS(vp);
866 int haveGlock = ISAFS_GLOCK();
868 AFS_STATCNT(afs_inactive);
870 if (prtactive && vp->v_usecount != 0)
871 vprint("afs_obsd_inactive(): pushing active", vp);
875 afs_InactiveVCache(vc, 0); /* decrs ref counts */
879 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
884 afs_obsd_reclaim(void *v)
886 struct vop_reclaim_args /* {
887 * struct vnode *a_vp;
890 struct vnode *vp = ap->a_vp;
891 struct vcache *avc = VTOAFS(vp);
892 int haveGlock = ISAFS_GLOCK();
893 int haveVlock = CheckLock(&afs_xvcache);
896 printf("reclaim usecount %d\n", vp->v_usecount);
897 /* OK, there are no internal vrefCounts, so there shouldn't
898 * be any more refs here. */
899 vp->v_data = NULL; /* remove from vnode */
900 avc->v = NULL; /* also drop the ptr to vnode */
906 ObtainWriteLock(&afs_xvcache, 901);
907 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
908 code = afs_FlushVCache(avc, &slept);
910 ReleaseWriteLock(&afs_xvcache);
917 #ifdef AFS_OBSD42_ENV
918 #define VP_INTERLOCK NULL
920 #define VP_INTERLOCK (&vp->v_interlock)
924 afs_obsd_lock(void *v)
926 struct vop_lock_args /* {
927 * struct vnode *a_vp;
931 struct vnode *vp = ap->a_vp;
932 struct vcache *vc = VTOAFS(vp);
935 panic("afs_obsd_lock: null vcache");
936 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, VP_INTERLOCK, ap->a_p);
940 afs_obsd_unlock(void *v)
942 struct vop_unlock_args /* {
943 * struct vnode *a_vp;
947 struct vnode *vp = ap->a_vp;
948 struct vcache *vc = VTOAFS(vp);
951 panic("afs_obsd_unlock: null vcache");
952 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, VP_INTERLOCK, ap->a_p);
956 afs_obsd_bmap(void *v)
958 struct vop_bmap_args /* {
959 * struct vnode *a_vp;
961 * struct vnode **a_vpp;
965 struct vcache *vcp = VTOAFS(ap->a_vp);
967 AFS_STATCNT(afs_bmap);
969 *ap->a_bnp = ap->a_bn * btodb(8192);
971 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
976 afs_obsd_strategy(void *v)
978 struct vop_strategy_args /* {
981 struct buf *abp = ap->a_bp;
983 struct iovec tiovec[1];
984 struct vcache *tvc = VTOAFS(abp->b_vp);
985 struct ucred *credp = osi_curcred();
986 long len = abp->b_bcount;
989 AFS_STATCNT(afs_strategy);
991 tuio.afsio_iov = tiovec;
992 tuio.afsio_iovcnt = 1;
993 tuio.afsio_seg = AFS_UIOSYS;
994 tuio.afsio_resid = len;
995 tiovec[0].iov_base = abp->b_data;
996 tiovec[0].iov_len = len;
999 if ((abp->b_flags & B_READ) == B_READ) {
1000 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1001 if (code == 0 && tuio.afsio_resid > 0)
1002 bzero(abp->b_data + len - tuio.afsio_resid, tuio.afsio_resid);
1004 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1007 ReleaseWriteLock(&tvc->lock);
1008 AFS_RELE(AFSTOV(tvc));
1013 afs_obsd_print(void *v)
1015 struct vop_print_args /* {
1016 * struct vnode *a_vp;
1018 struct vnode *vp = ap->a_vp;
1019 struct vcache *vc = VTOAFS(ap->a_vp);
1021 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1022 (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
1023 (int)vc->f.fid.Fid.Unique);
1024 lockmgr_printinfo(&vc->rwlock);
1030 afs_obsd_islocked(void *v)
1032 struct vop_islocked_args /* {
1033 * struct vnode *a_vp;
1035 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1039 * Return POSIX pathconf information applicable to ufs filesystems.
1042 afs_obsd_pathconf(void *v)
1044 struct vop_pathconf_args /* {
1045 * struct vnode *a_vp;
1049 AFS_STATCNT(afs_cntl);
1050 switch (ap->a_name) {
1052 *ap->a_retval = LINK_MAX;
1055 *ap->a_retval = NAME_MAX;
1058 *ap->a_retval = PATH_MAX;
1060 case _PC_CHOWN_RESTRICTED:
1076 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1077 afs_ucred_t *acred, pid_t clid);
1080 * Advisory record locking support (fcntl() POSIX style)
1083 afs_obsd_advlock(void *v)
1085 struct vop_advlock_args /* {
1086 * struct vnode *a_vp;
1089 * struct flock *a_fl;
1096 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),