2 Copyright 1995 Massachusetts Institute of Technology. All Rights
5 You are hereby granted a worldwide, irrevocable, paid-up, right and
6 license to use, execute, display, modify, copy and distribute MIT's
7 Modifications, provided that (i) you abide by the terms and conditions
8 of your Transarc AFS License Agreement, and (ii) you do not use the name
9 of MIT in any advertising or publicity without the prior written consent
10 of MIT. MIT disclaims all liability for your use of MIT's
11 Modifications. MIT's Modifications are provided "AS IS" WITHOUT
12 WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
13 ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
18 * OpenBSD specific vnodeops + other misc interface glue
19 * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
20 * OpenBSD version by Jim Rees <rees@umich.edu>
26 * A bunch of code cribbed from NetBSD ufs_vnops.c, ffs_vnops.c, and
27 * nfs_vnops.c which carry this copyright:
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
32 * (c) UNIX System Laboratories, Inc.
33 * All or some portions of this file are derived from material licensed
34 * to the University of California by American Telephone and Telegraph
35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
36 * the permission of UNIX System Laboratories, Inc.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 #include <afsconfig.h>
69 #include "afs/param.h"
73 #include "afs/sysincludes.h" /* Standard vendor system headers */
74 #include "afs/afsincludes.h" /* Afs-based standard headers */
75 #include "afs/afs_stats.h" /* statistics */
77 #include <sys/malloc.h>
78 #include <sys/namei.h>
80 #include "afs/afs_cbqueue.h"
81 #include "afs/nfsclient.h"
82 #include "afs/afs_osidnlc.h"
85 extern int afs_FlushVS(struct vcache *tvc);
88 #define M_AFSNODE (M_TEMP-1) /* XXX */
90 int afs_nbsd_lookup(struct vop_lookup_args *);
91 int afs_nbsd_create(struct vop_create_args *);
92 int afs_nbsd_mknod(struct vop_mknod_args *);
93 int afs_nbsd_open(struct vop_open_args *);
94 int afs_nbsd_close(struct vop_close_args *);
95 int afs_nbsd_access(struct vop_access_args *);
96 int afs_nbsd_getattr(struct vop_getattr_args *);
97 int afs_nbsd_setattr(struct vop_setattr_args *);
98 int afs_nbsd_read(struct vop_read_args *);
99 int afs_nbsd_write(struct vop_write_args *);
100 int afs_nbsd_ioctl(struct vop_ioctl_args *);
101 int afs_nbsd_select(struct vop_select_args *);
102 int afs_nbsd_fsync(struct vop_fsync_args *);
103 int afs_nbsd_remove(struct vop_remove_args *);
104 int afs_nbsd_link(struct vop_link_args *);
105 int afs_nbsd_rename(struct vop_rename_args *);
106 int afs_nbsd_mkdir(struct vop_mkdir_args *);
107 int afs_nbsd_rmdir(struct vop_rmdir_args *);
108 int afs_nbsd_symlink(struct vop_symlink_args *);
109 int afs_nbsd_readdir(struct vop_readdir_args *);
110 int afs_nbsd_readlink(struct vop_readlink_args *);
111 extern int ufs_abortop(struct vop_abortop_args *);
112 int afs_nbsd_inactive(struct vop_inactive_args *);
113 int afs_nbsd_reclaim(struct vop_reclaim_args *);
114 int afs_nbsd_lock(struct vop_lock_args *);
115 int afs_nbsd_unlock(struct vop_unlock_args *);
116 int afs_nbsd_bmap(struct vop_bmap_args *);
117 int afs_nbsd_strategy(struct vop_strategy_args *);
118 int afs_nbsd_print(struct vop_print_args *);
119 int afs_nbsd_islocked(struct vop_islocked_args *);
120 int afs_nbsd_pathconf(struct vop_pathconf_args *);
121 int afs_nbsd_advlock(struct vop_advlock_args *);
123 #define afs_nbsd_opnotsupp \
124 ((int (*) __P((struct vop_reallocblks_args *)))eopnotsupp)
125 #define afs_nbsd_reallocblks afs_nbsd_opnotsupp
127 /* Global vfs data structures for AFS. */
128 int (**afs_vnodeop_p) __P((void *));
129 struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
130 { &vop_default_desc, vn_default_error },
131 { &vop_lookup_desc, afs_nbsd_lookup }, /* lookup */
132 { &vop_create_desc, afs_nbsd_create }, /* create */
133 { &vop_mknod_desc, afs_nbsd_mknod }, /* mknod */
134 { &vop_open_desc, afs_nbsd_open }, /* open */
135 { &vop_close_desc, afs_nbsd_close }, /* close */
136 { &vop_access_desc, afs_nbsd_access }, /* access */
137 { &vop_getattr_desc, afs_nbsd_getattr }, /* getattr */
138 { &vop_setattr_desc, afs_nbsd_setattr }, /* setattr */
139 { &vop_read_desc, afs_nbsd_read }, /* read */
140 { &vop_write_desc, afs_nbsd_write }, /* write */
141 { &vop_ioctl_desc, afs_nbsd_ioctl }, /* XXX ioctl */
142 { &vop_select_desc, afs_nbsd_select }, /* select */
143 { &vop_fsync_desc, afs_nbsd_fsync }, /* fsync */
144 { &vop_remove_desc, afs_nbsd_remove }, /* remove */
145 { &vop_link_desc, afs_nbsd_link }, /* link */
146 { &vop_rename_desc, afs_nbsd_rename }, /* rename */
147 { &vop_mkdir_desc, afs_nbsd_mkdir }, /* mkdir */
148 { &vop_rmdir_desc, afs_nbsd_rmdir }, /* rmdir */
149 { &vop_symlink_desc, afs_nbsd_symlink }, /* symlink */
150 { &vop_readdir_desc, afs_nbsd_readdir }, /* readdir */
151 { &vop_readlink_desc, afs_nbsd_readlink }, /* readlink */
152 { &vop_abortop_desc, vop_generic_abortop }, /* abortop */
153 { &vop_inactive_desc, afs_nbsd_inactive }, /* inactive */
154 { &vop_reclaim_desc, afs_nbsd_reclaim }, /* reclaim */
155 { &vop_lock_desc, afs_nbsd_lock }, /* lock */
156 { &vop_unlock_desc, afs_nbsd_unlock }, /* unlock */
157 { &vop_bmap_desc, afs_nbsd_bmap }, /* bmap */
158 { &vop_strategy_desc, afs_nbsd_strategy }, /* strategy */
159 { &vop_print_desc, afs_nbsd_print }, /* print */
160 { &vop_islocked_desc, afs_nbsd_islocked }, /* islocked */
161 { &vop_pathconf_desc, afs_nbsd_pathconf }, /* pathconf */
162 { &vop_advlock_desc, afs_nbsd_advlock }, /* advlock */
163 { &vop_reallocblks_desc, afs_nbsd_reallocblks }, /* reallocblks */
164 { &vop_bwrite_desc, vop_generic_bwrite },
165 { (struct vnodeop_desc *) NULL, (int (*) __P((void *))) NULL}
167 struct vnodeopv_desc afs_vnodeop_opv_desc =
168 { &afs_vnodeop_p, afs_vnodeop_entries };
171 struct componentname *cnp = ap->a_cnp; \
173 MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \
174 bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
175 name[cnp->cn_namelen] = '\0'
177 #define DROPNAME() FREE(name, M_TEMP)
181 #define NBSD_WRITES_ALLOWED
182 #ifndef NBSD_WRITES_ALLOWED
183 int nbsd_writes_allowed = 0;
187 #define vrele afs_nbsd_rele
189 #define VREF afs_nbsd_ref
193 struct vop_lookup_args /* {
194 struct vnodeop_desc * a_desc;
196 struct vnode **a_vpp;
197 struct componentname *a_cnp;
202 struct vnode *vp, *dvp;
203 int flags = ap->a_cnp->cn_flags;
204 int lockparent; /* 1 => lockparent flag is set */
205 int wantparent; /* 1 => wantparent or lockparent flag */
208 lockparent = flags & LOCKPARENT;
209 wantparent = flags & (LOCKPARENT|WANTPARENT);
211 if (ap->a_dvp->v_type != VDIR) {
217 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
218 printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags, name, dvp->v_usecount);
219 error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
221 if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
222 (flags & ISLASTCN) && error == ENOENT)
224 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
225 cnp->cn_flags |= SAVENAME;
230 vp = AFSTOV(vcp); /* always get a node if no error */
232 /* The parent directory comes in locked. We unlock it on return
233 unless the caller wants it left locked.
234 we also always return the vnode locked. */
237 /* they're the same; afs_lookup() already ref'ed the leaf.
238 It came in locked, so we don't need to ref OR lock it */
239 if (afs_debug & AFSDEB_VNLAYER)
240 printf("ref'ed %p as .\n", dvp);
242 if (!lockparent || !(flags & ISLASTCN))
243 VOP_UNLOCK(dvp, 0, curproc); /* done with parent. */
244 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc); /* always return the child locked */
245 if (afs_debug & AFSDEB_VNLAYER)
246 printf("locked ret %p from lookup\n", vp);
250 if (((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN))
251 || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
252 cnp->cn_flags |= SAVENAME;
255 if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
256 printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
262 struct vop_create_args /* {
264 struct vnode **a_vpp;
265 struct componentname *a_cnp;
271 struct vnode *dvp = ap->a_dvp;
274 if (afs_debug & AFSDEB_VNLAYER)
275 printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
277 /* vnode layer handles excl/nonexcl */
279 #ifndef NBSD_WRITES_ALLOWED
280 if (!nbsd_writes_allowed)
284 error = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
285 ap->a_vap->va_mode, &vcp,
288 VOP_ABORTOP(dvp, cnp);
295 *ap->a_vpp = AFSTOV(vcp);
296 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
300 if ((cnp->cn_flags & SAVESTART) == 0)
301 FREE(cnp->cn_pnbuf, M_NAMEI);
304 if (afs_debug & AFSDEB_VNLAYER)
305 printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
311 struct vop_mknod_args /* {
313 struct vnode **a_vpp;
314 struct componentname *a_cnp;
318 free(ap->a_cnp->cn_pnbuf, M_NAMEI);
325 struct vop_open_args /* {
328 struct ucred *a_cred;
333 struct vcache *vc = VTOAFS(ap->a_vp);
334 error = afs_open(&vc, ap->a_mode, ap->a_cred);
336 if (AFSTOV(vc) != ap->a_vp)
337 panic("AFS open changed vnode!");
344 struct vop_close_args /* {
347 struct ucred *a_cred;
351 return afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
356 struct vop_access_args /* {
359 struct ucred *a_cred;
363 return afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
367 struct vop_getattr_args /* {
370 struct ucred *a_cred;
374 return afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
378 struct vop_setattr_args /* {
381 struct ucred *a_cred;
385 return afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
389 struct vop_read_args /* {
393 struct ucred *a_cred;
396 return afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0, 0, 0);
400 struct vop_write_args /* {
404 struct ucred *a_cred;
408 (void) uvm_vnp_uncache(ap->a_vp); /* toss stale pages */
410 vnode_pager_uncache(ap->a_vp);
412 return afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
416 struct vop_ioctl_args /* {
421 struct ucred *a_cred;
425 struct vcache *tvc = VTOAFS(ap->a_vp);
428 /* in case we ever get in here... */
430 AFS_STATCNT(afs_ioctl);
431 if (((ap->a_command >> 8) & 0xff) == 'V') {
432 /* This is a VICEIOCTL call */
433 error = HandleIoctl(tvc, (struct file *)0/*Not used*/,
434 ap->a_command, ap->a_data);
437 /* No-op call; just return. */
445 struct vop_select_args /* {
449 struct ucred *a_cred;
454 * We should really check to see if I/O is possible.
461 struct vop_fsync_args /* {
463 struct ucred *a_cred;
468 int wait = ap->a_waitfor == MNT_WAIT;
469 struct vnode *vp = ap->a_vp;
471 return afs_fsync(VTOAFS(vp), ap->a_cred);
476 struct vop_remove_args /* {
479 struct componentname *a_cnp;
483 struct vnode *vp = ap->a_vp;
484 struct vnode *dvp = ap->a_dvp;
487 #ifndef NBSD_WRITES_ALLOWED
488 if (!nbsd_writes_allowed)
492 error = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
498 FREE(cnp->cn_pnbuf, M_NAMEI);
505 struct vop_link_args /* {
507 struct vnode *a_tdvp;
508 struct componentname *a_cnp;
512 struct vnode *dvp = ap->a_dvp;
513 struct vnode *vp = ap->a_vp;
516 if (dvp->v_mount != vp->v_mount) {
517 VOP_ABORTOP(vp, cnp);
521 if (vp->v_type == VDIR) {
522 VOP_ABORTOP(vp, cnp);
526 if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
527 VOP_ABORTOP(dvp, cnp);
530 #ifndef NBSD_WRITES_ALLOWED
531 if (!nbsd_writes_allowed)
535 error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
536 FREE(cnp->cn_pnbuf, M_NAMEI);
538 VOP_UNLOCK(vp, 0, curproc);
547 struct vop_rename_args /* {
548 struct vnode *a_fdvp;
550 struct componentname *a_fcnp;
551 struct vnode *a_tdvp;
553 struct componentname *a_tcnp;
557 struct componentname *fcnp = ap->a_fcnp;
559 struct componentname *tcnp = ap->a_tcnp;
561 struct vnode *tvp = ap->a_tvp;
562 struct vnode *tdvp = ap->a_tdvp;
563 struct vnode *fvp = ap->a_fvp;
564 struct vnode *fdvp = ap->a_fdvp;
567 * Check for cross-device rename.
569 if ((fvp->v_mount != tdvp->v_mount) ||
570 (tvp && (fvp->v_mount != tvp->v_mount))) {
573 VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
580 VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
586 * if fvp == tvp, we're just removing one name of a pair of
587 * directory entries for the same element. convert call into rename.
588 ( (pinched from NetBSD 1.0's ufs_rename())
591 if (fvp->v_type == VDIR) {
596 /* Release destination completely. */
597 VOP_ABORTOP(tdvp, tcnp);
604 fcnp->cn_flags &= ~MODMASK;
605 fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
606 if ((fcnp->cn_flags & SAVESTART) == 0)
607 panic("afs_rename: lost from startdir");
608 fcnp->cn_nameiop = DELETE;
609 (void) relookup(fdvp, &fvp, fcnp);
610 return (VOP_REMOVE(fdvp, fvp, fcnp));
613 if ((error = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
616 MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK);
617 bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
618 fname[fcnp->cn_namelen] = '\0';
619 MALLOC(tname, char *, tcnp->cn_namelen+1, M_TEMP, M_WAITOK);
620 bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
621 tname[tcnp->cn_namelen] = '\0';
624 #ifndef NBSD_WRITES_ALLOWED
625 if (!nbsd_writes_allowed)
629 /* XXX use "from" or "to" creds? NFS uses "to" creds */
630 error = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
632 VOP_UNLOCK(fvp, 0, curproc);
636 goto abortit; /* XXX */
650 struct vop_mkdir_args /* {
652 struct vnode **a_vpp;
653 struct componentname *a_cnp;
657 struct vnode *dvp = ap->a_dvp;
658 struct vattr *vap = ap->a_vap;
664 if ((cnp->cn_flags & HASBUF) == 0)
665 panic("afs_nbsd_mkdir: no name");
667 #ifndef NBSD_WRITES_ALLOWED
668 if (!nbsd_writes_allowed)
672 error = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
674 VOP_ABORTOP(dvp, cnp);
680 *ap->a_vpp = AFSTOV(vcp);
681 vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY, curproc);
685 FREE(cnp->cn_pnbuf, M_NAMEI);
692 struct vop_rmdir_args /* {
695 struct componentname *a_cnp;
699 struct vnode *vp = ap->a_vp;
700 struct vnode *dvp = ap->a_dvp;
706 FREE(cnp->cn_pnbuf, M_NAMEI);
711 #ifndef NBSD_WRITES_ALLOWED
712 if (!nbsd_writes_allowed)
716 error = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
725 struct vop_symlink_args /* {
727 struct vnode **a_vpp;
728 struct componentname *a_cnp;
733 struct vnode *dvp = ap->a_dvp;
735 /* NFS ignores a_vpp; so do we. */
738 #ifndef NBSD_WRITES_ALLOWED
739 if (!nbsd_writes_allowed)
743 error = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
746 FREE(cnp->cn_pnbuf, M_NAMEI);
753 struct vop_readdir_args /* {
756 struct ucred *a_cred;
762 /* printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
764 return afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
765 ap->a_eofflag, ap->a_ncookies, ap->a_cookies);
769 afs_nbsd_readlink(ap)
770 struct vop_readlink_args /* {
773 struct ucred *a_cred;
776 /* printf("readlink %p\n", ap->a_vp);*/
777 return afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
780 extern int prtactive;
783 afs_nbsd_inactive(ap)
784 struct vop_inactive_args /* {
788 struct vnode *vp = ap->a_vp;
789 struct vcache *vc = VTOAFS(vp);
791 AFS_STATCNT(afs_inactive);
793 if (prtactive && vp->v_usecount != 0)
794 vprint("afs_nbsd_inactive(): pushing active", vp);
796 vc->states &= ~CMAPPED;
797 vc->states &= ~CDirty;
799 lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
805 struct vop_reclaim_args /* {
810 struct vnode *vp = ap->a_vp;
811 struct vcache *avc = VTOAFS(vp);
813 cache_purge(vp); /* just in case... */
817 vnode_pager_uncache(vp);
820 #ifndef AFS_DISCON_ENV
821 error = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
823 /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
824 error = afs_FlushVS(avc);
826 if (!error && vp->v_data)
827 panic("afs_reclaim: vnode not cleaned");
833 struct vop_lock_args /* {
839 struct vnode *vp = ap->a_vp;
840 struct vcache *vc = VTOAFS(vp);
844 panic("afs_nbsd_lock: null vcache");
846 return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock, ap->a_p);
851 struct vop_unlock_args /* {
857 struct vnode *vp = ap->a_vp;
858 struct vcache *vc = VTOAFS(vp);
862 panic("afs_nbsd_unlock: null vcache");
864 return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock, ap->a_p);
869 struct vop_bmap_args /* {
872 struct vnode **a_vpp;
877 struct vcache *vcp = VTOAFS(ap->a_vp);
879 AFS_STATCNT(afs_bmap);
881 ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
883 *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
888 afs_nbsd_strategy(ap)
889 struct vop_strategy_args /* {
893 struct buf *abp = ap->a_bp;
895 struct iovec tiovec[1];
896 struct vcache *tvc = VTOAFS(abp->b_vp);
897 struct ucred *credp = osi_curcred();
898 long len = abp->b_bcount;
901 AFS_STATCNT(afs_strategy);
903 tuio.afsio_iov = tiovec;
904 tuio.afsio_iovcnt = 1;
905 tuio.afsio_seg = AFS_UIOSYS;
906 tuio.afsio_resid = len;
907 tiovec[0].iov_base = abp->b_un.b_addr;
908 tiovec[0].iov_len = len;
910 if ((abp->b_flags & B_READ) == B_READ) {
911 code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
912 if (code == 0 && tuio.afsio_resid > 0)
913 bzero(abp->b_un.b_addr + len - tuio.afsio_resid, tuio.afsio_resid);
915 code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
917 ReleaseWriteLock(&tvc->lock);
918 AFS_RELE(AFSTOV(tvc));
924 struct vop_print_args /* {
928 struct vnode *vp = ap->a_vp;
929 struct vcache *vc = VTOAFS(ap->a_vp);
931 printf("tag %d, fid: %ld.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
932 (int) vc->fid.Fid.Volume, (int) vc->fid.Fid.Vnode, (int) vc->fid.Fid.Unique);
933 lockmgr_printinfo(&vc->rwlock);
939 afs_nbsd_islocked(ap)
940 struct vop_islocked_args /* {
944 return lockstatus(&VTOAFS(ap->a_vp)->rwlock);
948 * Return POSIX pathconf information applicable to ufs filesystems.
951 afs_nbsd_pathconf(ap)
952 struct vop_pathconf_args /* {
958 AFS_STATCNT(afs_cntl);
959 switch (ap->a_name) {
961 *ap->a_retval = LINK_MAX;
964 *ap->a_retval = NAME_MAX;
967 *ap->a_retval = PATH_MAX;
969 case _PC_CHOWN_RESTRICTED:
985 afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid);
988 * Advisory record locking support (fcntl() POSIX style)
992 struct vop_advlock_args /* {
1000 return afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),