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 #ifdef AFS_OBSD44_ENV /* feel free to zero in on this */
164 {&vop_default_desc, eopnotsupp},
166 {&vop_default_desc, vn_default_error},
168 {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */
169 {&vop_create_desc, afs_nbsd_create}, /* create */
170 {&vop_mknod_desc, afs_nbsd_mknod}, /* mknod */
171 {&vop_open_desc, afs_nbsd_open}, /* open */
172 {&vop_close_desc, afs_nbsd_close}, /* close */
173 {&vop_access_desc, afs_nbsd_access}, /* access */
174 {&vop_getattr_desc, afs_nbsd_getattr}, /* getattr */
175 {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */
176 {&vop_read_desc, afs_nbsd_read}, /* read */
177 {&vop_write_desc, afs_nbsd_write}, /* write */
178 {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */
179 #ifdef AFS_OBSD35_ENV
180 {&vop_poll_desc, afs_nbsd_select}, /* select */
182 {&vop_select_desc, afs_nbsd_select}, /* select */
184 {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */
185 {&vop_remove_desc, afs_nbsd_remove}, /* remove */
186 {&vop_link_desc, afs_nbsd_link}, /* link */
187 {&vop_rename_desc, afs_nbsd_rename}, /* rename */
188 {&vop_mkdir_desc, afs_nbsd_mkdir}, /* mkdir */
189 {&vop_rmdir_desc, afs_nbsd_rmdir}, /* rmdir */
190 {&vop_symlink_desc, afs_nbsd_symlink}, /* symlink */
191 {&vop_readdir_desc, afs_nbsd_readdir}, /* readdir */
192 {&vop_readlink_desc, afs_nbsd_readlink}, /* readlink */
193 {&vop_abortop_desc, vop_generic_abortop}, /* abortop */
194 {&vop_inactive_desc, afs_nbsd_inactive}, /* inactive */
195 {&vop_reclaim_desc, afs_nbsd_reclaim}, /* reclaim */
196 {&vop_lock_desc, afs_nbsd_lock}, /* lock */
197 {&vop_unlock_desc, afs_nbsd_unlock}, /* unlock */
198 {&vop_bmap_desc, afs_nbsd_bmap}, /* bmap */
199 {&vop_strategy_desc, afs_nbsd_strategy}, /* strategy */
200 {&vop_print_desc, afs_nbsd_print}, /* print */
201 {&vop_islocked_desc, afs_nbsd_islocked}, /* islocked */
202 {&vop_pathconf_desc, afs_nbsd_pathconf}, /* pathconf */
203 {&vop_advlock_desc, afs_nbsd_advlock}, /* advlock */
204 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */
205 {&vop_bwrite_desc, vop_generic_bwrite},
206 {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
208 struct vnodeopv_desc afs_vnodeop_opv_desc =
209 { &afs_vnodeop_p, afs_vnodeop_entries };
212 struct componentname *cnp = ap->a_cnp; \
214 BSD_KMALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
215 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
216 name[cnp->cn_namelen] = '\0'
218 #define DROPNAME() BSD_KFREE(name, M_TEMP)
220 #ifdef AFS_OBSD36_ENV
221 #define DROPCNP(cnp) pool_put(&namei_pool, (cnp)->cn_pnbuf)
223 #define DROPCNP(cnp) FREE((cnp)->cn_pnbuf, M_NAMEI)
229 afs_nbsd_lookup(void *v)
231 struct vop_lookup_args /* {
232 * struct vnodeop_desc * a_desc;
233 * struct vnode *a_dvp;
234 * struct vnode **a_vpp;
235 * struct componentname *a_cnp;
239 struct vnode *vp, *dvp;
240 int flags = ap->a_cnp->cn_flags;
241 int lockparent; /* 1 => lockparent flag is set */
242 int wantparent; /* 1 => wantparent or lockparent flag */
245 lockparent = flags & LOCKPARENT;
246 wantparent = flags & (LOCKPARENT | WANTPARENT);
248 cnp->cn_flags &= ~PDIRUNLOCK;
251 if (ap->a_dvp->v_type != VDIR) {
257 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
258 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags,
259 name, dvp->v_usecount);
261 code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
264 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
265 && (flags & ISLASTCN) && code == ENOENT)
267 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
268 cnp->cn_flags |= SAVENAME;
273 vp = AFSTOV(vcp); /* always get a node if no error */
276 * The parent directory comes in locked. We unlock it on return
277 * unless the caller wants it left locked.
278 * we also always return the vnode locked.
282 /* they're the same; afs_lookup() already ref'ed the leaf.
283 * It came in locked, so we don't need to ref OR lock it */
284 if (afs_debug & AFSDEB_VNLAYER)
285 printf("ref'ed %p as .\n", dvp);
287 if (!lockparent || !(flags & ISLASTCN)) {
288 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
290 cnp->cn_flags |= PDIRUNLOCK;
293 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
294 if (afs_debug & AFSDEB_VNLAYER)
295 printf("locked ret %p from lookup\n", vp);
299 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
300 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
301 cnp->cn_flags |= SAVENAME;
304 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
305 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
310 afs_nbsd_create(void *v)
312 struct vop_create_args /* {
313 * struct vnode *a_dvp;
314 * struct vnode **a_vpp;
315 * struct componentname *a_cnp;
316 * struct vattr *a_vap;
320 struct vnode *dvp = ap->a_dvp;
323 if (afs_debug & AFSDEB_VNLAYER)
324 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
326 /* vnode layer handles excl/nonexcl */
330 afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
334 VOP_ABORTOP(dvp, cnp);
341 *ap->a_vpp = AFSTOV(vcp);
342 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
346 if ((cnp->cn_flags & SAVESTART) == 0)
350 if (afs_debug & AFSDEB_VNLAYER)
351 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
356 afs_nbsd_mknod(void *v)
358 struct vop_mknod_args /* {
359 * struct vnode *a_dvp;
360 * struct vnode **a_vpp;
361 * struct componentname *a_cnp;
362 * struct vattr *a_vap;
370 afs_nbsd_open(void *v)
372 struct vop_open_args /* {
373 * struct vnode *a_vp;
375 * struct ucred *a_cred;
379 struct vcache *vc = VTOAFS(ap->a_vp);
382 code = afs_open(&vc, ap->a_mode, ap->a_cred);
384 if (AFSTOV(vc) != ap->a_vp)
385 panic("AFS open changed vnode!");
392 afs_nbsd_close(void *v)
394 struct vop_close_args /* {
395 * struct vnode *a_vp;
397 * struct ucred *a_cred;
403 code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
409 afs_nbsd_access(void *v)
411 struct vop_access_args /* {
412 * struct vnode *a_vp;
414 * struct ucred *a_cred;
420 code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
426 afs_nbsd_getattr(void *v)
428 struct vop_getattr_args /* {
429 * struct vnode *a_vp;
430 * struct vattr *a_vap;
431 * struct ucred *a_cred;
437 code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
443 afs_nbsd_setattr(void *v)
445 struct vop_setattr_args /* {
446 * struct vnode *a_vp;
447 * struct vattr *a_vap;
448 * struct ucred *a_cred;
454 code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
460 afs_nbsd_read(void *v)
462 struct vop_read_args /* {
463 * struct vnode *a_vp;
466 * struct ucred *a_cred;
472 afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t) 0, NULL,
479 afs_nbsd_write(void *v)
481 struct vop_write_args /* {
482 * struct vnode *a_vp;
485 * struct ucred *a_cred;
490 (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
492 vnode_pager_uncache(ap->a_vp);
496 afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
502 afs_nbsd_ioctl(void *v)
504 struct vop_ioctl_args /* {
505 * struct vnode *a_vp;
509 * struct ucred *a_cred;
514 /* in case we ever get in here... */
516 AFS_STATCNT(afs_ioctl);
518 if (((ap->a_command >> 8) & 0xff) == 'V')
519 /* This is a VICEIOCTL call */
521 HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
522 (struct afs_ioctl *)ap->a_data);
524 /* No-op call; just return. */
531 afs_nbsd_select(void *v)
537 afs_nbsd_fsync(void *v)
539 struct vop_fsync_args /* {
540 * struct vnode *a_vp;
541 * struct ucred *a_cred;
545 int wait = ap->a_waitfor == MNT_WAIT;
546 struct vnode *vp = ap->a_vp;
551 code = afs_fsync(VTOAFS(vp), ap->a_cred);
557 afs_nbsd_remove(void *v)
559 struct vop_remove_args /* {
560 * struct vnode *a_dvp;
561 * struct vnode *a_vp;
562 * struct componentname *a_cnp;
565 struct vnode *vp = ap->a_vp;
566 struct vnode *dvp = ap->a_dvp;
570 code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
583 afs_nbsd_link(void *v)
585 struct vop_link_args /* {
586 * struct vnode *a_vp;
587 * struct vnode *a_tdvp;
588 * struct componentname *a_cnp;
591 struct vnode *dvp = ap->a_dvp;
592 struct vnode *vp = ap->a_vp;
595 if (dvp->v_mount != vp->v_mount) {
596 VOP_ABORTOP(vp, cnp);
600 if (vp->v_type == VDIR) {
601 VOP_ABORTOP(vp, cnp);
605 if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
606 VOP_ABORTOP(dvp, cnp);
611 code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
615 VOP_UNLOCK(vp, 0, curproc);
624 afs_nbsd_rename(void *v)
626 struct vop_rename_args /* {
627 * struct vnode *a_fdvp;
628 * struct vnode *a_fvp;
629 * struct componentname *a_fcnp;
630 * struct vnode *a_tdvp;
631 * struct vnode *a_tvp;
632 * struct componentname *a_tcnp;
635 struct componentname *fcnp = ap->a_fcnp;
637 struct componentname *tcnp = ap->a_tcnp;
639 struct vnode *tvp = ap->a_tvp;
640 struct vnode *tdvp = ap->a_tdvp;
641 struct vnode *fvp = ap->a_fvp;
642 struct vnode *fdvp = ap->a_fdvp;
645 * Check for cross-device rename.
647 if ((fvp->v_mount != tdvp->v_mount)
648 || (tvp && (fvp->v_mount != tvp->v_mount))) {
651 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
658 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
664 * if fvp == tvp, we're just removing one name of a pair of
665 * directory entries for the same element. convert call into rename.
666 ( (pinched from NetBSD 1.0's ufs_rename())
669 if (fvp->v_type == VDIR) {
674 /* Release destination completely. */
675 VOP_ABORTOP(tdvp, tcnp);
682 fcnp->cn_flags &= ~MODMASK;
683 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
684 if ((fcnp->cn_flags & SAVESTART) == 0)
685 panic("afs_rename: lost from startdir");
686 fcnp->cn_nameiop = DELETE;
687 (void)relookup(fdvp, &fvp, fcnp);
688 return (VOP_REMOVE(fdvp, fvp, fcnp));
691 if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
694 BSD_KMALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
695 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
696 fname[fcnp->cn_namelen] = '\0';
697 BSD_KMALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
698 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
699 tname[tcnp->cn_namelen] = '\0';
703 /* XXX use "from" or "to" creds? NFS uses "to" creds */
705 afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
708 VOP_UNLOCK(fvp, 0, curproc);
709 BSD_KFREE(fname, M_TEMP);
710 BSD_KFREE(tname, M_TEMP);
712 goto abortit; /* XXX */
725 afs_nbsd_mkdir(void *v)
727 struct vop_mkdir_args /* {
728 * struct vnode *a_dvp;
729 * struct vnode **a_vpp;
730 * struct componentname *a_cnp;
731 * struct vattr *a_vap;
733 struct vnode *dvp = ap->a_dvp;
734 struct vattr *vap = ap->a_vap;
740 if ((cnp->cn_flags & HASBUF) == 0)
741 panic("afs_nbsd_mkdir: no name");
744 code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
747 VOP_ABORTOP(dvp, cnp);
753 *ap->a_vpp = AFSTOV(vcp);
754 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
764 afs_nbsd_rmdir(void *v)
766 struct vop_rmdir_args /* {
767 * struct vnode *a_dvp;
768 * struct vnode *a_vp;
769 * struct componentname *a_cnp;
772 struct vnode *vp = ap->a_vp;
773 struct vnode *dvp = ap->a_dvp;
785 code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
794 afs_nbsd_symlink(void *v)
796 struct vop_symlink_args /* {
797 * struct vnode *a_dvp;
798 * struct vnode **a_vpp;
799 * struct componentname *a_cnp;
800 * struct vattr *a_vap;
803 struct vnode *dvp = ap->a_dvp;
805 /* NFS ignores a_vpp; so do we. */
810 afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
819 afs_nbsd_readdir(void *v)
821 struct vop_readdir_args /* {
822 * struct vnode *a_vp;
824 * struct ucred *a_cred;
827 * u_long **a_cookies;
832 #ifdef AFS_HAVE_COOKIES
833 printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
836 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag,
837 ap->a_ncookies, ap->a_cookies);
840 afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
847 afs_nbsd_readlink(void *v)
849 struct vop_readlink_args /* {
850 * struct vnode *a_vp;
852 * struct ucred *a_cred;
857 code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
862 extern int prtactive;
865 afs_nbsd_inactive(void *v)
867 struct vop_inactive_args /* {
868 * struct vnode *a_vp;
870 struct vnode *vp = ap->a_vp;
871 struct vcache *vc = VTOAFS(vp);
872 int haveGlock = ISAFS_GLOCK();
874 AFS_STATCNT(afs_inactive);
876 if (prtactive && vp->v_usecount != 0)
877 vprint("afs_nbsd_inactive(): pushing active", vp);
881 afs_InactiveVCache(vc, 0); /* decrs ref counts */
885 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
890 afs_nbsd_reclaim(void *v)
892 struct vop_reclaim_args /* {
893 * struct vnode *a_vp;
896 struct vnode *vp = ap->a_vp;
897 struct vcache *avc = VTOAFS(vp);
898 int haveGlock = ISAFS_GLOCK();
899 int haveVlock = CheckLock(&afs_xvcache);
902 printf("reclaim usecount %d\n", vp->v_usecount);
903 /* OK, there are no internal vrefCounts, so there shouldn't
904 * be any more refs here. */
905 vp->v_data = NULL; /* remove from vnode */
906 avc->v = NULL; /* also drop the ptr to vnode */
912 ObtainWriteLock(&afs_xvcache, 901);
913 #ifndef AFS_DISCON_ENV
914 code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
916 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
917 code = afs_FlushVS(avc);
920 ReleaseWriteLock(&afs_xvcache);
927 #ifdef AFS_OBSD42_ENV
928 #define VP_INTERLOCK NULL
930 #define VP_INTERLOCK (&vp->v_interlock)
934 afs_nbsd_lock(void *v)
936 struct vop_lock_args /* {
937 * struct vnode *a_vp;
941 struct vnode *vp = ap->a_vp;
942 struct vcache *vc = VTOAFS(vp);
945 panic("afs_nbsd_lock: null vcache");
946 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, VP_INTERLOCK, ap->a_p);
950 afs_nbsd_unlock(void *v)
952 struct vop_unlock_args /* {
953 * struct vnode *a_vp;
957 struct vnode *vp = ap->a_vp;
958 struct vcache *vc = VTOAFS(vp);
961 panic("afs_nbsd_unlock: null vcache");
962 return afs_osi_lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, VP_INTERLOCK, ap->a_p);
966 afs_nbsd_bmap(void *v)
968 struct vop_bmap_args /* {
969 * struct vnode *a_vp;
971 * struct vnode **a_vpp;
975 struct vcache *vcp = VTOAFS(ap->a_vp);
977 AFS_STATCNT(afs_bmap);
979 *ap->a_bnp = ap->a_bn * btodb(8192);
981 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
986 afs_nbsd_strategy(void *v)
988 struct vop_strategy_args /* {
991 struct buf *abp = ap->a_bp;
993 struct iovec tiovec[1];
994 struct vcache *tvc = VTOAFS(abp->b_vp);
995 struct ucred *credp = osi_curcred();
996 long len = abp->b_bcount;
999 AFS_STATCNT(afs_strategy);
1001 tuio.afsio_iov = tiovec;
1002 tuio.afsio_iovcnt = 1;
1003 tuio.afsio_seg = AFS_UIOSYS;
1004 tuio.afsio_resid = len;
1005 tiovec[0].iov_base = abp->b_data;
1006 tiovec[0].iov_len = len;
1009 if ((abp->b_flags & B_READ) == B_READ) {
1010 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
1011 if (code == 0 && tuio.afsio_resid > 0)
1012 bzero(abp->b_data + len - tuio.afsio_resid, tuio.afsio_resid);
1014 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
1017 ReleaseWriteLock(&tvc->lock);
1018 AFS_RELE(AFSTOV(tvc));
1023 afs_nbsd_print(void *v)
1025 struct vop_print_args /* {
1026 * struct vnode *a_vp;
1028 struct vnode *vp = ap->a_vp;
1029 struct vcache *vc = VTOAFS(ap->a_vp);
1031 printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1032 (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
1033 (int)vc->f.fid.Fid.Unique);
1034 lockmgr_printinfo(&vc->rwlock);
1040 afs_nbsd_islocked(void *v)
1042 struct vop_islocked_args /* {
1043 * struct vnode *a_vp;
1045 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
1049 * Return POSIX pathconf information applicable to ufs filesystems.
1052 afs_nbsd_pathconf(void *v)
1054 struct vop_pathconf_args /* {
1055 * struct vnode *a_vp;
1059 AFS_STATCNT(afs_cntl);
1060 switch (ap->a_name) {
1062 *ap->a_retval = LINK_MAX;
1065 *ap->a_retval = NAME_MAX;
1068 *ap->a_retval = PATH_MAX;
1070 case _PC_CHOWN_RESTRICTED:
1086 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1087 struct AFS_UCRED *acred, pid_t clid);
1090 * Advisory record locking support (fcntl() POSIX style)
1093 afs_nbsd_advlock(void *v)
1095 struct vop_advlock_args /* {
1096 * struct vnode *a_vp;
1099 * struct flock *a_fl;
1106 afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),