Port cache manager to NetBSD-5 and NetBSD-current
[openafs.git] / src / afs / NBSD / osi_vnodeops.c
1 /*
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>
5  *
6  * $Id: osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $
7  */
8
9 /*
10 copyright 2002
11 the regents of the university of michigan
12 all rights reserved
13
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
23 also be included.
24
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
36 such damages.
37 */
38
39 /*
40 Copyright 1995 Massachusetts Institute of Technology.  All Rights
41 Reserved.
42
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
52 NONINFRINGEMENT.
53 */
54
55 /*
56  * A bunch of code cribbed from NetBSD ufs_vnops.c, ffs_vnops.c, and
57  * nfs_vnops.c which carry this copyright:
58  */
59 /*
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.
67  *
68  * Redistribution and use in source and binary forms, with or without
69  * modification, are permitted provided that the following conditions
70  * are met:
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.
83  *
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
94  * SUCH DAMAGE.
95  *
96  */
97
98 #include <afsconfig.h>
99 #include "afs/param.h"
100
101 #include "afs/sysincludes.h"    /* Standard vendor system headers */
102 #include "afs/afsincludes.h"    /* Afs-based standard headers */
103 #include "afs/afs_stats.h"      /* statistics */
104
105 #include <sys/malloc.h>
106 #include <sys/namei.h>
107 #include <sys/pool.h>
108 #include <miscfs/genfs/genfs.h>
109
110 #include "afs/afs_cbqueue.h"
111 #include "afs/nfsclient.h"
112 #include "afs/afs_osidnlc.h"
113
114 int afs_nbsd_lookup(void *);
115 int afs_nbsd_create(void *);
116 int afs_nbsd_mknod(void *);
117 int afs_nbsd_open(void *);
118 int afs_nbsd_close(void *);
119 int afs_nbsd_access(void *);
120 int afs_nbsd_getattr(void *);
121 int afs_nbsd_setattr(void *);
122 int afs_nbsd_read(void *);
123 int afs_nbsd_write(void *);
124 int afs_nbsd_ioctl(void *);
125 int afs_nbsd_fsync(void *);
126 int afs_nbsd_remove(void *);
127 int afs_nbsd_link(void *);
128 int afs_nbsd_rename(void *);
129 int afs_nbsd_mkdir(void *);
130 int afs_nbsd_rmdir(void *);
131 int afs_nbsd_symlink(void *);
132 int afs_nbsd_readdir(void *);
133 int afs_nbsd_readlink(void *);
134 int afs_nbsd_inactive(void *);
135 int afs_nbsd_reclaim(void *);
136 int afs_nbsd_lock(void *);
137 int afs_nbsd_unlock(void *);
138 int afs_nbsd_bmap(void *);
139 int afs_nbsd_strategy(void *);
140 int afs_nbsd_print(void *);
141 int afs_nbsd_islocked(void *);
142 int afs_nbsd_pathconf(void *);
143 int afs_nbsd_advlock(void *);
144
145 int afs_debug;
146
147 /*
148  * Skip:
149  *   vop_*xtattr
150  *
151  */
152
153 /* Global vfs data structures for AFS. */
154 int (**afs_vnodeop_p) __P((void *));
155 const struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
156     {&vop_default_desc, vn_default_error},
157     {&vop_lookup_desc, afs_nbsd_lookup},        /* lookup */
158     {&vop_create_desc, afs_nbsd_create},        /* create */
159     {&vop_mknod_desc, afs_nbsd_mknod},          /* mknod */
160     {&vop_open_desc, afs_nbsd_open},            /* open */
161     {&vop_close_desc, afs_nbsd_close},          /* close */
162     {&vop_access_desc, afs_nbsd_access},        /* access */
163     {&vop_getattr_desc, afs_nbsd_getattr},      /* getattr */
164     {&vop_setattr_desc, afs_nbsd_setattr},      /* setattr */
165     {&vop_read_desc, afs_nbsd_read},            /* read */
166     {&vop_write_desc, afs_nbsd_write},          /* write */
167 #if NOTYET
168     {&vop_ioctl_desc, afs_nbsd_ioctl},          /* XXX ioctl */
169 #else
170     {&vop_ioctl_desc, genfs_enoioctl},          /* ioctl */
171 #endif
172     {&vop_fcntl_desc, genfs_fcntl},             /* fcntl */
173     {&vop_poll_desc, genfs_poll},               /* poll */
174     {&vop_kqfilter_desc, genfs_kqfilter },      /* kqfilter */
175     {&vop_mmap_desc, genfs_mmap},               /* mmap */
176     {&vop_fsync_desc, afs_nbsd_fsync},          /* fsync */
177     {&vop_seek_desc, genfs_seek},               /* seek */
178     {&vop_remove_desc, afs_nbsd_remove},        /* remove */
179     {&vop_link_desc, afs_nbsd_link},            /* link */
180     {&vop_rename_desc, afs_nbsd_rename},        /* rename */
181     {&vop_mkdir_desc, afs_nbsd_mkdir},          /* mkdir */
182     {&vop_rmdir_desc, afs_nbsd_rmdir},          /* rmdir */
183     {&vop_symlink_desc, afs_nbsd_symlink},      /* symlink */
184     {&vop_readdir_desc, afs_nbsd_readdir},      /* readdir */
185     {&vop_readlink_desc, afs_nbsd_readlink},    /* readlink */
186     {&vop_abortop_desc, genfs_abortop},         /* abortop */
187     {&vop_inactive_desc, afs_nbsd_inactive},    /* inactive */
188     {&vop_reclaim_desc, afs_nbsd_reclaim},      /* reclaim */
189     {&vop_lock_desc, afs_nbsd_lock},            /* lock */
190     {&vop_unlock_desc, afs_nbsd_unlock},        /* unlock */
191     {&vop_bmap_desc, afs_nbsd_bmap},            /* bmap */
192     {&vop_strategy_desc, afs_nbsd_strategy},    /* strategy */
193     {&vop_print_desc, afs_nbsd_print},          /* print */
194     {&vop_islocked_desc, afs_nbsd_islocked},    /* islocked */
195     {&vop_pathconf_desc, afs_nbsd_pathconf},    /* pathconf */
196     {&vop_advlock_desc, afs_nbsd_advlock},      /* advlock */
197 #if 0
198     {&vop_reallocblks_desc, afs_nbsd_reallocblks},      /* reallocblks */
199 #endif
200     {&vop_bwrite_desc, vn_bwrite},              /* bwrite */
201     {&vop_getpages_desc, genfs_getpages},       /* getpages */
202     {&vop_putpages_desc, genfs_putpages},       /* putpages */
203     { NULL, NULL}
204 };
205 const struct vnodeopv_desc afs_vnodeop_opv_desc =
206     { &afs_vnodeop_p, afs_vnodeop_entries };
207
208 static void
209 afs_nbsd_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
210 {
211
212         *eobp = MAX(size, vp->v_size);
213 }
214
215 static int
216 afs_nbsd_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags,
217     kauth_cred_t cred)
218 {
219
220     return (0);
221 }
222
223 static const struct genfs_ops afs_genfsops = {
224         .gop_size  = afs_nbsd_gop_size,
225         .gop_alloc = afs_nbsd_gop_alloc,
226         .gop_write = genfs_gop_write,
227 };
228
229 extern void cpu_Debugger(void);
230
231 static char *
232 cnstrdup(const struct componentname *cnp)
233 {
234         char *string;
235
236         string = PNBUF_GET();
237         memcpy(string, cnp->cn_nameptr, cnp->cn_namelen);
238         string[cnp->cn_namelen] = '\0';
239
240         return string;
241 }
242
243 static void
244 cnstrfree(char *string)
245 {
246         PNBUF_PUT(string);
247 }
248
249 /* toss "stale" pages by shrinking the vnode uobj to a 0-length
250  * region (see uvm_vnp_setsize in uvm_vnode.c) */
251 #ifdef AFS_NBSD50_ENV
252 #define VNP_UNCACHE(vp) \
253     do {                \
254         struct uvm_object *uobj = &vp->v_uobj; \
255         mutex_enter(&uobj->vmobjlock); \
256         VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
257         mutex_exit(&uobj->vmobjlock); \
258     } while(0);
259 #else
260 #define VNP_UNCACHE(vp) \
261     do {                \
262         struct uvm_object *uobj = &vp->v_uobj; \
263         simple_lock(&uobj->vmobjlock); \
264         VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
265         simple_unlock(&uobj->vmobjlock); \
266     } while(0);
267 #endif
268
269 /* psuedo-vnop, wherein we learn that obsd and nbsd disagree
270  * about vnode refcounting */
271 void
272 afs_nbsd_getnewvnode(struct vcache *tvc)
273 {
274     struct nbvdata *vd;
275
276     KASSERT(AFSTOV(tvc) == NULL);
277     while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &AFSTOV(tvc))) {
278         /* no vnodes available, force an alloc (limits be damned)! */
279         printf("afs: upping desiredvnodes\n");
280         desiredvnodes++;
281     }
282
283     vd = kmem_zalloc(sizeof(*vd), KM_SLEEP);
284 #ifdef AFS_NBSD50_ENV
285     mutex_enter(&AFSTOV(tvc)->v_interlock);
286 #else
287     simple_lock(&AFSTOV(tvc)->v_interlock);
288 #endif
289     vd->afsvc = tvc;
290     AFSTOV(tvc)->v_data = vd;
291     genfs_node_init(AFSTOV(tvc), &afs_genfsops);
292 #ifdef AFS_NBSD50_ENV
293     mutex_exit(&AFSTOV(tvc)->v_interlock);
294 #else
295     simple_unlock(&AFSTOV(tvc)->v_interlock);
296 #endif
297     uvm_vnp_setsize(AFSTOV(tvc), 0);
298 }
299
300 int
301 afs_nbsd_lookup(void *v)
302 {
303     struct vop_lookup_args      /* {
304                                  * struct vnodeop_desc * a_desc;
305                                  * struct vnode *a_dvp;
306                                  * struct vnode **a_vpp;
307                                  * struct componentname *a_cnp;
308                                  * } */ *ap = v;
309     struct vnode *dvp, *vp;
310     struct vcache *vcp;
311     struct componentname *cnp;
312     char *name;
313     int code;
314
315     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
316         printf("nbsd_lookup a_cnp->cn_nameptr %s cred %p a_dvp %p\n",
317             ap->a_cnp->cn_nameptr, ap->a_cnp->cn_cred, ap->a_dvp);
318     } else {
319         KASSERT(VOP_ISLOCKED(ap->a_dvp));
320     }
321
322     dvp = ap->a_dvp;
323     vp = *ap->a_vpp = NULL;
324     cnp = ap->a_cnp;
325
326 #if AFS_USE_NBSD_NAMECACHE
327     code = cache_lookup(dvp, ap->a_vpp, cnp);
328     if (code >= 0)
329         goto out;
330 #endif
331
332     code = 0;
333
334     if (dvp->v_type != VDIR) {
335         code = ENOTDIR;
336         goto out;
337     }
338
339     name = cnstrdup(cnp);
340     AFS_GLOCK();
341     code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
342     AFS_GUNLOCK();
343     cnstrfree(name); name = NULL;
344
345     if (code == ENOENT
346         && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)
347         && (cnp->cn_flags & ISLASTCN)) {
348             *ap->a_vpp = NULL;
349             code = EJUSTRETURN;
350 #if !defined(AFS_NBSD60_ENV)
351             cnp->cn_flags |= SAVENAME;
352 #endif
353             goto out;
354     }
355
356     if (code == 0) {
357         vp = *ap->a_vpp = AFSTOV(vcp);
358         if (cnp->cn_flags & ISDOTDOT) {
359 #if defined(AFS_NBSD60_ENV)
360             VOP_UNLOCK(dvp);
361 #else
362             VOP_UNLOCK(dvp, 0);
363 #endif
364             vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
365             vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
366         } else if (vp == dvp) {
367             vref(dvp);
368         } else {
369             vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
370         }
371     }
372
373 #if AFS_USE_NBSD_NAMECACHE
374     if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) {
375         cache_enter(dvp, *ap->a_vpp, cnp);
376     }
377 #endif
378
379  out:
380 #if 0
381 #ifdef AFS_NBSD50_ENV
382     if ((afs_debug & AFSDEB_VNLAYER) != 0 && (dvp->v_vflag & VV_ROOT) != 0)
383 #else
384     if ((afs_debug & AFSDEB_VNLAYER) != 0 && (dvp->v_flag & VROOT) != 0)
385 #endif
386 #endif
387     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
388         printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
389     }
390
391     if (code == 0 && afs_debug == 0) {
392         KASSERT(VOP_ISLOCKED(*ap->a_vpp));
393     }
394
395     return (code);
396 }
397
398 int
399 afs_nbsd_create(void *v)
400 {
401     struct vop_create_args      /* {
402                                  * struct vnode *a_dvp;
403                                  * struct vnode **a_vpp;
404                                  * struct componentname *a_cnp;
405                                  * struct vattr *a_vap;
406                                  * } */ *ap = v;
407     int code = 0;
408     struct vcache *vcp;
409     struct vnode *dvp = ap->a_dvp;
410     struct componentname *cnp = ap->a_cnp;
411     char *name;
412
413     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
414         /* printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount); */
415         printf("nbsd_create a_cnp->cn_nameptr %s cred %p a_dvp %p\n",
416             ap->a_cnp->cn_nameptr, ap->a_cnp->cn_cred, ap->a_dvp);
417         /* printf("name: %d %s\n", ap->a_cnp->cn_namelen, name); */
418     }
419
420     /* vnode layer handles excl/nonexcl */
421
422     name = cnstrdup(cnp);
423     AFS_GLOCK();
424     code =
425         afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
426                    &vcp, cnp->cn_cred);
427     AFS_GUNLOCK();
428     cnstrfree(name);
429     if (code) {
430         VOP_ABORTOP(dvp, cnp);
431         vput(dvp);
432         return (code);
433     }
434
435     if (vcp) {
436         *ap->a_vpp = AFSTOV(vcp);
437         vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
438     } else
439         *ap->a_vpp = NULL;
440
441 #if !defined(AFS_NBSD60_ENV)
442     if (code || (cnp->cn_flags & SAVESTART) == 0) {
443         PNBUF_PUT(cnp->cn_pnbuf);
444     }
445 #endif
446     vput(dvp);
447     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
448         printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
449     }
450     return code;
451 }
452
453 int
454 afs_nbsd_mknod(void *v)
455 {
456     struct vop_mknod_args       /* {
457                                  * struct vnode *a_dvp;
458                                  * struct vnode **a_vpp;
459                                  * struct componentname *a_cnp;
460                                  * struct vattr *a_vap;
461                                  * } */ *ap = v;
462
463     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
464         printf("nbsd_mknod: enter %p dvp %p\n", ap, ap->a_dvp);
465     }
466
467
468 #if !defined(AFS_NBSD60_ENV)
469     PNBUF_PUT(ap->a_cnp->cn_pnbuf);
470 #endif
471     vput(ap->a_dvp);
472
473     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
474         printf("nbsd_mknod: exit ap %p\n", ap);
475     }
476
477     return (ENODEV);
478 }
479
480 int
481 afs_nbsd_open(void *v)
482 {
483     struct vop_open_args        /* {
484                                  * struct vnode *a_vp;
485                                  * int  a_mode;
486                                  * struct ucred *a_cred;
487                                  * struct lwp *a_l;
488                                  * } */ *ap = v;
489     int code;
490     struct vnode *vp = ap->a_vp;
491     struct vcache *vc = VTOAFS(vp);
492
493     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
494         printf("nbsd_open: enter %p vp %p vc %p\n", ap, ap->a_vp, vc);
495     }
496
497     AFS_GLOCK();
498     code = afs_open(&vc, ap->a_mode, ap->a_cred);
499 #ifdef DIAGNOSTIC
500     if (AFSTOV(vc) != ap->a_vp)
501         panic("nbsd_open: AFS open changed vnode!");
502 #endif
503     AFS_GUNLOCK();
504
505     uvm_vnp_setsize(ap->a_vp, VTOAFS(ap->a_vp)->f.m.Length);
506
507     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
508         printf("nbsd_open: exit vp %p vc %p\n", vp, vc);
509     }
510
511     return (code);
512 }
513
514 int
515 afs_nbsd_close(void *v)
516 {
517     struct vop_close_args       /* {
518                                  * struct vnode *a_vp;
519                                  * int  a_fflag;
520                                  * kauth_cred_t a_cred;
521                                  * struct lwp *a_l;
522                                  * } */ *ap = v;
523     int code;
524     struct vnode *vp = ap->a_vp;
525     struct vcache *vc = VTOAFS(vp);
526
527     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
528         printf("nbsd_close: enter %p vp %p vc %p\n", ap, ap->a_vp, vc);
529     }
530
531     AFS_GLOCK();
532     code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
533     AFS_GUNLOCK();
534
535     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
536         printf("nbsd_close: exit vp %p vc %p\n", vp, vc);
537     }
538
539     return (code);
540 }
541
542 int
543 afs_nbsd_access(void *v)
544 {
545     struct vop_access_args      /* {
546                                  * struct vnode *a_vp;
547                                  * int  a_mode;
548                                  * kauth_cred_t a_cred;
549                                  * struct lwp *a_l;
550                                  * } */ *ap = v;
551     int code;
552     struct vnode *vp = ap->a_vp;
553     struct vcache *vc = VTOAFS(vp);
554
555     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
556         printf("nbsd_access: enter %p vp %p vc %p mode %d\n", ap, ap->a_vp, vc, ap->a_mode);
557     }
558
559     AFS_GLOCK();
560     code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
561     AFS_GUNLOCK();
562
563     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
564         printf("nbsd_access: exit vp %p vc %p mode %d\n", vp, vc, ap->a_mode);
565     }
566
567     return (code);
568 }
569
570 int
571 afs_nbsd_getattr(void *v)
572 {
573     struct vop_getattr_args     /* {
574                                  * struct vnode *a_vp;
575                                  * struct vattr *a_vap;
576                                  * kauth_cred_t a_cred;
577                                  * struct lwp *a_l;
578                                  * } */ *ap = v;
579     int code;
580     struct vnode *vp = ap->a_vp;
581     struct vcache *vc = VTOAFS(vp);
582
583     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
584         printf("nbsd_getattr: enter %p vp %p vc %p acred %p\n",
585             ap, ap->a_vp, vc, ap->a_cred);
586     }
587
588     AFS_GLOCK();
589     code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
590     AFS_GUNLOCK();
591
592     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
593         printf("nbsd_getattr: exit vp %p vc %p acred %p\n", vp, vc,
594                ap->a_cred);
595     }
596
597     return (code);
598 }
599
600 int
601 afs_nbsd_setattr(void *v)
602 {
603     struct vop_setattr_args     /* {
604                                  * struct vnode *a_vp;
605                                  * struct vattr *a_vap;
606                                  * kauth_cred_t a_cred;
607                                  * struct lwp *a_l;
608                                  * } */ *ap = v;
609     int code;
610
611     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
612         printf("nbsd_setattr: enter %p vp %p\n", ap, ap->a_vp);
613     }
614
615     AFS_GLOCK();
616     code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
617     AFS_GUNLOCK();
618
619     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
620         printf("nbsd_setattr: exit %p\n", ap);
621     }
622
623     return (code);
624 }
625
626 int
627 afs_nbsd_read(void *v)
628 {
629     struct vop_read_args        /* {
630                                  * struct vnode *a_vp;
631                                  * struct uio *a_uio;
632                                  * int a_ioflag;
633                                  * kauth_cred_t a_cred;
634                                  * } */ *ap = v;
635     int code;
636
637     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
638         printf("nbsd_read enter %p vp %p\n", ap, ap->a_vp);
639     }
640
641 #if 0
642     if (ap->a_uio->uio_offset > ap->a_vp->v_size) {
643         return 0; }
644 #endif
645
646     AFS_GLOCK();
647     code = afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0);
648     AFS_GUNLOCK();
649
650     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
651         printf("nbsd_read exit %p\n", ap);
652     }
653
654     return (code);
655 }
656
657 int
658 afs_nbsd_write(void *v)
659 {
660     struct vop_write_args       /* {
661                                  * struct vnode *a_vp;
662                                  * struct uio *a_uio;
663                                  * int a_ioflag;
664                                  * kauth_cred_t a_cred;
665                                  * } */ *ap = v;
666     int code;
667
668     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
669         printf("nbsd_write enter %p vp %p\n", ap, ap->a_vp);
670     }
671
672     AFS_GLOCK();
673     /* osi_FlushPages(VTOAFS(ap->a_vp), ap->a_cred); */
674     code =
675         afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
676     AFS_GUNLOCK();
677
678     if (ap->a_vp->v_size < ap->a_uio->uio_offset) {
679         uvm_vnp_setsize(ap->a_vp, ap->a_uio->uio_offset);
680     }
681
682     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
683         printf("nbsd_write exit %p\n", ap);
684     }
685
686     return (code);
687 }
688
689 int
690 afs_nbsd_ioctl(void *v)
691 {
692     struct vop_ioctl_args       /* {
693                                  * struct vnode *a_vp;
694                                  * int  a_command;
695                                  * caddr_t  a_data;
696                                  * int  a_fflag;
697                                  * kauth_cred_t a_cred;
698                                  * struct lwp *a_l;
699                                  * } */ *ap = v;
700     int code;
701
702     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
703         printf("nbsd_ioctl: enter %p vp %p\n", ap, ap->a_vp);
704     }
705
706     /* in case we ever get in here... */
707
708     AFS_STATCNT(afs_ioctl);
709     AFS_GLOCK();
710     if (((ap->a_command >> 8) & 0xff) == 'V')
711         /* This is a VICEIOCTL call */
712         code =
713             HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
714                         (struct afs_ioctl *)ap->a_data);
715     else
716         /* No-op call; just return. */
717         code = ENOTTY;
718     AFS_GUNLOCK();
719
720     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
721         printf("nbsd_ioctl: exit %p\n", ap);
722     }
723
724     return (code);
725 }
726
727 int
728 afs_nbsd_fsync(void *v)
729 {
730     struct vop_fsync_args       /* {
731                                  * struct vnode *a_vp;
732                                  * kauth_cred_t a_cred;
733                                  * int a_waitfor;
734                                  * struct lwp *a_l;
735                                  * } */ *ap = v;
736     struct vnode *vp = ap->a_vp;
737     int code, wait;
738
739     if (afs_debug & AFSDEB_VNLAYER)
740         printf("nbsd_fsync: enter %p vp %p\n", ap, ap->a_vp);
741
742     wait = (ap->a_flags & FSYNC_WAIT) != 0;
743
744     AFS_GLOCK();
745     vflushbuf(vp, wait);
746     code = afs_fsync(VTOAFS(vp), ap->a_cred);
747     AFS_GUNLOCK();
748
749     if (afs_debug & AFSDEB_VNLAYER)
750         printf("nbsd_fsync: exit %p\n", ap);
751
752     return (code);
753 }
754
755 int
756 afs_nbsd_remove(void *v)
757 {
758     struct vop_remove_args      /* {
759                                  * struct vnode *a_dvp;
760                                  * struct vnode *a_vp;
761                                  * struct componentname *a_cnp;
762                                  * } */ *ap = v;
763     int code;
764     struct vnode *vp = ap->a_vp;
765     struct vnode *dvp = ap->a_dvp;
766     struct componentname *cnp = ap->a_cnp;
767     char *name;
768
769     if (afs_debug & AFSDEB_VNLAYER)
770         printf("nbsd_remove: enter %p vp %p\n", ap, ap->a_vp);
771
772     name = cnstrdup(cnp);
773     AFS_GLOCK();
774     code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
775     AFS_GUNLOCK();
776     cnstrfree(name); name = NULL;
777     if (dvp == vp)
778         vrele(vp);
779     else
780         vput(vp);
781     vput(dvp);
782
783     if (afs_debug & AFSDEB_VNLAYER)
784         printf("nbsd_remove: exit %p\n", ap);
785
786     return (code);
787 }
788
789 int
790 afs_nbsd_link(void *v)
791 {
792     struct vop_link_args        /* {
793                                  * struct vnode *a_vp;
794                                  * struct vnode *a_tdvp;
795                                  * struct componentname *a_cnp;
796                                  * } */ *ap = v;
797     int code;
798     struct vnode *dvp = ap->a_dvp;
799     struct vnode *vp = ap->a_vp;
800     struct componentname *cnp = ap->a_cnp;
801     char *name;
802
803     if (afs_debug & AFSDEB_VNLAYER)
804         printf("nbsd_link: enter %p vp %p\n", ap, ap->a_vp);
805
806     if (dvp->v_mount != vp->v_mount) {
807         VOP_ABORTOP(vp, cnp);
808         code = EXDEV;
809         goto out;
810     }
811     if (vp->v_type == VDIR) {
812         VOP_ABORTOP(vp, cnp);
813         code = EISDIR;
814         goto out;
815     }
816     if (dvp != vp) {
817       if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) {
818         VOP_ABORTOP(dvp, cnp);
819         goto out;
820       }
821     }
822
823     name = cnstrdup(cnp);
824     AFS_GLOCK();
825     code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
826     AFS_GUNLOCK();
827     cnstrfree(name); name = NULL;
828     if (dvp != vp) {
829 #if defined(AFS_NBSD60_ENV)
830         VOP_UNLOCK(vp);
831 #else
832         VOP_UNLOCK(vp, 0);
833 #endif
834     }
835
836   out:
837     vput(dvp);
838
839     if (afs_debug & AFSDEB_VNLAYER)
840         printf("nbsd_link: exit %p\n", ap);
841
842     return (code);
843 }
844
845 int
846 afs_nbsd_rename(void *v)
847 {
848     struct vop_rename_args      /* {
849                                  * struct vnode *a_fdvp;
850                                  * struct vnode *a_fvp;
851                                  * struct componentname *a_fcnp;
852                                  * struct vnode *a_tdvp;
853                                  * struct vnode *a_tvp;
854                                  * struct componentname *a_tcnp;
855                                  * } */ *ap = v;
856     int code = 0;
857     struct componentname *fcnp = ap->a_fcnp;
858     char *fname;
859     struct componentname *tcnp = ap->a_tcnp;
860     char *tname;
861     struct vnode *tvp = ap->a_tvp;
862     struct vnode *tdvp = ap->a_tdvp;
863     struct vnode *fvp = ap->a_fvp;
864     struct vnode *fdvp = ap->a_fdvp;
865
866     if (afs_debug & AFSDEB_VNLAYER)
867         printf("nbsd_rename: enter %p\n", ap);
868
869     /*
870      * Check for cross-device rename.
871      */
872     if ((fvp->v_mount != tdvp->v_mount)
873         || (tvp && (fvp->v_mount != tvp->v_mount))) {
874         code = EXDEV;
875     abortit:
876         VOP_ABORTOP(tdvp, tcnp);    /* XXX, why not in NFS? */
877         if (tdvp == tvp)
878             vrele(tdvp);
879         else
880             vput(tdvp);
881         if (tvp)
882             vput(tvp);
883         VOP_ABORTOP(fdvp, fcnp);    /* XXX, why not in NFS? */
884         vrele(fdvp);
885         vrele(fvp);
886         goto out;
887     }
888     /*
889      * if fvp == tvp, we're just removing one name of a pair of
890      * directory entries for the same element.  convert call into rename.
891      ( (pinched from NetBSD 1.0's ufs_rename())
892      */
893     if (fvp == tvp) {
894         if (fvp->v_type == VDIR) {
895             code = EINVAL;
896             goto abortit;
897         }
898
899         /* Release destination completely. */
900         VOP_ABORTOP(tdvp, tcnp);
901         vput(tdvp);
902         vput(tvp);
903
904         /* Delete source. */
905         vrele(fdvp);
906         vrele(fvp);
907         fcnp->cn_flags &= ~MODMASK;
908         fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
909         fcnp->cn_nameiop = DELETE;
910 #if !defined(AFS_NBSD60_ENV)
911         if ((fcnp->cn_flags & SAVESTART) == 0)
912             panic("afs_rename: lost from startdir");
913         (void)relookup(fdvp, &fvp, fcnp);
914 #else
915         (void)relookup(fdvp, &fvp, fcnp, 0);
916 #endif
917         code = VOP_REMOVE(fdvp, fvp, fcnp);
918         goto out;
919     }
920
921     if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY)))
922         goto abortit;
923
924     fname = cnstrdup(fcnp);
925     tname = cnstrdup(tcnp);
926
927     AFS_GLOCK();
928     /* XXX use "from" or "to" creds? NFS uses "to" creds */
929     code = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
930     AFS_GUNLOCK();
931
932     cnstrfree(fname); fname = NULL;
933     cnstrfree(tname); tname = NULL;
934     if (code)
935         goto abortit;        /* XXX */
936     if (tdvp == tvp)
937         vrele(tdvp);
938     else
939         vput(tdvp);
940     if (tvp)
941         vput(tvp);
942     vrele(fdvp);
943     vput(fvp);
944
945  out:
946     if (afs_debug & AFSDEB_VNLAYER)
947         printf("nbsd_rename: exit %p\n", ap);
948
949     return (code);
950 }
951
952 int
953 afs_nbsd_mkdir(void *v)
954 {
955     struct vop_mkdir_args       /* {
956                                  * struct vnode *a_dvp;
957                                  * struct vnode **a_vpp;
958                                  * struct componentname *a_cnp;
959                                  * struct vattr *a_vap;
960                                  * } */ *ap = v;
961     struct vnode *dvp = ap->a_dvp;
962     struct vattr *vap = ap->a_vap;
963     struct componentname *cnp = ap->a_cnp;
964     struct vcache *vcp;
965     int code;
966     char *name;
967
968
969     if (afs_debug & AFSDEB_VNLAYER)
970         printf("nbsd_mkdir: enter %p dvp %p\n", ap, ap->a_dvp);
971
972 #if !defined(AFS_NBSD60_ENV)
973 #ifdef DIAGNOSTIC
974     if ((cnp->cn_flags & HASBUF) == 0)
975         panic("afs_nbsd_mkdir: no name");
976 #endif
977 #endif
978
979     name = cnstrdup(cnp);
980     AFS_GLOCK();
981     code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
982     AFS_GUNLOCK();
983     cnstrfree(name); name = NULL;
984     if (code) {
985         VOP_ABORTOP(dvp, cnp);
986         vput(dvp);
987         goto out;
988     }
989     if (vcp) {
990         *ap->a_vpp = AFSTOV(vcp);
991         vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
992     } else
993         *ap->a_vpp = NULL;
994 #if !defined(AFS_NBSD60_ENV)
995     if (code || (cnp->cn_flags & SAVESTART) == 0) {
996         PNBUF_PUT(cnp->cn_pnbuf);
997     }
998 #endif
999     vput(dvp);
1000
1001  out:
1002     if (afs_debug & AFSDEB_VNLAYER)
1003         printf("nbsd_mkdir: exit %p\n", ap);
1004
1005     return (code);
1006 }
1007
1008 int
1009 afs_nbsd_rmdir(void *v)
1010 {
1011     struct vop_rmdir_args       /* {
1012                                  * struct vnode *a_dvp;
1013                                  * struct vnode *a_vp;
1014                                  * struct componentname *a_cnp;
1015                                  * } */ *ap = v;
1016     int code;
1017     struct vnode *vp = ap->a_vp;
1018     struct vnode *dvp = ap->a_dvp;
1019     struct componentname *cnp = ap->a_cnp;
1020     char *name;
1021
1022
1023     if (afs_debug & AFSDEB_VNLAYER)
1024         printf("nbsd_rmdir: enter %p vp %p\n", ap, ap->a_vp);
1025
1026     if (dvp == vp) {
1027         vrele(dvp);
1028         vput(vp);
1029         code = EINVAL;
1030         goto out;
1031     }
1032
1033     name = cnstrdup(cnp);
1034     AFS_GLOCK();
1035     code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
1036     AFS_GUNLOCK();
1037     cnstrfree(name); name = NULL;
1038
1039 #if AFS_USE_NBSD_NAMECACHE
1040     if (code == 0) {
1041         cache_purge(vp);
1042     }
1043 #endif
1044
1045     vput(dvp);
1046     vput(vp);
1047
1048  out:
1049     if (afs_debug & AFSDEB_VNLAYER)
1050         printf("nbsd_rmdir: exit %p\n", ap);
1051
1052     return (code);
1053 }
1054
1055 int
1056 afs_nbsd_symlink(void *v)
1057 {
1058     struct vop_symlink_args     /* {
1059                                  * struct vnode *a_dvp;
1060                                  * struct vnode **a_vpp;
1061                                  * struct componentname *a_cnp;
1062                                  * struct vattr *a_vap;
1063                                  * char *a_target;
1064                                  * } */ *ap = v;
1065     struct vnode *dvp = ap->a_dvp;
1066     struct vnode *nvp = NULL;
1067     struct vcache *vcp;
1068     struct componentname *cnp = ap->a_cnp;
1069     int code;
1070     char *name;
1071     /* NFS ignores a_vpp; so do we. */
1072
1073     if (afs_debug & AFSDEB_VNLAYER)
1074         printf("nbsd_symlink: enter %p dvp %p\n", ap, ap->a_dvp);
1075
1076     name = cnstrdup(cnp);
1077     AFS_GLOCK();
1078     code =
1079         afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
1080                     cnp->cn_cred);
1081     if (code == 0) {
1082         code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
1083         if (code == 0) {
1084           nvp = AFSTOV(vcp);
1085           vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
1086         }
1087     }
1088     AFS_GUNLOCK();
1089     cnstrfree(name); name = NULL;
1090 #if !defined(AFS_NBSD60_ENV)
1091     if (code || (cnp->cn_flags & SAVESTART) == 0) {
1092         PNBUF_PUT(cnp->cn_pnbuf);
1093     }
1094 #endif
1095
1096     *(ap->a_vpp) = nvp;
1097
1098     vput(dvp);
1099
1100     if (afs_debug & AFSDEB_VNLAYER)
1101         printf("nbsd_symlink: exit %p\n", ap);
1102
1103     return (code);
1104 }
1105
1106 int
1107 afs_nbsd_readdir(void *v)
1108 {
1109     struct vop_readdir_args     /* {
1110                                  * struct vnode *a_vp;
1111                                  * struct uio *a_uio;
1112                                  * kauth_cred_t a_cred;
1113                                  * int *a_eofflag;
1114                                  * int *a_ncookies;
1115                                  * u_long **a_cookies;
1116                                  * } */ *ap = v;
1117     int code;
1118     struct vnode *vp = ap->a_vp;
1119     struct vcache *vc = VTOAFS(vp);
1120
1121     if (afs_debug & AFSDEB_VNLAYER)
1122         printf("nbsd_readdir: enter %p vp %p vc %p acred %p auio %p\n", ap,
1123             vp, vc, ap->a_cred, ap->a_uio);
1124
1125     AFS_GLOCK();
1126 #ifdef AFS_HAVE_COOKIES
1127     printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
1128            ap->a_ncookies);
1129     code =
1130         afs_readdir(vc, ap->a_uio, ap->a_cred, ap->a_eofflag,
1131                     ap->a_ncookies, ap->a_cookies);
1132 #else
1133     code =
1134         afs_readdir(vc, ap->a_uio, ap->a_cred, ap->a_eofflag);
1135 #endif
1136     AFS_GUNLOCK();
1137
1138     if (afs_debug & AFSDEB_VNLAYER)
1139         printf("nbsd_readdir: exit %p eofflag %d\n", ap, *ap->a_eofflag);
1140
1141     return (code);
1142 }
1143
1144 int
1145 afs_nbsd_readlink(void *v)
1146 {
1147     struct vop_readlink_args    /* {
1148                                  * struct vnode *a_vp;
1149                                  * struct uio *a_uio;
1150                                  * kauth_cred_t a_cred;
1151                                  * } */ *ap = v;
1152     int code;
1153
1154     if (afs_debug & AFSDEB_VNLAYER)
1155         printf("nbsd_readlink: enter %p vp %p\n", ap, ap->a_vp);
1156
1157     AFS_GLOCK();
1158     code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
1159     AFS_GUNLOCK();
1160
1161     if (afs_debug & AFSDEB_VNLAYER)
1162         printf("nbsd_readlink: exit %p\n", ap);
1163
1164     return (code);
1165 }
1166
1167 extern int prtactive;
1168
1169 int
1170 afs_nbsd_inactive(void *v)
1171 {
1172     struct vop_inactive_args    /* {
1173                                  * struct vnode *a_vp;
1174                                  * } */ *ap = v;
1175     struct vnode *vp = ap->a_vp;
1176     struct vcache *vc = VTOAFS(vp);
1177     int haveGlock = ISAFS_GLOCK();
1178
1179     AFS_STATCNT(afs_inactive);
1180
1181     if (afs_debug & AFSDEB_VNLAYER)
1182         printf("nbsd_inactive: enter %p vp %p\n", ap, ap->a_vp);
1183
1184     if (prtactive && vp->v_usecount != 0)
1185         vprint("afs_nbsd_inactive: pushing active", vp);
1186
1187     if (!haveGlock)
1188         AFS_GLOCK();
1189     afs_InactiveVCache(vc, NULL);       /* decrs ref counts */
1190     if (!haveGlock)
1191         AFS_GUNLOCK();
1192
1193     *ap->a_recycle = (vc->f.states & CUnlinked) != 0;
1194
1195 #if defined(AFS_NBSD60_ENV)
1196     VOP_UNLOCK(vp);
1197 #else
1198     VOP_UNLOCK(vp, 0);
1199 #endif
1200
1201     if (afs_debug & AFSDEB_VNLAYER)
1202         printf("nbsd_inactive: exit %p\n", ap);
1203
1204     return (0);
1205 }
1206
1207 int
1208 afs_nbsd_reclaim(void *v)
1209 {
1210     struct vop_reclaim_args     /* {
1211                                  * struct vnode *a_vp;
1212                                  * } */ *ap = v;
1213     int code, slept;
1214     struct vnode *vp = ap->a_vp;
1215     struct vcache *avc = VTOAFS(vp);
1216     int haveGlock = ISAFS_GLOCK();
1217     int haveVlock = CheckLock(&afs_xvcache);
1218
1219     if (afs_debug & AFSDEB_VNLAYER)
1220         printf("nbsd_reclaim: enter %p vp %p\n", ap, vp);
1221
1222     if (!haveGlock)
1223                 AFS_GLOCK();
1224     if (!haveVlock)
1225                 ObtainWriteLock(&afs_xvcache, 901);
1226     /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
1227     code = afs_FlushVCache(avc, &slept);
1228
1229 #if 1
1230     if (avc->f.states & CVInit) {
1231         avc->f.states &= ~CVInit;
1232         afs_osi_Wakeup(&avc->f.states);
1233     }
1234 #endif
1235
1236     if (!haveVlock)
1237         ReleaseWriteLock(&afs_xvcache);
1238     if (!haveGlock)
1239         AFS_GUNLOCK();
1240
1241     if (vp->v_tag != VT_AFS) {
1242         vprint("afs reclaim", vp);
1243     }
1244     KASSERT(vp->v_tag == VT_AFS);
1245
1246     if (vp->v_data != NULL) {
1247         genfs_node_destroy(vp);
1248         kmem_free(vp->v_data, sizeof(struct nbvdata));
1249         vp->v_data = NULL;              /* remove from vnode */
1250         avc->v = NULL;                  /* also drop the ptr to vnode */
1251     } else {
1252         if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1253             vprint("reclaim", vp);
1254         }
1255     }
1256
1257 #if AFS_USE_NBSD_NAMECACHE
1258     cache_purge(vp);
1259 #endif
1260
1261     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1262         printf("nbsd_reclaim: exit %p\n", ap);
1263     }
1264
1265     return code;
1266 }
1267
1268 int
1269 afs_nbsd_lock(void *v)
1270 {
1271     struct vop_lock_args        /* {
1272                                  * struct vnode *a_vp;
1273                                  * int a_flags;
1274                                  * struct lwp *a_l;
1275                                  * } */ *ap = v;
1276     int code;
1277
1278     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1279         printf("nbsd_lock: enter %p vp %p\n", ap, ap->a_vp);
1280     }
1281
1282     KASSERT(VTOAFS(ap->a_vp) != NULL);
1283
1284     code = genfs_lock(v);
1285
1286     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1287         printf("nbsd_lock: exit %p\n", ap);
1288     }
1289
1290     return (code);
1291 }
1292
1293 int
1294 afs_nbsd_unlock(void *v)
1295 {
1296     struct vop_unlock_args      /* {
1297                                  * struct vnode *a_vp;
1298                                  * int a_flags;
1299                                  * struct lwp *a_l;
1300                                  * } */ *ap = v;
1301     int code;
1302
1303     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1304         printf("nbsd_unlock: enter %p vp %p\n", ap, ap->a_vp);
1305     }
1306
1307     KASSERT(VTOAFS(ap->a_vp) != NULL);
1308
1309     code = genfs_unlock(v);
1310
1311     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1312         printf("nbsd_unlock: exit %p\n", ap);
1313     }
1314
1315     return (code);
1316 }
1317
1318 int
1319 afs_nbsd_islocked(void *v)
1320 {
1321     struct vop_islocked_args    /* {
1322                                  * struct vnode *a_vp;
1323                                  * } */ *ap = v;
1324
1325     int code;
1326
1327     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1328         printf("nbsd_islocked: enter %p vp %p\n", ap, ap->a_vp);
1329     }
1330
1331     code = genfs_islocked(v);
1332
1333     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1334         printf("nbsd_islocked: exit %p\n", ap);
1335     }
1336
1337     return (code);
1338 }
1339
1340
1341 int
1342 afs_nbsd_bmap(void *v)
1343 {
1344     struct vop_bmap_args        /* {
1345                                  * struct vnode *a_vp;
1346                                  * daddr_t  a_bn;
1347                                  * struct vnode **a_vpp;
1348                                  * daddr_t *a_bnp;
1349                                  * int *a_runp;
1350                                  * } */ *ap = v;
1351
1352     AFS_STATCNT(afs_bmap);
1353
1354     if (afs_debug & AFSDEB_VNLAYER)
1355         printf("nbsd_bmap: enter %p vp %p\n", ap, ap->a_vp);
1356
1357     if (ap->a_bnp)
1358         *ap->a_bnp = ap->a_bn;
1359     if (ap->a_vpp)
1360         *ap->a_vpp = ap->a_vp;
1361     if (ap->a_runp != NULL)
1362         *ap->a_runp = 1024 * 1024; /* XXX */
1363 #ifdef notyet
1364     if (ap->a_runb != NULL)
1365         *ap->a_runb = 0;
1366 #endif
1367
1368 #if 0
1369     if (afs_debug & AFSDEB_VNLAYER)
1370         printf("nbsd_bmap: exit %p\n", ap);
1371 #endif
1372
1373     return (0);
1374 }
1375
1376 int
1377 afs_nbsd_strategy(void *v)
1378 {
1379     struct vop_strategy_args    /* {
1380                                  * struct buf *a_bp;
1381                                  * } */ *ap = v;
1382     int code;
1383
1384     AFS_STATCNT(afs_strategy);
1385
1386     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1387         printf("nbsd_strategy: enter %p vp %p\n", ap, ap->a_vp);
1388     }
1389
1390     AFS_GLOCK();
1391     code = afs_ustrategy(ap->a_bp, osi_curcred());
1392     AFS_GUNLOCK();
1393
1394     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1395         printf("nbsd_strategy: exit %p vp %p\n", ap, ap->a_vp);
1396     }
1397
1398     return (code);
1399 }
1400
1401 int
1402 afs_nbsd_print(void *v)
1403 {
1404     struct vop_print_args       /* {
1405                                  * struct vnode *a_vp;
1406                                  * } */ *ap = v;
1407     struct vnode *vp = ap->a_vp;
1408     struct vcache *vc = VTOAFS(ap->a_vp);
1409
1410     printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
1411            vc->f.fid.Fid.Volume, vc->f.fid.Fid.Vnode,
1412            vc->f.fid.Fid.Unique);
1413 #ifdef AFS_NBSD50_ENV
1414 #if defined(DDB) && defined(LOCKDEBUG)
1415     lockdebug_lock_print(&vc->rwlock, printf);
1416 #endif
1417 #else
1418     lockmgr_printinfo(&vc->rwlock);
1419 #endif
1420     printf("\n");
1421     return (0);
1422 }
1423
1424 /*
1425  * Return POSIX pathconf information applicable to ufs filesystems.
1426  */
1427 int
1428 afs_nbsd_pathconf(void *v)
1429 {
1430     struct vop_pathconf_args    /* {
1431                                  * struct vnode *a_vp;
1432                                  * int a_name;
1433                                  * int *a_retval;
1434                                  * } */ *ap = v;
1435     int code = 0;
1436
1437     AFS_STATCNT(afs_cntl);
1438
1439     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1440         printf("nbsd_pathconf: enter %p vp %p\n", ap, ap->a_vp);
1441     }
1442
1443     switch (ap->a_name) {
1444     case _PC_LINK_MAX:
1445         *ap->a_retval = LINK_MAX;
1446         break;
1447     case _PC_NAME_MAX:
1448         *ap->a_retval = NAME_MAX;
1449         break;
1450     case _PC_PATH_MAX:
1451         *ap->a_retval = PATH_MAX;
1452         break;
1453     case _PC_CHOWN_RESTRICTED:
1454         *ap->a_retval = 1;
1455         break;
1456     case _PC_NO_TRUNC:
1457         *ap->a_retval = 1;
1458         break;
1459     case _PC_PIPE_BUF:
1460         code = EINVAL;
1461         goto out;
1462         break;
1463     default:
1464         code = EINVAL;
1465         goto out;
1466     }
1467
1468 out:
1469     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1470         printf("nbsd_pathconf: exit %p\n", ap);
1471     }
1472
1473     return (0);
1474 }
1475
1476 extern int
1477   afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
1478               afs_ucred_t *acred, pid_t clid);
1479
1480 /*
1481  * Advisory record locking support (fcntl() POSIX style)
1482  */
1483 int
1484 afs_nbsd_advlock(void *v)
1485 {
1486     struct vop_advlock_args     /* {
1487                                  * struct vnode *a_vp;
1488                                  * caddr_t  a_id;
1489                                  * int  a_op;
1490                                  * struct flock *a_fl;
1491                                  * int  a_flags;
1492                                  * } */ *ap = v;
1493     int code;
1494
1495     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1496         printf("nbsd_pathconf: enter %p vp %p\n", ap, ap->a_vp);
1497     }
1498
1499     AFS_GLOCK();
1500     code = afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),
1501         (uintptr_t)ap->a_id);
1502     AFS_GUNLOCK();
1503
1504     if ((afs_debug & AFSDEB_VNLAYER) != 0) {
1505         printf("nbsd_pathconf: exit %p\n", ap);
1506     }
1507
1508     return (code);
1509 }