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"
104 #include "afs/sysincludes.h" /* Standard vendor system headers */
105 #include "afs/afsincludes.h" /* Afs-based standard headers */
106 #include "afs/afs_stats.h" /* statistics */
108 #include <sys/malloc.h>
109 #include <sys/namei.h>
110 #ifdef AFS_OBSD36_ENV
111 #include <sys/pool.h>
114 #include "afs/afs_cbqueue.h"
115 #include "afs/nfsclient.h"
116 #include "afs/afs_osidnlc.h"
118 #ifdef AFS_DISCON_ENV
119 extern int afs_FlushVS(struct vcache *tvc);
122 #define M_AFSNODE (M_TEMP-1) /* XXX */
124 int afs_nbsd_lookup(void *);
125 int afs_nbsd_create(void *);
126 int afs_nbsd_mknod(void *);
127 int afs_nbsd_open(void *);
128 int afs_nbsd_close(void *);
129 int afs_nbsd_access(void *);
130 int afs_nbsd_getattr(void *);
131 int afs_nbsd_setattr(void *);
132 int afs_nbsd_read(void *);
133 int afs_nbsd_write(void *);
134 int afs_nbsd_ioctl(void *);
135 int afs_nbsd_select(void *);
136 int afs_nbsd_fsync(void *);
137 int afs_nbsd_remove(void *);
138 int afs_nbsd_link(void *);
139 int afs_nbsd_rename(void *);
140 int afs_nbsd_mkdir(void *);
141 int afs_nbsd_rmdir(void *);
142 int afs_nbsd_symlink(void *);
143 int afs_nbsd_readdir(void *);
144 int afs_nbsd_readlink(void *);
145 int afs_nbsd_inactive(void *);
146 int afs_nbsd_reclaim(void *);
147 int afs_nbsd_lock(void *);
148 int afs_nbsd_unlock(void *);
149 int afs_nbsd_bmap(void *);
150 int afs_nbsd_strategy(void *);
151 int afs_nbsd_print(void *);
152 int afs_nbsd_islocked(void *);
153 int afs_nbsd_pathconf(void *);
154 int afs_nbsd_advlock(void *);
156 #define afs_nbsd_opnotsupp \
157 ((int (*) __P((void *)))eopnotsupp)
158 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
160 /* Global vfs data structures for AFS. */
161 int (**afs_vnodeop_p) __P((void *));
162 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
163 {&vop_default_desc, vn_default_error},
164 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
165 {&vop_create_desc, afs_nbsd_create}, /* create */
166 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
167 {&vop_open_desc, afs_nbsd_open}, /* open */
168 {&vop_close_desc, afs_nbsd_close}, /* close */
169 {&vop_access_desc, afs_nbsd_access}, /* access */
170 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
171 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
172 {&vop_read_desc, afs_nbsd_read}, /* read */
173 {&vop_write_desc, afs_nbsd_write}, /* write */
174 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
175 #ifdef AFS_OBSD35_ENV
176 {&vop_poll_desc, afs_nbsd_select}, /* select */
178 {&vop_select_desc, afs_nbsd_select}, /* select */
180 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
181 {&vop_remove_desc, afs_nbsd_remove}, /* remove */
182 {&vop_link_desc, afs_nbsd_link}, /* link */
183 {&vop_rename_desc, afs_nbsd_rename}, /* rename */
184 {&vop_mkdir_desc, afs_nbsd_mkdir}, /* mkdir */
185 {&vop_rmdir_desc, afs_nbsd_rmdir}, /* rmdir */
186 {&vop_symlink_desc, afs_nbsd_symlink}, /* symlink */
187 {&vop_readdir_desc, afs_nbsd_readdir}, /* readdir */
188 {&vop_readlink_desc, afs_nbsd_readlink}, /* readlink */
189 {&vop_abortop_desc, vop_generic_abortop}, /* abortop */
190 {&vop_inactive_desc, afs_nbsd_inactive}, /* inactive */
191 {&vop_reclaim_desc, afs_nbsd_reclaim}, /* reclaim */
192 {&vop_lock_desc, afs_nbsd_lock}, /* lock */
193 {&vop_unlock_desc, afs_nbsd_unlock}, /* unlock */
194 {&vop_bmap_desc, afs_nbsd_bmap}, /* bmap */
195 {&vop_strategy_desc, afs_nbsd_strategy}, /* strategy */
196 {&vop_print_desc, afs_nbsd_print}, /* print */
197 {&vop_islocked_desc, afs_nbsd_islocked}, /* islocked */
198 {&vop_pathconf_desc, afs_nbsd_pathconf}, /* pathconf */
199 {&vop_advlock_desc, afs_nbsd_advlock}, /* advlock */
200 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
201 {&vop_bwrite_desc, vop_generic_bwrite},
202 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
204 struct vnodeopv_desc afs_vnodeop_opv_desc =
205 { &afs_vnodeop_p, afs_vnodeop_entries };
208 struct componentname *cnp = ap->a_cnp; \
210 MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
211 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
212 name[cnp->cn_namelen] = '\0'
214 #define DROPNAME() FREE(name, M_TEMP)
216 #ifdef AFS_OBSD36_ENV
217 #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
219 #define DROPCNP(cnp) FREE((cnp)->cn_pnbuf, M_NAMEI)
225 afs_nbsd_lookup(void *v)
227 struct vop_lookup_args /* {
228 * struct vnodeop_desc * a_desc;
229 * struct vnode *a_dvp;
230 * struct vnode **a_vpp;
231 * struct componentname *a_cnp;
235 struct vnode *vp, *dvp;
236 int flags = ap->a_cnp->cn_flags;
237 int lockparent; /* 1 => lockparent flag is set */
238 int wantparent; /* 1 => wantparent or lockparent flag */
241 lockparent = flags & LOCKPARENT;
242 wantparent = flags & (LOCKPARENT | WANTPARENT);
244 cnp->cn_flags &= ~PDIRUNLOCK;
247 if (ap->a_dvp->v_type != VDIR) {
253 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
254 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
255 name, dvp->v_usecount);
257 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
260 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
261 && (flags & ISLASTCN) && code == 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 */
272 * The parent directory comes in locked. We unlock it on return
273 * unless the caller wants it left locked.
274 * 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. */
286 cnp->cn_flags |= PDIRUNLOCK;
289 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
290 if (afs_debug & AFSDEB_VNLAYER)
291 printf("locked ret %p from lookup\n", vp);
295 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
296 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
297 cnp->cn_flags |= SAVENAME;
300 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
301 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
306 afs_nbsd_create(void *v)
308 struct vop_create_args /* {
309 * struct vnode *a_dvp;
310 * struct vnode **a_vpp;
311 * struct componentname *a_cnp;
312 * struct vattr *a_vap;
316 struct vnode *dvp = ap->a_dvp;
319 if (afs_debug & AFSDEB_VNLAYER)
320 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
322 /* vnode layer handles excl/nonexcl */
326 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
330 VOP_ABORTOP(dvp, cnp);
337 *ap->a_vpp = AFSTOV(vcp);
338 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
342 if ((cnp->cn_flags & SAVESTART) == 0)
346 if (afs_debug & AFSDEB_VNLAYER)
347 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
352 afs_nbsd_mknod(void *v)
354 struct vop_mknod_args /* {
355 * struct vnode *a_dvp;
356 * struct vnode **a_vpp;
357 * struct componentname *a_cnp;
358 * struct vattr *a_vap;
366 afs_nbsd_open(void *v)
368 struct vop_open_args /* {
369 * struct vnode *a_vp;
371 * struct ucred *a_cred;
375 struct vcache *vc = VTOAFS(ap->a_vp);
378 code = afs_open(&vc, ap->a_mode, ap->a_cred);
380 if (AFSTOV(vc) != ap->a_vp)
381 panic("AFS open changed vnode!");
388 afs_nbsd_close(void *v)
390 struct vop_close_args /* {
391 * struct vnode *a_vp;
393 * struct ucred *a_cred;
399 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
405 afs_nbsd_access(void *v)
407 struct vop_access_args /* {
408 * struct vnode *a_vp;
410 * struct ucred *a_cred;
416 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
422 afs_nbsd_getattr(void *v)
424 struct vop_getattr_args /* {
425 * struct vnode *a_vp;
426 * struct vattr *a_vap;
427 * struct ucred *a_cred;
433 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
439 afs_nbsd_setattr(void *v)
441 struct vop_setattr_args /* {
442 * struct vnode *a_vp;
443 * struct vattr *a_vap;
444 * struct ucred *a_cred;
450 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
456 afs_nbsd_read(void *v)
458 struct vop_read_args /* {
459 * struct vnode *a_vp;
462 * struct ucred *a_cred;
468 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
475 afs_nbsd_write(void *v)
477 struct vop_write_args /* {
478 * struct vnode *a_vp;
481 * struct ucred *a_cred;
486 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
488 vnode_pager_uncache(ap->a_vp);
492 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
498 afs_nbsd_ioctl(void *v)
500 struct vop_ioctl_args /* {
501 * struct vnode *a_vp;
505 * struct ucred *a_cred;
510 /* in case we ever get in here... */
512 AFS_STATCNT(afs_ioctl);
514 if (((ap->a_command >> 8) & 0xff) == 'V')
515 /* This is a VICEIOCTL call */
517 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
518 (struct afs_ioctl *)ap->a_data);
520 /* No-op call; just return. */
527 afs_nbsd_select(void *v)
533 afs_nbsd_fsync(void *v)
535 struct vop_fsync_args /* {
536 * struct vnode *a_vp;
537 * struct ucred *a_cred;
541 int wait = ap->a_waitfor == MNT_WAIT;
542 struct vnode *vp = ap->a_vp;
547 code = afs_fsync(VTOAFS(vp), ap->a_cred);
553 afs_nbsd_remove(void *v)
555 struct vop_remove_args /* {
556 * struct vnode *a_dvp;
557 * struct vnode *a_vp;
558 * struct componentname *a_cnp;
561 struct vnode *vp = ap->a_vp;
562 struct vnode *dvp = ap->a_dvp;
566 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
579 afs_nbsd_link(void *v)
581 struct vop_link_args /* {
582 * struct vnode *a_vp;
583 * struct vnode *a_tdvp;
584 * struct componentname *a_cnp;
587 struct vnode *dvp = ap->a_dvp;
588 struct vnode *vp = ap->a_vp;
591 if (dvp->v_mount != vp->v_mount) {
592 VOP_ABORTOP(vp, cnp);
596 if (vp->v_type == VDIR) {
597 VOP_ABORTOP(vp, cnp);
601 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
602 VOP_ABORTOP(dvp, cnp);
607 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
611 VOP_UNLOCK(vp, 0, curproc);
620 afs_nbsd_rename(void *v)
622 struct vop_rename_args /* {
623 * struct vnode *a_fdvp;
624 * struct vnode *a_fvp;
625 * struct componentname *a_fcnp;
626 * struct vnode *a_tdvp;
627 * struct vnode *a_tvp;
628 * struct componentname *a_tcnp;
631 struct componentname *fcnp = ap->a_fcnp;
633 struct componentname *tcnp = ap->a_tcnp;
635 struct vnode *tvp = ap->a_tvp;
636 struct vnode *tdvp = ap->a_tdvp;
637 struct vnode *fvp = ap->a_fvp;
638 struct vnode *fdvp = ap->a_fdvp;
641 * Check for cross-device rename.
643 if ((fvp->v_mount != tdvp->v_mount)
644 || (tvp && (fvp->v_mount != tvp->v_mount))) {
647 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
654 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
660 * if fvp == tvp, we're just removing one name of a pair of
661 * directory entries for the same element. convert call into rename.
662 ( (pinched from NetBSD 1.0's ufs_rename())
665 if (fvp->v_type == VDIR) {
670 /* Release destination completely. */
671 VOP_ABORTOP(tdvp, tcnp);
678 fcnp->cn_flags &= ~MODMASK;
679 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
680 if ((fcnp->cn_flags & SAVESTART) == 0)
681 panic("afs_rename: lost from startdir");
682 fcnp->cn_nameiop = DELETE;
683 (void)relookup(fdvp, &fvp, fcnp);
684 return (VOP_REMOVE(fdvp, fvp, fcnp));
687 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
690 MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
691 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
692 fname[fcnp->cn_namelen] = '\0';
693 MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
694 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
695 tname[tcnp->cn_namelen] = '\0';
699 /* XXX use "from" or "to" creds? NFS uses "to" creds */
701 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
704 VOP_UNLOCK(fvp, 0, curproc);
708 goto abortit; /* XXX */
721 afs_nbsd_mkdir(void *v)
723 struct vop_mkdir_args /* {
724 * struct vnode *a_dvp;
725 * struct vnode **a_vpp;
726 * struct componentname *a_cnp;
727 * struct vattr *a_vap;
729 struct vnode *dvp = ap->a_dvp;
730 struct vattr *vap = ap->a_vap;
736 if ((cnp->cn_flags & HASBUF) == 0)
737 panic("afs_nbsd_mkdir: no name");
740 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
743 VOP_ABORTOP(dvp, cnp);
749 *ap->a_vpp = AFSTOV(vcp);
750 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
760 afs_nbsd_rmdir(void *v)
762 struct vop_rmdir_args /* {
763 * struct vnode *a_dvp;
764 * struct vnode *a_vp;
765 * struct componentname *a_cnp;
768 struct vnode *vp = ap->a_vp;
769 struct vnode *dvp = ap->a_dvp;
781 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
790 afs_nbsd_symlink(void *v)
792 struct vop_symlink_args /* {
793 * struct vnode *a_dvp;
794 * struct vnode **a_vpp;
795 * struct componentname *a_cnp;
796 * struct vattr *a_vap;
799 struct vnode *dvp = ap->a_dvp;
801 /* NFS ignores a_vpp; so do we. */
806 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
815 afs_nbsd_readdir(void *v)
817 struct vop_readdir_args /* {
818 * struct vnode *a_vp;
820 * struct ucred *a_cred;
823 * u_long **a_cookies;
828 #ifdef AFS_HAVE_COOKIES
829 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
832 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
833 ap->a_ncookies, ap->a_cookies);
836 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
843 afs_nbsd_readlink(void *v)
845 struct vop_readlink_args /* {
846 * struct vnode *a_vp;
848 * struct ucred *a_cred;
853 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
858 extern int prtactive;
861 afs_nbsd_inactive(void *v)
863 struct vop_inactive_args /* {
864 * struct vnode *a_vp;
866 struct vnode *vp = ap->a_vp;
867 struct vcache *vc = VTOAFS(vp);
868 int haveGlock = ISAFS_GLOCK();
870 AFS_STATCNT(afs_inactive);
872 if (prtactive && vp->v_usecount != 0)
873 vprint("afs_nbsd_inactive(): pushing active", vp);
877 afs_InactiveVCache(vc, 0); /* decrs ref counts */
881 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
886 afs_nbsd_reclaim(void *v)
888 struct vop_reclaim_args /* {
889 * struct vnode *a_vp;
892 struct vnode *vp = ap->a_vp;
893 struct vcache *avc = VTOAFS(vp);
894 int haveGlock = ISAFS_GLOCK();
895 int haveVlock = CheckLock(&afs_xvcache);
898 printf("reclaim usecount %d\n", vp->v_usecount);
899 /* OK, there are no internal vrefCounts, so there shouldn't
900 * be any more refs here. */
901 vp->v_data = NULL; /* remove from vnode */
902 avc->v = NULL; /* also drop the ptr to vnode */
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);
923 #ifdef AFS_OBSD42_ENV
924 #define VP_INTERLOCK NULL
926 #define VP_INTERLOCK (&vp->v_interlock)
930 afs_nbsd_lock(void *v)
932 struct vop_lock_args /* {
933 * struct vnode *a_vp;
937 struct vnode *vp = ap->a_vp;
938 struct vcache *vc = VTOAFS(vp);
941 panic("afs_nbsd_lock: null vcache");
942 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, VP_INTERLOCK, ap->a_p);
946 afs_nbsd_unlock(void *v)
948 struct vop_unlock_args /* {
949 * struct vnode *a_vp;
953 struct vnode *vp = ap->a_vp;
954 struct vcache *vc = VTOAFS(vp);
957 panic("afs_nbsd_unlock: null vcache");
958 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, VP_INTERLOCK, ap->a_p);
962 afs_nbsd_bmap(void *v)
964 struct vop_bmap_args /* {
965 * struct vnode *a_vp;
967 * struct vnode **a_vpp;
971 struct vcache *vcp = VTOAFS(ap->a_vp);
973 AFS_STATCNT(afs_bmap);
975 *ap->a_bnp = ap->a_bn * btodb(8192);
977 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
982 afs_nbsd_strategy(void *v)
984 struct vop_strategy_args /* {
987 struct buf *abp = ap->a_bp;
989 struct iovec tiovec[1];
990 struct vcache *tvc = VTOAFS(abp->b_vp);
991 struct ucred *credp = osi_curcred();
992 long len = abp->b_bcount;
995 AFS_STATCNT(afs_strategy);
997 tuio.afsio_iov = tiovec;
998 tuio.afsio_iovcnt = 1;
999 tuio.afsio_seg = AFS_UIOSYS;
1000 tuio.afsio_resid = len;
1001 tiovec[0].iov_base = abp->b_data;
1002 tiovec[0].iov_len = len;
1005 if ((abp->b_flags & B_READ) == B_READ) {
1006 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1007 if (code == 0 && tuio.afsio_resid > 0)
1008 bzero(abp->b_data + len - tuio.afsio_resid, tuio.afsio_resid);
1010 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1013 ReleaseWriteLock(&tvc->lock);
1014 AFS_RELE(AFSTOV(tvc));
1019 afs_nbsd_print(void *v)
1021 struct vop_print_args /* {
1022 * struct vnode *a_vp;
1024 struct vnode *vp = ap->a_vp;
1025 struct vcache *vc = VTOAFS(ap->a_vp);
1027 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
1028 (int)vc->fid.Fid.Volume, (int)vc->fid.Fid.Vnode,
1029 (int)vc->fid.Fid.Unique);
1030 lockmgr_printinfo(&vc->rwlock);
1036 afs_nbsd_islocked(void *v)
1038 struct vop_islocked_args /* {
1039 * struct vnode *a_vp;
1041 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1045 * Return POSIX pathconf information applicable to ufs filesystems.
1048 afs_nbsd_pathconf(void *v)
1050 struct vop_pathconf_args /* {
1051 * struct vnode *a_vp;
1055 AFS_STATCNT(afs_cntl);
1056 switch (ap->a_name) {
1058 *ap->a_retval = LINK_MAX;
1061 *ap->a_retval = NAME_MAX;
1064 *ap->a_retval = PATH_MAX;
1066 case _PC_CHOWN_RESTRICTED:
1082 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1083 struct AFS_UCRED *acred, pid_t clid);
1086 * Advisory record locking support (fcntl() POSIX style)
1089 afs_nbsd_advlock(void *v)
1091 struct vop_advlock_args /* {
1092 * struct vnode *a_vp;
1095 * struct flock *a_fl;
1102 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),