openbsd-vnops-20030707
[openafs.git] / src / afs / OBSD / osi_vnodeops.c
index 3ea68b3..2748bb1 100644 (file)
@@ -1,11 +1,49 @@
 /*
+ * OpenBSD specific vnodeops + other misc interface glue
+ * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
+ * OpenBSD version by Jim Rees <rees@umich.edu>
+ *
+ * $Id$
+ */
+
+/*
+copyright 2002
+the regents of the university of michigan
+all rights reserved
+
+permission is granted to use, copy, create derivative works 
+and redistribute this software and such derivative works 
+for any purpose, so long as the name of the university of 
+michigan is not used in any advertising or publicity 
+pertaining to the use or distribution of this software 
+without specific, written prior authorization.  if the 
+above copyright notice or any other identification of the 
+university of michigan is included in any copy of any 
+portion of this software, then the disclaimer below must 
+also be included.
+
+this software is provided as is, without representation 
+from the university of michigan as to its fitness for any 
+purpose, and without warranty by the university of 
+michigan of any kind, either express or implied, including 
+without limitation the implied warranties of 
+merchantability and fitness for a particular purpose. the 
+regents of the university of michigan shall not be liable 
+for any damages, including special, indirect, incidental, or 
+consequential damages, with respect to any claim arising 
+out of or in connection with the use of the software, even 
+if it has been or is hereafter advised of the possibility of 
+such damages.
+*/
+
+/*
 Copyright 1995 Massachusetts Institute of Technology.  All Rights
 Reserved.
 
 You are hereby granted a worldwide, irrevocable, paid-up, right and
 license to use, execute, display, modify, copy and distribute MIT's
 Modifications, provided that (i) you abide by the terms and conditions
-of your Transarc AFS License Agreement, and (ii) you do not use the name
+of your OpenAFS License Agreement, and (ii) you do not use the name
 of MIT in any advertising or publicity without the prior written consent
 of MIT.  MIT disclaims all liability for your use of MIT's
 Modifications.  MIT's Modifications are provided "AS IS" WITHOUT
@@ -15,14 +53,6 @@ NONINFRINGEMENT.
 */
 
 /*
- * OpenBSD specific vnodeops + other misc interface glue
- * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
- * OpenBSD version by Jim Rees <rees@umich.edu>
- *
- * $Id$
- */
-
-/*
  * A bunch of code cribbed from NetBSD ufs_vnops.c, ffs_vnops.c, and
  * nfs_vnops.c which carry this copyright:
  */
@@ -81,7 +111,7 @@ RCSID("$Header$");
 #include "afs/nfsclient.h"
 #include "afs/afs_osidnlc.h"
 
-#ifdef DISCONN
+#ifdef AFS_DISCON_ENV
 extern int afs_FlushVS(struct vcache *tvc);
 #endif
 
@@ -138,7 +168,7 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
        { &vop_setattr_desc, afs_nbsd_setattr },        /* setattr */
        { &vop_read_desc, afs_nbsd_read },              /* read */
        { &vop_write_desc, afs_nbsd_write },            /* write */
-       { &vop_ioctl_desc, afs_nbsd_ioctl }, /* XXX ioctl */
+       { &vop_ioctl_desc, afs_nbsd_ioctl },            /* XXX ioctl */
        { &vop_select_desc, afs_nbsd_select },          /* select */
        { &vop_fsync_desc, afs_nbsd_fsync },            /* fsync */
        { &vop_remove_desc, afs_nbsd_remove },          /* remove */
@@ -178,16 +208,25 @@ struct vnodeopv_desc afs_vnodeop_opv_desc =
 
 int afs_debug;
 
-#define NBSD_WRITES_ALLOWED
-#ifndef NBSD_WRITES_ALLOWED
-int nbsd_writes_allowed = 0;
-#endif
-
 #undef vrele
 #define vrele afs_nbsd_rele
 #undef VREF
 #define VREF afs_nbsd_ref
 
+extern int afs_lookup();
+extern int afs_open();
+extern int afs_close();
+extern int HandleIoctl(struct vcache *avc, afs_int32 acom, struct afs_ioctl *adata);
+extern int afs_fsync();
+extern int afs_remove();
+extern int afs_link();
+extern int afs_rename();
+extern int afs_mkdir();
+extern int afs_rmdir();
+extern int afs_symlink();
+extern int afs_readdir();
+extern int afs_readlink();
+
 int
 afs_nbsd_lookup(ap)
 struct vop_lookup_args /* {
@@ -197,7 +236,7 @@ struct vop_lookup_args /* {
                          struct componentname *a_cnp;
                          } */ *ap;
 {
-    int error;
+    int code;
     struct vcache *vcp;
     struct vnode *vp, *dvp;
     int flags = ap->a_cnp->cn_flags;
@@ -207,31 +246,38 @@ struct vop_lookup_args /* {
     GETNAME();
     lockparent = flags & LOCKPARENT;
     wantparent = flags & (LOCKPARENT|WANTPARENT);
+#ifdef PDIRUNLOCK
+    cnp->cn_flags &= ~PDIRUNLOCK;
+#endif
 
     if (ap->a_dvp->v_type != VDIR) {
-       *ap->a_vpp = 0;
+       *ap->a_vpp = NULL;
        DROPNAME();
        return ENOTDIR;
     }
     dvp = ap->a_dvp;
     if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
        printf("nbsd_lookup dvp %p flags %x name %s cnt %d\n", dvp, flags, name, dvp->v_usecount);
-    error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
-    if (error) {
+    AFS_GLOCK();
+    code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
+    AFS_GUNLOCK();
+    if (code) {
        if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
-           (flags & ISLASTCN) && error == ENOENT)
-           error = EJUSTRETURN;
+           (flags & ISLASTCN) && code == ENOENT)
+           code = EJUSTRETURN;
        if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
            cnp->cn_flags |= SAVENAME;
        DROPNAME();
-       *ap->a_vpp = 0;
-       return (error);
+       *ap->a_vpp = NULL;
+       return (code);
     }
     vp = AFSTOV(vcp);                  /* always get a node if no error */
 
-    /* The parent directory comes in locked.  We unlock it on return
-       unless the caller wants it left locked.
-       we also always return the vnode locked. */
+    /*
+     * The parent directory comes in locked.  We unlock it on return
+     * unless the caller wants it left locked.
+     * we also always return the vnode locked.
+     */
 
     if (vp == dvp) {
        /* they're the same; afs_lookup() already ref'ed the leaf.
@@ -239,9 +285,13 @@ struct vop_lookup_args /* {
        if (afs_debug & AFSDEB_VNLAYER)
            printf("ref'ed %p as .\n", dvp);
     } else {
-       if (!lockparent || !(flags & ISLASTCN))
+       if (!lockparent || !(flags & ISLASTCN)) {
            VOP_UNLOCK(dvp, 0, curproc);                /* done with parent. */
-       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);                  /* always return the child locked */
+#ifdef PDIRUNLOCK
+           cnp->cn_flags |= PDIRUNLOCK;
+#endif
+       }
+       vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);  /* always return the child locked */
        if (afs_debug & AFSDEB_VNLAYER)
            printf("locked ret %p from lookup\n", vp);
     }
@@ -254,7 +304,7 @@ struct vop_lookup_args /* {
     DROPNAME();
     if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
        printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
-    return error;
+    return code;
 }
 
 int
@@ -266,7 +316,7 @@ afs_nbsd_create(ap)
                struct vattr *a_vap;
        } */ *ap;
 {
-    int error = 0;
+    int code = 0;
     struct vcache *vcp;
     struct vnode *dvp = ap->a_dvp;
     GETNAME();
@@ -276,19 +326,16 @@ afs_nbsd_create(ap)
 
     /* vnode layer handles excl/nonexcl */
 
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
+    AFS_GLOCK();
+    code = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL,
                       ap->a_vap->va_mode, &vcp,
                       cnp->cn_cred);
-    if (error) {
+    AFS_GUNLOCK();
+    if (code) {
        VOP_ABORTOP(dvp, cnp);
        vput(dvp);
        DROPNAME();
-       return(error);
+       return(code);
     }
 
     if (vcp) {
@@ -303,7 +350,7 @@ afs_nbsd_create(ap)
     DROPNAME();
     if (afs_debug & AFSDEB_VNLAYER)
        printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
-    return error;
+    return code;
 }
 
 int
@@ -329,14 +376,17 @@ afs_nbsd_open(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    int error;
+    int code;
     struct vcache *vc = VTOAFS(ap->a_vp);
-    error = afs_open(&vc, ap->a_mode, ap->a_cred);
+
+    AFS_GLOCK();
+    code = afs_open(&vc, ap->a_mode, ap->a_cred);
 #ifdef DIAGNOSTIC
     if (AFSTOV(vc) != ap->a_vp)
        panic("AFS open changed vnode!");
 #endif
-    return error;
+    AFS_GUNLOCK();
+    return code;
 }
 
 int
@@ -348,7 +398,12 @@ afs_nbsd_close(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    return afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p);
+    AFS_GUNLOCK();
+    return code;
 }
 
 int
@@ -360,8 +415,14 @@ afs_nbsd_access(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    return afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
 }
+
 int
 afs_nbsd_getattr(ap)
        struct vop_getattr_args /* {
@@ -371,8 +432,14 @@ afs_nbsd_getattr(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    return afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
 }
+
 int
 afs_nbsd_setattr(ap)
        struct vop_setattr_args /* {
@@ -382,8 +449,14 @@ afs_nbsd_setattr(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    return afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
 }
+
 int
 afs_nbsd_read(ap)
        struct vop_read_args /* {
@@ -393,8 +466,14 @@ afs_nbsd_read(ap)
                struct ucred *a_cred;
        } */ *ap;
 {
-    return afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0, 0, 0);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, (daddr_t)0, NULL, 0);
+    AFS_GUNLOCK();
+    return code;
 }
+
 int
 afs_nbsd_write(ap)
        struct vop_write_args /* {
@@ -404,13 +483,19 @@ afs_nbsd_write(ap)
                struct ucred *a_cred;
        } */ *ap;
 {
+    int code;
+
 #ifdef UVM
     (void) uvm_vnp_uncache(ap->a_vp);  /* toss stale pages */
 #else
     vnode_pager_uncache(ap->a_vp);
 #endif
-    return afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
+    AFS_GLOCK();
+    code = afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0);
+    AFS_GUNLOCK();
+    return code;
 }
+
 int
 afs_nbsd_ioctl(ap)
        struct vop_ioctl_args /* {
@@ -422,21 +507,20 @@ afs_nbsd_ioctl(ap)
                struct proc *a_p;
        } */ *ap;
 {
-    struct vcache *tvc = VTOAFS(ap->a_vp);
-    int error = 0;
+    int code;
 
     /* in case we ever get in here... */
 
     AFS_STATCNT(afs_ioctl);
-    if (((ap->a_command >> 8) & 0xff) == 'V') {
+    AFS_GLOCK();
+    if (((ap->a_command >> 8) & 0xff) == 'V')
        /* This is a VICEIOCTL call */
-       error = HandleIoctl(tvc, (struct file *)0/*Not used*/,
-                           ap->a_command, ap->a_data);
-       return(error);
-    } else {
+       code = HandleIoctl(VTOAFS(ap->a_vp), ap->a_command, (struct afs_ioctl *) ap->a_data);
+    else
        /* No-op call; just return. */
-       return(ENOTTY);
-    }
+       code = ENOTTY;
+    AFS_GUNLOCK();
+    return code;
 }
 
 /* ARGSUSED */
@@ -450,10 +534,10 @@ afs_nbsd_select(ap)
                struct proc *a_p;
        } */ *ap;
 {
-       /*
-        * We should really check to see if I/O is possible.
-        */
-       return (1);
+    /*
+     * We should really check to see if I/O is possible.
+     */
+    return (1);
 }
 
 int
@@ -467,8 +551,13 @@ afs_nbsd_fsync(ap)
 {
     int wait = ap->a_waitfor == MNT_WAIT;
     struct vnode *vp = ap->a_vp;
+    int code;
+
+    AFS_GLOCK();
     vflushbuf(vp, wait);
-    return afs_fsync(VTOAFS(vp), ap->a_cred);
+    code = afs_fsync(VTOAFS(vp), ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
 }
 
 int
@@ -479,17 +568,14 @@ afs_nbsd_remove(ap)
                struct componentname *a_cnp;
        } */ *ap;
 {
-    int error = 0;
+    int code;
     struct vnode *vp = ap->a_vp;
     struct vnode *dvp = ap->a_dvp;
 
     GETNAME();
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error =  afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GLOCK();
+    code =  afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
     if (dvp == vp)
        vrele(vp);
     else
@@ -497,7 +583,7 @@ afs_nbsd_remove(ap)
     vput(dvp);
     FREE(cnp->cn_pnbuf, M_NAMEI);
     DROPNAME();
-    return error;
+    return code;
 }
 
 int
@@ -508,38 +594,37 @@ afs_nbsd_link(ap)
                struct componentname *a_cnp;
        } */ *ap;
 {
-    int error = 0;
+    int code;
     struct vnode *dvp = ap->a_dvp;
     struct vnode *vp = ap->a_vp;
 
     GETNAME();
     if (dvp->v_mount != vp->v_mount) {
        VOP_ABORTOP(vp, cnp);
-       error = EXDEV;
+       code = EXDEV;
        goto out;
     }
     if (vp->v_type == VDIR) {
        VOP_ABORTOP(vp, cnp);
-       error = EISDIR;
+       code = EISDIR;
        goto out;
     }
-    if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
+    if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
        VOP_ABORTOP(dvp, cnp);
        goto out;
     }
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
+
+    AFS_GLOCK();
+    code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
     FREE(cnp->cn_pnbuf, M_NAMEI);
     if (dvp != vp)
        VOP_UNLOCK(vp, 0, curproc);
+
 out:
     vput(dvp);
     DROPNAME();
-    return error;
+    return code;
 }
 
 int
@@ -553,7 +638,7 @@ afs_nbsd_rename(ap)
                struct componentname *a_tcnp;
        } */ *ap;
 {
-    int error = 0;
+    int code = 0;
     struct componentname *fcnp = ap->a_fcnp;
     char *fname;
     struct componentname *tcnp = ap->a_tcnp;
@@ -568,7 +653,7 @@ afs_nbsd_rename(ap)
      */
     if ((fvp->v_mount != tdvp->v_mount) ||
        (tvp && (fvp->v_mount != tvp->v_mount))) {
-       error = EXDEV;
+       code = EXDEV;
 abortit:
        VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
        if (tdvp == tvp)
@@ -580,7 +665,7 @@ abortit:
        VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
        vrele(fdvp);
        vrele(fvp);
-       return (error);
+       return (code);
     }
     /*
      * if fvp == tvp, we're just removing one name of a pair of
@@ -589,7 +674,7 @@ abortit:
      */
     if (fvp == tvp) {
        if (fvp->v_type == VDIR) {
-           error = EINVAL;
+           code = EINVAL;
            goto abortit;
        }
 
@@ -610,7 +695,7 @@ abortit:
        return (VOP_REMOVE(fdvp, fvp, fcnp));
     }
 
-    if ((error = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
+    if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curproc)))
        goto abortit;
 
     MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK);
@@ -621,18 +706,15 @@ abortit:
     tname[tcnp->cn_namelen] = '\0';
 
 
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
+    AFS_GLOCK();
     /* XXX use "from" or "to" creds? NFS uses "to" creds */
-    error = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
+    code = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred);
+    AFS_GUNLOCK();
 
     VOP_UNLOCK(fvp, 0, curproc);
     FREE(fname, M_TEMP);
     FREE(tname, M_TEMP);
-    if (error)
+    if (code)
        goto abortit;                   /* XXX */
     if (tdvp == tvp)
        vrele(tdvp);
@@ -642,7 +724,7 @@ abortit:
        vput(tvp);
     vrele(fdvp);
     vrele(fvp);
-    return error;
+    return code;
 }
 
 int
@@ -656,7 +738,7 @@ afs_nbsd_mkdir(ap)
 {
     struct vnode *dvp = ap->a_dvp;
     struct vattr *vap = ap->a_vap;
-    int error = 0;
+    int code;
     struct vcache *vcp;
 
     GETNAME();
@@ -664,17 +746,14 @@ afs_nbsd_mkdir(ap)
     if ((cnp->cn_flags & HASBUF) == 0)
        panic("afs_nbsd_mkdir: no name");
 #endif
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
-    if (error) {
+    AFS_GLOCK();
+    code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred);
+    AFS_GUNLOCK();
+    if (code) {
        VOP_ABORTOP(dvp, cnp);
        vput(dvp);
        DROPNAME();
-       return(error);
+       return(code);
     }
     if (vcp) {
        *ap->a_vpp = AFSTOV(vcp);
@@ -684,7 +763,7 @@ afs_nbsd_mkdir(ap)
     DROPNAME();
     FREE(cnp->cn_pnbuf, M_NAMEI);
     vput(dvp);
-    return error;
+    return code;
 }
 
 int
@@ -695,7 +774,7 @@ afs_nbsd_rmdir(ap)
                struct componentname *a_cnp;
        } */ *ap;
 {
-    int error = 0;
+    int code;
     struct vnode *vp = ap->a_vp;
     struct vnode *dvp = ap->a_dvp;
 
@@ -708,16 +787,13 @@ afs_nbsd_rmdir(ap)
        return (EINVAL);
     }
 
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GLOCK();
+    code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
     DROPNAME();
     vput(dvp);
     vput(vp);
-    return error;
+    return code;
 }
 
 int
@@ -731,21 +807,18 @@ afs_nbsd_symlink(ap)
        } */ *ap;
 {
     struct vnode *dvp = ap->a_dvp;
-    int error = 0;
+    int code;
     /* NFS ignores a_vpp; so do we. */
 
     GETNAME();
-#ifndef NBSD_WRITES_ALLOWED
-    if (!nbsd_writes_allowed)
-       error = EROFS;
-    if (!error)
-#endif
-    error = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
+    AFS_GLOCK();
+    code = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
                        cnp->cn_cred);
+    AFS_GUNLOCK();
     DROPNAME();
     FREE(cnp->cn_pnbuf, M_NAMEI);
     vput(dvp);
-    return error;
+    return code;
 }
 
 int
@@ -759,10 +832,19 @@ afs_nbsd_readdir(ap)
                u_long **a_cookies;
        } */ *ap;
 {
-/*    printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
-          ap->a_ncookies); */
-    return afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
+    int code;
+
+    AFS_GLOCK();
+#ifdef AFS_HAVE_COOKIES
+    printf("readdir %p cookies %p ncookies %d\n", ap->a_vp, ap->a_cookies,
+          ap->a_ncookies);
+    code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred,
                       ap->a_eofflag, ap->a_ncookies, ap->a_cookies);
+#else
+    code = afs_readdir(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, ap->a_eofflag);
+#endif
+    AFS_GUNLOCK();
+    return code;
 }
 
 int
@@ -773,8 +855,12 @@ afs_nbsd_readlink(ap)
                struct ucred *a_cred;
        } */ *ap;
 {
-/*    printf("readlink %p\n", ap->a_vp);*/
-    return afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
+    int code;
+
+    AFS_GLOCK();
+    code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
 }
 
 extern int prtactive;
@@ -787,14 +873,18 @@ afs_nbsd_inactive(ap)
 {
     struct vnode *vp = ap->a_vp;
     struct vcache *vc = VTOAFS(vp);
+    int haveGlock = ISAFS_GLOCK();
 
     AFS_STATCNT(afs_inactive);
 
     if (prtactive && vp->v_usecount != 0)
        vprint("afs_nbsd_inactive(): pushing active", vp);
 
-    vc->states &= ~CMAPPED;
-    vc->states &= ~CDirty;
+    if (!haveGlock)
+       AFS_GLOCK();
+    afs_InactiveVCache(vc, 0);   /* decrs ref counts */
+    if (!haveGlock)
+       AFS_GUNLOCK();
 
     lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
     return 0;
@@ -806,26 +896,27 @@ afs_nbsd_reclaim(ap)
                struct vnode *a_vp;
        } */ *ap;
 {
-    int error, slept;
+    int code, slept;
     struct vnode *vp = ap->a_vp;
     struct vcache *avc = VTOAFS(vp);
-
-    cache_purge(vp);                   /* just in case... */
-#ifdef UVM
-    uvm_vnp_uncache(vp);
-#else
-    vnode_pager_uncache(vp);
-#endif
-
-#ifndef DISCONN
-    error = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
+    int haveGlock = ISAFS_GLOCK();
+    int haveVlock = CheckLock(&afs_xvcache);
+
+    if (!haveGlock)
+       AFS_GLOCK();
+    if (!haveVlock)
+       ObtainWriteLock(&afs_xvcache, 901);
+#ifndef AFS_DISCON_ENV
+    code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */
 #else
     /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */
-    error = afs_FlushVS(avc);
+    code = afs_FlushVS(avc);
 #endif
-    if (!error && vp->v_data)
-       panic("afs_reclaim: vnode not cleaned");
-    return error;
+    if (!haveVlock)
+       ReleaseWriteLock(&afs_xvcache);
+    if (!haveGlock)
+       AFS_GUNLOCK();
+    return code;
 }
 
 int
@@ -839,10 +930,8 @@ afs_nbsd_lock(ap)
     struct vnode *vp = ap->a_vp;
     struct vcache *vc = VTOAFS(vp);
 
-#ifdef DIAGNOSTIC
     if (!vc)
        panic("afs_nbsd_lock: null vcache");
-#endif
     return lockmgr(&vc->rwlock, ap->a_flags | LK_CANRECURSE, &vp->v_interlock, ap->a_p);
 }
 
@@ -857,10 +946,8 @@ afs_nbsd_unlock(ap)
     struct vnode *vp = ap->a_vp;
     struct vcache *vc = VTOAFS(vp);
 
-#ifdef DIAGNOSTIC
     if (!vc)
        panic("afs_nbsd_unlock: null vcache");
-#endif
     return lockmgr(&vc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock, ap->a_p);
 }
 
@@ -878,7 +965,7 @@ afs_nbsd_bmap(ap)
 
     AFS_STATCNT(afs_bmap);
     if (ap->a_bnp)
-       ap->a_bnp = ap->a_bn * (8192 / DEV_BSIZE);
+       ap->a_bnp = (daddr_t *) (ap->a_bn * (8192 / DEV_BSIZE));
     if (ap->a_vpp)
        *ap->a_vpp = (vcp) ? AFSTOV(vcp) : NULL;
     return 0;
@@ -907,12 +994,14 @@ afs_nbsd_strategy(ap)
     tiovec[0].iov_base = abp->b_un.b_addr;
     tiovec[0].iov_len = len;
 
+    AFS_GLOCK();
     if ((abp->b_flags & B_READ) == B_READ) {
        code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp);
        if (code == 0 && tuio.afsio_resid > 0)
            bzero(abp->b_un.b_addr + len - tuio.afsio_resid, tuio.afsio_resid);
     } else
        code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp);
+    AFS_GUNLOCK();
 
     ReleaseWriteLock(&tvc->lock);
     AFS_RELE(AFSTOV(tvc));
@@ -928,7 +1017,7 @@ afs_nbsd_print(ap)
     struct vnode *vp = ap->a_vp;
     struct vcache *vc = VTOAFS(ap->a_vp);
 
-    printf("tag %d, fid: %ld.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
+    printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->fid.Cell,
           (int) vc->fid.Fid.Volume, (int) vc->fid.Fid.Vnode, (int) vc->fid.Fid.Unique);
     lockmgr_printinfo(&vc->rwlock);
     printf("\n");
@@ -957,30 +1046,33 @@ afs_nbsd_pathconf(ap)
 {
     AFS_STATCNT(afs_cntl);
     switch (ap->a_name) {
-      case _PC_LINK_MAX:
+    case _PC_LINK_MAX:
        *ap->a_retval = LINK_MAX;
        break;
-      case _PC_NAME_MAX:
+    case _PC_NAME_MAX:
        *ap->a_retval = NAME_MAX;
        break;
-      case _PC_PATH_MAX:
+    case _PC_PATH_MAX:
        *ap->a_retval = PATH_MAX;
        break;
-      case _PC_CHOWN_RESTRICTED:
+    case _PC_CHOWN_RESTRICTED:
        *ap->a_retval = 1;
        break;
-      case _PC_NO_TRUNC:
+    case _PC_NO_TRUNC:
        *ap->a_retval = 1;
        break;
-      case _PC_PIPE_BUF:
+    case _PC_PIPE_BUF:
        return EINVAL;
        break;
-      default:
+    default:
        return EINVAL;
     }
     return 0;
 }
 
+extern int
+afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd, struct AFS_UCRED *acred, pid_t clid);
+
 /*
  * Advisory record locking support (fcntl() POSIX style)
  */
@@ -994,6 +1086,11 @@ afs_nbsd_advlock(ap)
                int  a_flags;
        } */ *ap;
 {
-    return afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),
+    int code;
+
+    AFS_GLOCK();
+    code = afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(),
                       (int) ap->a_id);
+    AFS_GUNLOCK();
+    return code;
 }