netbsd: rebase cm at NetBSD 4.0
authorMatt Benjmain <matt@linuxbox.com>
Wed, 28 Apr 2010 10:19:16 +0000 (06:19 -0400)
committerDerrick Brashear <shadow@dementia.org>
Wed, 28 Apr 2010 20:47:20 +0000 (13:47 -0700)
Rebases the NetBSD client port at OpenBSD, which was originally
based on an original NetBSD client port by John Kohl.  The
platforms remain closely connected.

At latest milestone, the port builds as a NetBSD LKM, which was
loadable and can mount /afs (but much work remains past this
point).

Change-Id: I1381a60078794da03a82e7bf6e78127da82d61ee
Change-Id: I8e07e82796f6981c99d22ff50dd5b284aad88a9f
Reviewed-on: http://gerrit.openafs.org/1874
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

42 files changed:
acinclude.m4
src/afs/NBSD/osi_file.c [new file with mode: 0644]
src/afs/NBSD/osi_gcpags.c [moved from src/afs/NBSD/placeholder with 100% similarity]
src/afs/NBSD/osi_groups.c [new file with mode: 0644]
src/afs/NBSD/osi_inode.c [new file with mode: 0644]
src/afs/NBSD/osi_inode.h [new file with mode: 0644]
src/afs/NBSD/osi_machdep.h [new file with mode: 0644]
src/afs/NBSD/osi_misc.c [new file with mode: 0644]
src/afs/NBSD/osi_prototypes.h [new file with mode: 0644]
src/afs/NBSD/osi_sleep.c [new file with mode: 0644]
src/afs/NBSD/osi_vfs.h [new file with mode: 0644]
src/afs/NBSD/osi_vfsops.c [new file with mode: 0644]
src/afs/NBSD/osi_vm.c [new file with mode: 0644]
src/afs/NBSD/osi_vnodeops.c [new file with mode: 0644]
src/afs/VNOPS/afs_vnop_attrs.c
src/afs/VNOPS/afs_vnop_fid.c
src/afs/VNOPS/afs_vnop_read.c
src/afs/VNOPS/afs_vnop_readdir.c
src/afs/VNOPS/afs_vnop_strategy.c
src/afs/VNOPS/afs_vnop_write.c
src/afs/afs.h
src/afs/afs_init.c
src/afs/afs_osi.c
src/afs/afs_osi.h
src/afs/afs_osi_alloc.c
src/afs/afs_osi_pag.c
src/afs/afs_pioctl.c
src/afs/afs_prototypes.h
src/afs/afs_server.c
src/afs/afs_syscall.c
src/afs/afs_vcache.c
src/afs/afsincludes.h
src/afs/lock.h
src/afs/sysincludes.h
src/afsd/afsd_kernel.c
src/config/param.nbsd40.h
src/config/stds.h
src/libafs/MakefileProto.NBSD.in
src/rx/NBSD/rx_kmutex.h
src/rx/NBSD/rx_knet.c
src/rx/rx_kcommon.c
src/rx/rx_kcommon.h

index 7aaef2a..9cf3a60 100644 (file)
@@ -1117,6 +1117,8 @@ else
                *_fbsd_*)
                        BSD_KERNEL_BUILD="${BSD_KERNEL_PATH}/${HOST_CPU}/compile/GENERIC"
                        ;;
+               *_nbsd*)
+                       BSD_KERNEL_BUILD="${BSD_KERNEL_PATH}/arch/${HOST_CPU}/compile/GENERIC"
        esac
 fi
 
diff --git a/src/afs/NBSD/osi_file.c b/src/afs/NBSD/osi_file.c
new file mode 100644 (file)
index 0000000..8c93145
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* afs statistics */
+
+
+int afs_osicred_initialized;
+afs_ucred_t afs_osi_cred;
+afs_lock_t afs_xosi;           /* lock is for tvattr */
+extern struct osi_dev cacheDev;
+extern struct mount *afs_cacheVfsp;
+
+void *
+osi_UFSOpen(afs_dcache_id_t *ainode)
+{
+    struct osi_file *afile;
+    struct vnode *vp;
+    extern int cacheDiskType;
+    afs_int32 code;
+
+    AFS_STATCNT(osi_UFSOpen);
+    if (cacheDiskType != AFS_FCACHE_TYPE_UFS)
+       osi_Panic("UFSOpen called for non-UFS cache\n");
+    afile = (struct osi_file *)osi_AllocSmallSpace(sizeof(struct osi_file));
+    AFS_GUNLOCK();
+    code = VFS_VGET(cacheDev.mp, (ino_t) ainode->ufs, &vp);
+    AFS_GLOCK();
+    if (code == 0 && vp->v_type == VNON)
+       code = ENOENT;
+    if (code) {
+       osi_FreeSmallSpace(afile);
+       osi_Panic("UFSOpen: igetinode failed");
+    }
+    VOP_UNLOCK(vp, 0);
+    afile->vnode = vp;
+    afile->size = VTOI(vp)->i_ffs1_size;
+    afile->offset = 0;
+    afile->proc = NULL;
+    return (void *)afile;
+}
+
+int
+afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
+{
+    afs_int32 code;
+    struct vattr tvattr;
+
+    AFS_STATCNT(osi_Stat);
+    MObtainWriteLock(&afs_xosi, 320);
+    AFS_GUNLOCK();
+    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp,
+                      osi_curproc());
+    AFS_GLOCK();
+    if (code == 0) {
+       astat->size = afile->size = tvattr.va_size;
+       astat->mtime = tvattr.va_mtime.tv_sec;
+       astat->atime = tvattr.va_atime.tv_sec;
+    }
+    MReleaseWriteLock(&afs_xosi);
+    return code;
+}
+
+int
+osi_UFSClose(struct osi_file *afile)
+{
+    AFS_STATCNT(osi_Close);
+
+    if (afile->vnode)
+       AFS_RELE(afile->vnode);
+
+    osi_FreeSmallSpace(afile);
+    return 0;
+}
+
+int
+osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
+{
+    struct vattr tvattr;
+    afs_int32 code;
+    struct osi_stat tstat;
+
+    AFS_STATCNT(osi_Truncate);
+
+    /*
+     * This routine only shrinks files, and most systems
+     * have very slow truncates, even when the file is already
+     * small enough.  Check now and save some time.
+     */
+    code = afs_osi_Stat(afile, &tstat);
+    if (code || tstat.size <= asize)
+       return code;
+
+    MObtainWriteLock(&afs_xosi, 321);
+    VATTR_NULL(&tvattr);
+    tvattr.va_size = asize;
+    AFS_GUNLOCK();
+    VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY);
+    code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp,
+                      osi_curproc());
+    VOP_UNLOCK(afile->vnode, 0);
+    AFS_GLOCK();
+    if (code == 0)
+       afile->size = asize;
+    MReleaseWriteLock(&afs_xosi);
+    return code;
+}
+
+void
+osi_DisableAtimes(struct vnode *avp)
+{
+#if 0
+    VTOI(avp)->i_flag &= ~IN_ACCESS;
+#endif
+}
+
+
+/* Generic read interface */
+int
+afs_osi_Read(struct osi_file *afile, int offset, void *aptr, afs_int32 asize)
+{
+    unsigned int resid;
+    afs_int32 code;
+
+    AFS_STATCNT(osi_Read);
+
+    /*
+     * If the osi_file passed in is NULL, panic only if AFS is not shutting
+     * down. No point in crashing when we are already shutting down
+     */
+    if (!afile) {
+       if (!afs_shuttingdown)
+           osi_Panic("osi_Read called with null param");
+       else
+           return EIO;
+    }
+
+    if (offset != -1)
+       afile->offset = offset;
+    AFS_GUNLOCK();
+    code =
+       vn_rdwr(UIO_READ, afile->vnode, aptr, asize, afile->offset,
+               AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid,
+               osi_curproc());
+    AFS_GLOCK();
+    if (code == 0) {
+       code = asize - resid;
+       afile->offset += code;
+       osi_DisableAtimes(afile->vnode);
+    } else {
+       afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid,
+                  ICL_TYPE_INT32, code);
+       code = -1;
+    }
+    return code;
+}
+
+/* Generic write interface */
+int
+afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
+             afs_int32 asize)
+{
+    unsigned int resid;
+    afs_int32 code;
+
+    AFS_STATCNT(osi_Write);
+    if (!afile)
+       osi_Panic("afs_osi_Write called with null afile");
+    if (offset != -1)
+       afile->offset = offset;
+
+    AFS_GUNLOCK();
+    VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY);
+    code =
+       vn_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset,
+               AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid, osi_curproc());
+    VOP_UNLOCK(afile->vnode, 0);
+    AFS_GLOCK();
+
+    if (code == 0) {
+       code = asize - resid;
+       afile->offset += code;
+       if (afile->offset > afile->size)
+           afile->size = afile->offset;
+    } else
+       code = -1;
+
+    if (afile->proc)
+       (*afile->proc) (afile, code);
+
+    return code;
+}
+
+/*
+ * This work should be handled by physstrat in ca/machdep.c.  This routine
+ * written from the RT NFS port strategy routine.  It has been generalized a
+ * bit, but should still be pretty clear.
+ */
+int
+afs_osi_MapStrategy(int (*aproc) (), struct buf *bp)
+{
+    afs_int32 returnCode;
+
+    AFS_STATCNT(osi_MapStrategy);
+    returnCode = (*aproc) (bp);
+
+    return returnCode;
+}
+
+void
+shutdown_osifile(void)
+{
+    AFS_STATCNT(shutdown_osifile);
+    if (afs_cold_shutdown)
+       afs_osicred_initialized = 0;
+}
diff --git a/src/afs/NBSD/osi_groups.c b/src/afs/NBSD/osi_groups.c
new file mode 100644 (file)
index 0000000..307973a
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * osi_groups.c
+ *
+ * Implements:
+ * Afs_xsetgroups (syscall)
+ * setpag
+ *
+ */
+#include <afsconfig.h>
+#include "afs/param.h"
+
+
+#include "afs/sysincludes.h"
+#include "afs/afsincludes.h"
+#include "afs/afs_stats.h"     /* statistics */
+#include "sys/syscallargs.h"
+
+#define NOUID   ((uid_t) -1)
+#define NOGID   ((gid_t) -1)
+
+/*
+ * NetBSD has a very flexible and elegant replacement for Unix
+ * groups KPIs, see KAUTH(9).
+ *
+ */
+
+static int
+osi_getgroups(kauth_cred_t cred, int ngroups, gid_t * gidset);
+
+
+/* why **? are we returning or reallocating creat? */
+static int
+osi_setgroups(struct proc *proc, kauth_cred_t *cred, int ngroups,
+             gid_t * gidset, int change_parent);
+
+int
+Afs_xsetgroups(struct proc *p, void *args, int *retval)
+{
+    int code = 0;
+    struct vrequest treq;
+    kauth_cred_t cred = osi_proccred(p);
+
+    AFS_STATCNT(afs_xsetgroups);
+
+    AFS_GLOCK();
+    code = afs_InitReq(&treq, (afs_ucred_t *) cred);
+    AFS_GUNLOCK();
+
+    if (code)
+       return code;
+
+    /*
+     * XXX Does treq.uid == osi_crgetruid(cred)?
+     */
+
+    code = kauth_cred_setgroups(cred, args, retval, osi_crgetruid(cred));
+    /*
+     * Note that if there is a pag already in the new groups we don't
+     * overwrite it with the old pag.
+     */
+    if (PagInCred(cred) == NOPAG) {
+       if (((treq.uid >> 24) & 0xff) == 'A') {
+           AFS_GLOCK();
+           /* we've already done a setpag, so now we redo it */
+           AddPag(p, treq.uid, &cred);
+           AFS_GUNLOCK();
+       }
+    }
+    return code;
+}
+
+
+int
+setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue,
+       afs_uint32 * newpag, int change_parent)
+{
+    gid_t gidset[NGROUPS];
+    int ngroups, code;
+    int j;
+
+    AFS_STATCNT(setpag);
+    ngroups = osi_getgroups(*cred, NGROUPS, gidset);
+    if (afs_get_pag_from_groups(gidset[1], gidset[2]) == NOPAG) {
+       /* We will have to shift grouplist to make room for pag */
+       if (ngroups + 2 > NGROUPS) {
+           return (E2BIG);
+       }
+       for (j = ngroups - 1; j >= 0; j--) {
+           gidset[j + 2] = gidset[j];
+       }
+       ngroups += 2;
+    }
+    *newpag = (pagvalue == -1 ? genpag() : pagvalue);
+    afs_get_groups_from_pag(*newpag, &gidset[1], &gidset[2]);
+    code = osi_setgroups(proc, cred, ngroups, gidset, change_parent);
+    return code;
+}
+
+
+static int
+osi_getgroups(kauth_cred_t cred, int ngroups, gid_t * gidset)
+{
+    int ngrps, savengrps;
+    struct kauth_cred *cr;
+    gid_t *gp;
+
+    AFS_STATCNT(afs_getgroups);
+
+    cr = (struct kauth_cred *) cred;
+    savengrps = ngrps = MIN(ngroups, kauth_cred_ngroups(cred));
+    gp = cred->cr_groups;
+    while (ngrps--)
+       *gidset++ = *gp++;
+    return savengrps;
+}
+
+
+static int
+osi_setgroups(struct proc *proc, kauth_cred_t *cred, int ngroups,
+             gid_t * gidset, int change_parent)
+{
+    int i;
+    struct kauth_cred *cr;
+
+    AFS_STATCNT(afs_setgroups); /* XXX rename statcnt */
+
+    if (ngroups > NGROUPS)
+       return EINVAL;
+
+    cr = (struct kauth_cred *) *cred;
+    if (!change_parent)
+       cr = kauth_cred_copy(cr);
+
+    for (i = 0; i < ngroups; i++)
+       cr->cr_groups[i] = gidset[i];
+    for (i = ngroups; i < NGROUPS; i++)
+       cr->cr_groups[i] = NOGROUP;
+    cr->cr_ngroups = ngroups;
+
+    *cred = cr;
+    return (0);
+}
diff --git a/src/afs/NBSD/osi_inode.c b/src/afs/NBSD/osi_inode.c
new file mode 100644 (file)
index 0000000..4e48584
--- /dev/null
@@ -0,0 +1,8 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
diff --git a/src/afs/NBSD/osi_inode.h b/src/afs/NBSD/osi_inode.h
new file mode 100644 (file)
index 0000000..4152721
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/* $Id: osi_inode.h,v 1.2 2002/11/15 17:19:40 rees Exp $ */
diff --git a/src/afs/NBSD/osi_machdep.h b/src/afs/NBSD/osi_machdep.h
new file mode 100644 (file)
index 0000000..2cd67e8
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ *
+ * OpenBSD OSI header file. Extends afs_osi.h.
+ *
+ * afs_osi.h includes this file, which is the only way this file should
+ * be included in a source file. This file can redefine macros declared in
+ * afs_osi.h.
+ */
+
+#ifndef _OSI_MACHDEP_H_
+#define _OSI_MACHDEP_H_
+
+#define RXK_LISTENER_ENV 1
+#define AFS_DIRENT 1
+
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/syscall.h>
+#include <sys/syscallargs.h>
+
+#include "opt_ddb.h" /* Debugger() */
+
+#define M_AFSFID       (M_TEMP-1)
+#define M_AFSBUFHDR    (M_TEMP-2)
+#define M_AFSBUFFER    (M_TEMP-3)
+#define M_AFSGENERIC   (M_TEMP-4)
+
+/* vfs */
+#define osi_vfs                mount
+#define osi_vfs_bsize  mnt_stat.f_bsize
+#define osi_vfs_iosize mnt_stat.f_iosize
+#define osi_vfs_fsid   mnt_stat.f_fsid
+#if 0
+#define vfs_bsize      mnt_stat.f_bsize
+#define vfs_fsid       mnt_stat.f_fsid
+#endif
+#define vfs_vnodecovered mnt_vnodecovered
+#define v_vfsp         v_mount
+#define VFS_STATFS      afs_statvfs
+
+int
+sys_ioctl(struct lwp *l, void *v, register_t *retval);
+
+/* vnode */
+#define VN_HOLD(vp)    (vref(vp))
+#define VN_RELE(vp)    (vrele(vp))
+#define osi_vnhold(avc, r) (VN_HOLD(AFSTOV(avc)))
+
+
+#define va_nodeid      va_fileid
+#define vnode_t                struct vnode
+
+/* syscall */
+struct afs_sysargs {
+    syscallarg(long) syscall;
+    syscallarg(long) parm1;
+    syscallarg(long) parm2;
+    syscallarg(long) parm3;
+    syscallarg(long) parm4;
+    syscallarg(long) parm5;
+    syscallarg(long) parm6;
+};
+
+/* uio */
+#define afsio_iov      uio_iov
+#define afsio_iovcnt   uio_iovcnt
+#define afsio_offset   uio_offset
+#define afsio_resid    uio_resid
+#define afsio_seg      uio_segflg
+#define AFS_UIOSYS     UIO_SYSSPACE
+#define AFS_UIOUSER    UIO_USERSPACE
+
+/* malloc */
+inline void * afs_osi_Alloc(size_t asize);
+inline void * afs_osi_Alloc_NoSleep(size_t asize);
+inline void afs_osi_Free(void *buf, size_t asize);
+inline void afs_osi_FreeStr(char *x);
+extern void *osi_nbsd_Alloc(size_t asize, int cansleep);
+extern void osi_nbsd_Free(void *p, size_t asize);
+
+#ifdef AFS_KALLOC
+#undef AFS_KALLOC
+#define AFS_KALLOC(s) (osi_nbsd_Alloc((s), 1 /* cansleep */))
+#endif
+
+#ifdef AFS_KFREE
+#undef AFS_KFREE
+#define AFS_KFREE(p, s) (osi_nbsd_Free((p), (s)))
+#endif
+
+/* proc */
+typedef struct lwp afs_proc_t;
+#define osi_curproc()  curlwp
+#define getpid()       (osi_curproc())->l_proc->p_pid
+
+/*
+ * XXX  I'm exporting the internal definition of kauth_cred_t
+ * until I work out protocol for switching group buffers.
+ * Matt.
+ */
+
+#define KAUTH_EXPORT 1
+#if defined(KAUTH_EXPORT)
+/* internal type from kern_auth.c */
+#ifdef AFS_NBSD40_ENV
+struct kauth_cred {
+       struct simplelock cr_lock;      /* lock on cr_refcnt */
+       u_int cr_refcnt;                /* reference count */
+       uid_t cr_uid;                   /* user id */
+       uid_t cr_euid;                  /* effective user id */
+       uid_t cr_svuid;                 /* saved effective user id */
+       gid_t cr_gid;                   /* group id */
+       gid_t cr_egid;                  /* effective group id */
+       gid_t cr_svgid;                 /* saved effective group id */
+       u_int cr_ngroups;               /* number of groups */
+       gid_t cr_groups[NGROUPS];       /* group memberships */
+};
+#else
+#error TODO:  verify kauth_cred structure, if this is still here
+#endif /* AFS_NBSD40_ENV */
+#endif /* KAUTH_EXPORT */
+
+typedef kauth_cred_t afs_ucred_t;
+#define osi_curcred()  (kauth_cred_get())
+#define afs_suser(x)   afs_osi_suser(osi_curcred())
+#define osi_crgetruid(acred) (kauth_cred_getuid(acred))
+#define osi_crgetrgid(acred) (kauth_cred_getgid(acred))
+#define osi_crngroups(acred) (kauth_cred_ngroups(acred))
+#define osi_proccred(aproc) (aproc->p_cred)
+#define osi_crdup(acred) (kauth_cred_dup(acred))
+#define crref osi_crdup
+#define crdup osi_crdup
+#define crhold crref
+#define crfree kauth_cred_free
+
+#define afs_cr_gid osi_crgetrgid
+#define afs_cr_uid osi_crgetruid
+
+inline gid_t osi_crgroupbyid(afs_ucred_t *acred, int gindex);
+
+/* time */
+#define        afs_hz          hz
+#define osi_GetTime(x) microtime(x)
+#define osi_Time()      time_second
+
+/* str */
+#define afs_strcasecmp(s1, s2) strncasecmp((s1), (s2), 65535)
+#define afs_strcat(s1, s2)     strcat((s1), (s2))
+
+/* other */
+#define afs_bufferpages bufpages
+#ifndef iodone
+#define iodone biodone
+#endif
+#define printk         printf  /* for RX version of xdr_* */
+#define setgroups      sys_setgroups
+#define UVM
+
+/* This is not always in scope yet */
+struct vcache;
+
+extern int afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg,
+                              int followlink, struct vnode **compvpp);
+extern void afs_nbsd_getnewvnode(struct vcache *tvc);
+extern int afs_vget();
+
+#undef gop_lookupname
+#undef gop_lookupname_user
+#define        osi_lookupname_user(fnamep, segflg, followlink, compvpp) \
+       afs_nbsd_lookupname((fnamep), (segflg), (followlink), (compvpp))
+#define gop_lookupname_user osi_lookupname_user
+#define gop_lookupname osi_lookupname_user
+
+#ifdef KERNEL
+#ifdef AFS_GLOBAL_SUNLOCK
+extern struct lock afs_global_lock;
+
+#if defined(LOCKDEBUG)
+#define AFS_GLOCK() \
+  do { \
+      _lockmgr(&afs_global_lock, LK_EXCLUSIVE, NULL, __FILE__, __LINE__); \
+  } while(0);
+#define AFS_GUNLOCK() \
+  do { \
+      _lockmgr(&afs_global_lock, LK_RELEASE, NULL, __FILE__, __LINE__); \
+  } while(0);
+#else
+#define AFS_GLOCK() \
+  do { \
+    lockmgr(&afs_global_lock, LK_EXCLUSIVE, NULL); \
+  } while(0);
+#define AFS_GUNLOCK() \
+  do { \
+    lockmgr(&afs_global_lock, LK_RELEASE, NULL); \
+  } while(0);
+#endif /* LOCKDEBUG */
+#define ISAFS_GLOCK() (lockstatus(&afs_global_lock) == LK_EXCLUSIVE)
+#else
+extern struct lock afs_global_lock;
+#define AFS_GLOCKP(p)
+#define AFS_GUNLOCKP(p)
+#define AFS_ASSERT_GLOCK()
+#define ISAFS_GLOCK() 1
+#endif
+
+#undef SPLVAR
+#define SPLVAR int splvar
+#undef NETPRI
+#define NETPRI splvar=splnet()
+#undef USERPRI
+#define USERPRI splx(splvar)
+#endif /* KERNEL */
+
+#if    !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__) && !defined(IGNORE_STDS_H)
+enum vcexcl { NONEXCL, EXCL };
+
+#ifndef MIN
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#endif
+#ifndef MAX
+#define MAX(A,B) ((A) > (B) ? (A) : (B))
+#endif
+
+#endif /* ASSEMBLER */
+
+/* vnodes */
+extern int (**afs_vnodeop_p) ();
+#define vType(vc)               AFSTOV(vc)->v_type
+#define vSetVfsp(vc, vfsp)      AFSTOV(vc)->v_mount = (vfsp)
+#define vSetType(vc, type)      AFSTOV(vc)->v_type = (type)
+#define IsAfsVnode(v)      ((v)->v_op == afs_vnodeop_p)
+#define SetAfsVnode(v)     /* nothing; done in getnewvnode() */
+
+#endif /* _OSI_MACHDEP_H_ */
diff --git a/src/afs/NBSD/osi_misc.c b/src/afs/NBSD/osi_misc.c
new file mode 100644 (file)
index 0000000..50ed099
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * osi_misc.c
+ *
+ * $Id: osi_misc.c,v 1.4 2003/10/09 16:13:16 rees Exp $
+ */
+
+/*
+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 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+
+/*
+ * afs_suser() returns true if the caller is superuser, false otherwise.
+ *
+ * Note that it must NOT set errno.
+ */
+
+/*
+ * Modern NetBSD version of afs_osi_suser().  For cognate code calling
+ * traditional BSD suser, see OBSD/osi_misc.c.
+ */
+int
+afs_osi_suser(void *credp)
+{
+    int code;
+    code = kauth_authorize_generic(credp,
+                                  KAUTH_GENERIC_ISSUSER,
+                                  &curlwp->l_acflag);
+    return (code == 0);
+}
+
+/*
+ * Support Alloc_NoSleep.  This should propagate back to OBSD.
+ * Matt.
+ */
+void *
+osi_nbsd_Alloc(size_t asize, int cansleep)
+{
+    void *p;
+    int glocked;
+
+    if (cansleep) {
+       glocked = ISAFS_GLOCK();
+       if (glocked)
+           AFS_GUNLOCK();
+       MALLOC(p, void *, asize, M_AFSGENERIC, M_WAITOK);
+       if (glocked)
+           AFS_GLOCK();
+    } else {
+       MALLOC(p, void *, asize, M_AFSGENERIC, M_NOWAIT);
+    }
+
+    return (p);
+}
+
+void
+osi_nbsd_Free(void *p, size_t asize)
+{
+    FREE(p, M_AFSGENERIC);
+}
+
+inline void *
+afs_osi_Alloc(size_t asize) {
+    return (osi_nbsd_Alloc(asize, 1));
+}
+
+inline void *
+afs_osi_Alloc_NoSleep(size_t asize) {
+    return (osi_nbsd_Alloc(asize, 0));
+}
+
+inline void
+afs_osi_Free(void *buf, size_t asize) {
+    osi_nbsd_Free(buf, asize);
+}
+
+inline void
+afs_osi_FreeStr(char *x)
+{
+    afs_osi_Free(x, strlen(x) + 1);
+}
+
+/* XXXX OpenBSD avoids space pool, presumably Rees believed the kernel
+ * allocator did as well or better */
+#if 0
+void
+osi_FreeLargeSpace(void *p)
+{
+    osi_nbsd_Free(p, 0);
+}
+
+/* XXXX OpenBSD avoids space pool, presumably Rees believed the kernel
+ * allocator did as well or better */
+#if 0
+void
+osi_FreeSmallSpace(void *p)
+{
+    osi_nbsd_Free(p, 0);
+}
+
+void *
+osi_AllocLargeSpace(size_t size)
+{
+    AFS_ASSERT_GLOCK();
+    AFS_STATCNT(osi_AllocLargeSpace);
+    return (osi_nbsd_Alloc(size, 1));
+}
+
+void *
+osi_AllocSmallSpace(size_t size)
+{
+    AFS_ASSERT_GLOCK();
+    AFS_STATCNT(osi_AllocSmallSpace);
+    return (osi_nbsd_Alloc(size, 1));
+}
+
+#endif /* Space undef */
+
+int
+afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval)
+    long *retval;
+    long dev, near_inode, param1, param2, param3, param4;
+{
+    return EINVAL;
+}
+
+#endif /* Space undef */
+
+int
+afs_syscall_iopen(dev, inode, usrmod, retval)
+    long *retval;
+    int dev, inode, usrmod;
+{
+    return EINVAL;
+}
+
+int
+afs_syscall_iincdec(dev, inode, inode_p1, amount)
+     int dev, inode, inode_p1, amount;
+{
+    return EINVAL;
+}
+
+inline gid_t
+osi_crgroupbyid(afs_ucred_t *acred, int gindex)
+{
+    struct kauth_cred *cr = acred;
+    return (cr->cr_groups[gindex]);
+}
+
+/*
+ * just calls kern_time.c:settime()
+ */
+void
+afs_osi_SetTime(osi_timeval_t *atv)
+{
+#if 0
+    printf("afs attempted to set clock; use \"afsd -nosettime\"\n");
+#else
+    struct timespec ts;
+    AFS_GUNLOCK();
+    ts.tv_sec = atv->tv_sec;
+    ts.tv_nsec = atv->tv_usec * 1000;
+    settime(osi_curproc()->l_proc, &ts); /* really takes a process */
+    AFS_GLOCK();
+#endif
+}
diff --git a/src/afs/NBSD/osi_prototypes.h b/src/afs/NBSD/osi_prototypes.h
new file mode 100644 (file)
index 0000000..4bc45e9
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * osi_prototypes.h
+ *
+ * Exported macos support routines.
+ */
+#ifndef _OSI_PROTO_H_
+#define _OSI_PROTO_H_
+
+/* osi_file.c */
+extern afs_rwlock_t afs_xosi;
+
+#endif /* _OSI_PROTO_H_ */
diff --git a/src/afs/NBSD/osi_sleep.c b/src/afs/NBSD/osi_sleep.c
new file mode 100644 (file)
index 0000000..b100a10
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * $Id: osi_sleep.c,v 1.9 2005/07/26 15:25:43 rees Exp $
+ */
+
+/*
+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 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* afs statistics */
+
+static char waitV;
+
+
+/* cancel osi_Wait */
+void
+afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
+{
+    caddr_t proc;
+
+    AFS_STATCNT(osi_CancelWait);
+    proc = achandle->proc;
+    if (proc == NULL)
+       return;
+    achandle->proc = NULL;
+    wakeup(&waitV);
+}
+
+/* afs_osi_Wait
+ * Waits for data on ahandle, or ams ms later.  ahandle may be null.
+ * Returns 0 if timeout and EINTR if signalled.
+ */
+int
+afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok)
+{
+    int timo, code = 0;
+    struct timeval atv, time_now, endTime;
+
+    AFS_STATCNT(osi_Wait);
+
+    atv.tv_sec = ams / 1000;
+    atv.tv_usec = (ams % 1000) * 1000;
+    time_now.tv_sec = time_second;
+    time_now.tv_usec = 0;
+    timeradd(&atv, &time_now, &endTime);
+
+    if (ahandle)
+       ahandle->proc = (caddr_t) osi_curproc();
+    AFS_ASSERT_GLOCK();
+    AFS_GUNLOCK();
+
+    do {
+
+       time_now.tv_sec = time_second;
+       time_now.tv_usec = 0;
+
+       timersub(&endTime, &time_now, &atv);
+       timo = atv.tv_sec * hz + atv.tv_usec * hz / 1000000 + 1;
+       if (aintok) {
+           code = tsleep(&waitV, PCATCH | PVFS, "afs_W1", timo);
+           if (code)
+               code = (code == EWOULDBLOCK) ? 0 : EINTR;
+       } else
+           tsleep(&waitV, PVFS, "afs_W2", timo);
+
+       /* if we were cancelled, quit now */
+       if (ahandle && (ahandle->proc == NULL)) {
+           /* we've been signalled */
+           break;
+       }
+    } while (timercmp(&time_now, &endTime, <));
+
+    AFS_GLOCK();
+    return code;
+}
+
+void
+afs_osi_Sleep(void *event)
+{
+    AFS_ASSERT_GLOCK();
+    AFS_GUNLOCK();
+    tsleep(event, PVFS, "afsslp", 0);
+    AFS_GLOCK();
+}
+
+int
+afs_osi_SleepSig(void *event)
+{
+    afs_osi_Sleep(event);
+    return 0;
+}
+
+int
+afs_osi_Wakeup(void *event)
+{
+    wakeup(event);
+    return 1;
+}
diff --git a/src/afs/NBSD/osi_vfs.h b/src/afs/NBSD/osi_vfs.h
new file mode 100644 (file)
index 0000000..aeccfd3
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#ifndef _OSI_VFS_H
+#define _OSI_VFS_H
+
+#define        VSUID   S_ISUID
+#define        VSGID   S_ISGID
+
+#endif /* _OSI_VFS_H */
diff --git a/src/afs/NBSD/osi_vfsops.c b/src/afs/NBSD/osi_vfsops.c
new file mode 100644 (file)
index 0000000..456d38f
--- /dev/null
@@ -0,0 +1,522 @@
+/*
+ * OpenBSD specific assistance routines & VFS ops
+ * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
+ * OpenBSD version by Jim Rees <rees@umich.edu>
+ * Reported to NetBSD 4.0 by Matt Benjamin (matt@linuxbox.com)
+ *
+ * $Id: osi_vfsops.c,v 1.20 2005/03/08 21:58:04 shadow Exp $
+ */
+
+/*
+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 the 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
+WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
+ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT.
+*/
+
+/*
+ * Some code cribbed from ffs_vfsops and other NetBSD sources, which
+ * are marked:
+ */
+/*
+ * Copyright (c) 1989, 1991, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* statistics */
+
+#include <sys/ioctl.h>
+#include <sys/lkm.h>
+
+#if 0
+/* from /usr/src/sys/kern/vfs_subr.c */
+extern void insmntque(struct vnode *, struct mount *);
+#endif
+extern int sys_lkmnosys(), afs3_syscall(), afs_xioctl(), Afs_xsetgroups();
+
+static int lkmid = -1;
+static int afs_badcall(struct lwp *, void *, register_t *);
+
+#if 0
+int
+newcall(l, v, retval)
+       struct lwp *l;
+       void *v;
+       int *retval;
+{
+       struct afs_sysargs *uap = v;
+
+       printf("kmod: newcall: %ld %ld %ld %ld\n",
+              SCARG(uap, syscall), SCARG(uap, parm1),
+              SCARG(uap, parm2), SCARG(uap, parm3));
+       return(0);
+}
+#endif
+
+struct sysent afs_sysent = { 6,
+                            sizeof(struct afs_sysargs),
+                            0,
+                            afs3_syscall};
+
+static struct sysent old_sysent;
+
+struct osi_vfs *afs_globalVFS;
+struct vcache *afs_globalVp;
+fsid_t afs_dynamic_fsid;
+
+int afs_mount(struct mount *, const char *, void *,
+             struct nameidata *, struct lwp *);
+int afs_start(struct mount *, int, struct lwp *);
+int afs_unmount(struct mount *, int, struct lwp *);
+int afs_root(struct mount *, struct vnode **);
+int afs_quotactl(struct mount *, int, uid_t, void *, struct lwp *);
+int afs_statvfs(struct mount *, struct statvfs *, struct lwp *);
+int afs_sync(struct mount *, int, kauth_cred_t, struct lwp *);
+int afs_vget(struct mount *, ino_t, struct vnode **);
+void afs_init(void);
+void afs_reinit(void);
+void afs_done(void);
+
+extern struct vnodeopv_desc afs_vnodeop_opv_desc;
+static const struct vnodeopv_desc *afs_vnodeopv_descs[] = {
+       &afs_vnodeop_opv_desc,
+       NULL,
+};
+
+struct vfsops afs_vfsops = {
+    AFS_MOUNT_AFS,
+    afs_mount,
+    afs_start,
+    afs_unmount,
+    afs_root,
+    afs_quotactl,
+    afs_statvfs,
+    afs_sync,
+    afs_vget,
+    (void *) eopnotsupp,       /* vfs_fhtovp */
+    (void *) eopnotsupp,       /* vfs_vptofh */
+    afs_init,
+    afs_reinit,
+    afs_done,
+    (int (*) (void)) eopnotsupp, /* mountroot */
+    (int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp,
+    vfs_stdextattrctl,
+    afs_vnodeopv_descs,
+    0,                 /* vfs_refcount */
+    { NULL, NULL },
+};
+
+VFS_ATTACH(afs_vfsops);
+
+int
+afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg, int followlink,
+                   struct vnode **compvpp)
+{
+    struct nameidata nd;
+    int niflag;
+    int error;
+
+    afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep);
+
+    /*
+     * Lookup pathname "fnamep", returning leaf in *compvpp.  segflg says
+     * whether the pathname is user or system space.
+     */
+    /* XXX LOCKLEAF ? */
+    niflag = followlink ? FOLLOW : NOFOLLOW;
+    NDINIT(&nd, LOOKUP, niflag, segflg, fnamep, osi_curproc());
+    if ((error = namei(&nd)))
+       return error;
+    *compvpp = nd.ni_vp;
+    return error;
+}
+
+int
+afs_quotactl(struct mount *mp, int cmd, uid_t uid,
+    void *arg, struct lwp *l)
+{
+    return EOPNOTSUPP;
+}
+
+int
+afs_sysctl()
+{
+    return EOPNOTSUPP;
+}
+
+int
+afs_start(struct mount *mp, int flags, struct lwp *l)
+{
+    return (0); /* nothing to do? */
+}
+
+void afs_done(void)
+{
+    return; /* nothing to do? */
+}
+
+int
+afs_mount(struct mount *mp, const char *path, void *data,
+         struct nameidata *ndp, struct lwp *l)
+{
+    /* ndp contains the mounted-from device.  Just ignore it.
+     * we also don't care about our proc struct. */
+    u_int size;
+
+    AFS_STATCNT(afs_mount);
+
+    afs_warn("afs_mount enter\n");
+
+    if (mp->mnt_flag & MNT_UPDATE)
+       return EINVAL;
+
+    if (afs_globalVFS) {
+       /* Don't allow remounts */
+       return EBUSY;
+    }
+
+    AFS_GLOCK();
+#ifdef AFS_DISCON_ENV
+    /* initialize the vcache entries before we start using them */
+
+    /* XXX find a better place for this if possible  */
+    init_vcache_entries();
+#endif
+    afs_globalVFS = mp;
+    mp->mnt_stat.f_bsize = 8192;
+    mp->mnt_stat.f_frsize = 8192;
+    mp->mnt_stat.f_iosize = 8192;
+#if 0
+    mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC;    /* magic */
+    mp->osi_vfs_fsid.val[1] = (int)AFS_VFSFSID;
+#else
+    vfs_getnewfsid(mp);
+    afs_dynamic_fsid = mp->mnt_stat.f_fsidx;
+#endif
+    (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1,
+                   &size);
+    bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
+    bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
+    strcpy(mp->mnt_stat.f_mntfromname, "AFS");
+    /* null terminated string "AFS" will fit, just leave it be. */
+    strcpy(mp->mnt_stat.f_fstypename, AFS_MOUNT_AFS);
+    AFS_GUNLOCK();
+    (void)afs_statvfs(mp, &mp->mnt_stat, l);
+
+    afs_warn("afs_mount exit\n");
+
+    return 0;
+}
+
+int
+afs_unmount(struct mount *mp, int mntflags, struct lwp *l)
+{
+    extern int sys_ioctl(), sys_setgroups();
+
+    AFS_STATCNT(afs_unmount);
+#ifdef AFS_DISCON_ENV
+    give_up_cbs();
+#endif
+    if (afs_globalVFS == NULL) {
+       printf("afs already unmounted\n");
+       return 0;
+    }
+    if (afs_globalVp)
+       vrele(AFSTOV(afs_globalVp));
+    afs_globalVp = NULL;
+
+    vflush(mp, NULLVP, 0);     /* don't support forced */
+    mp->mnt_data = NULL;
+    AFS_GLOCK();
+    afs_globalVFS = 0;
+    afs_cold_shutdown = 1;
+    afs_shutdown();            /* XXX */
+    AFS_GUNLOCK();
+
+    printf
+       ("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n",
+        lkmid);
+    return 0;
+}
+
+static int
+afs_badcall(struct lwp *l, void *xx, register_t * yy)
+{
+    return ENOSYS;
+}
+
+int
+afs_root(struct mount *mp, struct vnode **vpp)
+{
+    struct vrequest treq;
+    struct vcache *tvp;
+    int code, glocked;
+
+    AFS_STATCNT(afs_root);
+
+    glocked = ISAFS_GLOCK();
+    afs_warn("afs_root enter, glocked==%d\n", glocked);
+
+    AFS_GLOCK();
+
+    afs_warn("glocked\n");
+
+    if (!(code = afs_InitReq(&treq, osi_curcred()))
+       && !(code = afs_CheckInit())) {
+
+       afs_warn("afs_root: initReq && CheckInit: code==%d\n", code);
+
+       tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
+       afs_warn("afs_root: GetVCache: tvp==%lx\n", tvp);
+       if (tvp) {
+           /* There is really no reason to over-hold this bugger--it's held
+            * by the root filesystem reference. */
+           if (afs_globalVp != tvp) {
+#ifdef AFS_DONT_OVERHOLD_GLOBALVP
+               if (afs_globalVp)
+                   AFS_RELE(AFSTOV(afs_globalVp));
+#endif
+               afs_globalVp = tvp;
+               VREF(AFSTOV(afs_globalVp));
+           }
+           AFSTOV(tvp)->v_flag |= VROOT;
+           afs_globalVFS = mp;
+           *vpp = AFSTOV(tvp);
+       } else
+           code = ENOENT;
+    }
+    AFS_GUNLOCK();
+
+    afs_warn("afs_root: gunlocked\n");
+
+    if (!code) {
+       if (!VOP_ISLOCKED(*vpp))
+           vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); /* return it locked */
+    }
+
+    afs_warn("afs_root exit\n");
+
+    return code;
+}
+
+int
+afs_statvfs(struct mount *mp, struct statvfs *abp, struct lwp *l)
+{
+    AFS_STATCNT(afs_statfs);
+
+    afs_warn("afs_statvfs enter\n");
+
+    /* thank you, NetBSD */
+    copy_statvfs_info(abp, mp);
+
+    /* not actually sure which we really must set, but
+     * pretty sure of the right values (and in 40, none touched by
+     * the above convenience function) */
+    abp->f_bsize = mp->osi_vfs_bsize;
+    abp->f_frsize = mp->osi_vfs_bsize;
+    abp->f_iosize = mp->osi_vfs_bsize;
+
+    /*
+     * Fake a high number below to satisfy programs that use the ustat (for
+     * * AIX), or statfs (for the rest) call to make sure that there's
+     * enough * space in the device partition before storing something there
+     * (like * ed(1))
+     */
+    abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
+       abp->f_ffree = 9000000;
+
+    return (0);
+}
+
+int
+afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred, struct lwp *l)
+{
+    AFS_STATCNT(afs_sync);
+#if defined(AFS_DISCON_ENV)
+    /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
+    store_dirty_vcaches();
+#endif
+    return 0;
+}
+
+int
+afs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
+{
+    return (EOPNOTSUPP);
+}
+
+void
+afs_init()
+{
+    osi_Init();
+    return;
+}
+
+void
+afs_reinit(void)
+{
+    return;
+}
+
+/* LKM */
+
+/*
+ * declare the filesystem
+ */
+MOD_VFS("afs", -1, &afs_vfsops);
+
+#if 0
+static char afsgenmem[] = "afsgenmem";
+static char afsfidmem[] = "afsfidmem";
+static char afsbhdrmem[] = "afsbhdrmem";
+static char afsbfrmem[] = "afsbfrmem";
+#endif
+
+int
+afs_vfs_load(struct lkm_table *lkmtp, int cmd)
+{
+#if 0
+    extern char *memname[];
+
+    if (memname[M_AFSGENERIC] == NULL)
+       memname[M_AFSGENERIC] = afsgenmem;
+    if (memname[M_AFSFID] == NULL)
+       memname[M_AFSFID] = afsfidmem;
+    if (memname[M_AFSBUFHDR] == NULL)
+       memname[M_AFSBUFHDR] = afsbhdrmem;
+    if (memname[M_AFSBUFFER] == NULL)
+       memname[M_AFSBUFFER] = afsbfrmem;
+#endif
+    lkmid = lkmtp->id;
+
+    if (sysent[AFS_SYSCALL].sy_call != sys_nosys) {
+       printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
+              AFS_SYSCALL);
+       /* return EEXIST; */
+    }
+
+    old_sysent = sysent[AFS_SYSCALL];
+    sysent[AFS_SYSCALL] = afs_sysent;
+
+    printf("OpenAFS lkm loaded\n");
+
+    return (0);
+}
+
+int
+afs_vfs_unload(struct lkm_table *lktmp, int cmd)
+{
+#if 0
+    extern char *memname[];
+#endif
+
+    if (afs_globalVp)
+       return EBUSY;
+#if 0
+    if (memname[M_AFSGENERIC] == afsgenmem)
+       memname[M_AFSGENERIC] = NULL;
+    if (memname[M_AFSFID] == afsfidmem)
+       memname[M_AFSFID] = NULL;
+    if (memname[M_AFSBUFHDR] == afsbhdrmem)
+       memname[M_AFSBUFHDR] = NULL;
+    if (memname[M_AFSBUFFER] == afsbfrmem)
+       memname[M_AFSBUFFER] = NULL;
+#endif
+
+    if (sysent[AFS_SYSCALL].sy_call != afs_sysent.sy_call) {
+       printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
+              AFS_SYSCALL);
+       return EEXIST;
+    }
+
+    sysent[AFS_SYSCALL] = old_sysent;
+    printf("OpenAFS unloaded\n");
+
+    return (0);
+}
+
+int
+libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
+{
+    if (cmd == LKM_E_LOAD) {
+       if (sysent[AFS_SYSCALL].sy_call == afs3_syscall
+           || sysent[AFS_SYSCALL].sy_call == afs_badcall) {
+           printf("AFS already loaded\n");
+           return EINVAL;
+       }
+    }
+    DISPATCH(lkmtp, cmd, ver, afs_vfs_load, afs_vfs_unload, lkm_nofunc);
+}
diff --git a/src/afs/NBSD/osi_vm.c b/src/afs/NBSD/osi_vm.c
new file mode 100644 (file)
index 0000000..39f8921
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+
+/* osi_vm.c implements:
+ *
+ * osi_VM_FlushVCache(avc, slept)
+ * osi_ubc_flush_dirty_and_wait(vp, flags)
+ * osi_VM_StoreAllSegments(avc)
+ * osi_VM_TryToSmush(avc, acred, sync)
+ * osi_VM_FlushPages(avc, credp)
+ * osi_VM_Truncate(avc, alen, acred)
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* statistics */
+/* #include <vm/vm_ubc.h> */
+#include <limits.h>
+#include <float.h>
+
+/* Try to discard pages, in order to recycle a vcache entry.
+ *
+ * We also make some sanity checks:  ref count, open count, held locks.
+ *
+ * We also do some non-VM-related chores, such as releasing the cred pointer
+ * (for AIX and Solaris) and releasing the gnode (for AIX).
+ *
+ * Locking:  afs_xvcache lock is held.  If it is dropped and re-acquired,
+ *   *slept should be set to warn the caller.
+ *
+ * Formerly, afs_xvcache was dropped and re-acquired for Solaris, but now it
+ * is not dropped and re-acquired for any platform.  It may be that *slept is
+ * therefore obsolescent.
+ *
+ * OSF/1 Locking:  VN_LOCK has been called.
+ */
+int
+osi_VM_FlushVCache(struct vcache *avc, int *slept)
+{
+    return 0;
+}
+
+/* Try to store pages to cache, in order to store a file back to the server.
+ *
+ * Locking:  the vcache entry's lock is held.  It will usually be dropped and
+ * re-obtained.
+ */
+void
+osi_VM_StoreAllSegments(struct vcache *avc)
+{
+}
+
+/* Try to invalidate pages, for "fs flush" or "fs flushv"; or
+ * try to free pages, when deleting a file.
+ *
+ * Locking:  the vcache entry's lock is held.  It may be dropped and
+ * re-obtained.
+ *
+ * Since we drop and re-obtain the lock, we can't guarantee that there won't
+ * be some pages around when we return, newly created by concurrent activity.
+ */
+void
+osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync)
+{
+}
+
+/* Purge VM for a file when its callback is revoked.
+ *
+ * Locking:  No lock is held, not even the global lock.
+ */
+void
+osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp)
+{
+}
+
+/* Purge pages beyond end-of-file, when truncating a file.
+ *
+ * Locking:  no lock is held, not even the global lock.
+ * activeV is raised.  This is supposed to block pageins, but at present
+ * it only works on Solaris.
+ */
+void
+osi_VM_Truncate(struct vcache *avc, int alen, afs_ucred_t *acred)
+{
+}
diff --git a/src/afs/NBSD/osi_vnodeops.c b/src/afs/NBSD/osi_vnodeops.c
new file mode 100644 (file)
index 0000000..776a3b1
--- /dev/null
@@ -0,0 +1,1158 @@
+/*
+ * 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: osi_vnodeops.c,v 1.20 2006/03/09 15:27:17 rees Exp $
+ */
+
+/*
+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 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
+WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
+ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT.
+*/
+
+/*
+ * A bunch of code cribbed from NetBSD ufs_vnops.c, ffs_vnops.c, and
+ * nfs_vnops.c which carry this copyright:
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afs/afsincludes.h"   /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* statistics */
+
+#include <sys/malloc.h>
+#include <sys/namei.h>
+#include <sys/pool.h>
+#include <miscfs/genfs/genfs.h>
+
+
+#include "afs/afs_cbqueue.h"
+#include "afs/nfsclient.h"
+#include "afs/afs_osidnlc.h"
+
+#ifdef AFS_DISCON_ENV
+extern int afs_FlushVS(struct vcache *tvc);
+#endif
+
+#define M_AFSNODE (M_TEMP-1)   /* XXX */
+
+int afs_nbsd_lookup(void *);
+int afs_nbsd_create(void *);
+int afs_nbsd_mknod(void *);
+int afs_nbsd_open(void *);
+int afs_nbsd_close(void *);
+int afs_nbsd_access(void *);
+int afs_nbsd_getattr(void *);
+int afs_nbsd_setattr(void *);
+int afs_nbsd_read(void *);
+int afs_nbsd_write(void *);
+int afs_nbsd_ioctl(void *);
+int afs_nbsd_select(void *);
+int afs_nbsd_fsync(void *);
+int afs_nbsd_remove(void *);
+int afs_nbsd_link(void *);
+int afs_nbsd_rename(void *);
+int afs_nbsd_mkdir(void *);
+int afs_nbsd_rmdir(void *);
+int afs_nbsd_symlink(void *);
+int afs_nbsd_readdir(void *);
+int afs_nbsd_readlink(void *);
+int afs_nbsd_inactive(void *);
+int afs_nbsd_reclaim(void *);
+int afs_nbsd_lock(void *);
+int afs_nbsd_unlock(void *);
+int afs_nbsd_bmap(void *);
+int afs_nbsd_strategy(void *);
+int afs_nbsd_print(void *);
+int afs_nbsd_islocked(void *);
+int afs_nbsd_pathconf(void *);
+int afs_nbsd_advlock(void *);
+
+#if LATER
+int afs_nbsd_getpages(void*);
+#endif
+
+/*
+ * Implement:
+ *   vop_getpages (VM)
+ *   vop_putpages (VM)
+ *
+ * Someday:
+ *   vop_mmap_desc (mmap'd IO)
+ *
+ * Skip:
+ *   vop_*xtattr
+ *
+ * Unknown:
+ *   vop_fcntl
+ *
+ */
+
+#define afs_nbsd_opnotsupp \
+       ((int (*) __P((void *)))eopnotsupp)
+#define afs_nbsd_reallocblks afs_nbsd_opnotsupp
+
+/* Global vfs data structures for AFS. */
+int (**afs_vnodeop_p) __P((void *));
+struct vnodeopv_entry_desc afs_vnodeop_entries[] = {
+    {&vop_default_desc, vn_default_error},
+    {&vop_lookup_desc, afs_nbsd_lookup},       /* lookup */
+    {&vop_create_desc, afs_nbsd_create},       /* create */
+    {&vop_mknod_desc, afs_nbsd_mknod},         /* mknod */
+    {&vop_open_desc, afs_nbsd_open},           /* open */
+    {&vop_close_desc, afs_nbsd_close},         /* close */
+    {&vop_access_desc, afs_nbsd_access},       /* access */
+    {&vop_getattr_desc, afs_nbsd_getattr},     /* getattr */
+    {&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_poll_desc, afs_nbsd_select},         /* select */
+    {&vop_kqfilter_desc, genfs_kqfilter },     /* kqfilter */
+    {&vop_fsync_desc, afs_nbsd_fsync},         /* fsync */
+    {&vop_remove_desc, afs_nbsd_remove},       /* remove */
+    {&vop_link_desc, afs_nbsd_link},           /* link */
+    {&vop_rename_desc, afs_nbsd_rename},       /* rename */
+    {&vop_mkdir_desc, afs_nbsd_mkdir},         /* mkdir */
+    {&vop_rmdir_desc, afs_nbsd_rmdir},         /* rmdir */
+    {&vop_symlink_desc, afs_nbsd_symlink},     /* symlink */
+    {&vop_readdir_desc, afs_nbsd_readdir},     /* readdir */
+    {&vop_readlink_desc, afs_nbsd_readlink},   /* readlink */
+    {&vop_abortop_desc, genfs_abortop},                /* abortop */
+    {&vop_inactive_desc, afs_nbsd_inactive},   /* inactive */
+    {&vop_reclaim_desc, afs_nbsd_reclaim},     /* reclaim */
+    {&vop_lock_desc, afs_nbsd_lock},           /* lock */
+    {&vop_unlock_desc, afs_nbsd_unlock},       /* unlock */
+    {&vop_bmap_desc, afs_nbsd_bmap},           /* bmap */
+    {&vop_strategy_desc, afs_nbsd_strategy},   /* strategy */
+    {&vop_print_desc, afs_nbsd_print},         /* print */
+    {&vop_islocked_desc, afs_nbsd_islocked},   /* islocked */
+    {&vop_pathconf_desc, afs_nbsd_pathconf},   /* pathconf */
+    {&vop_advlock_desc, afs_nbsd_advlock},     /* advlock */
+#if 0
+    {&vop_reallocblks_desc, afs_nbsd_reallocblks},     /* reallocblks */
+#endif
+    {&vop_bwrite_desc, vn_bwrite},     /* bwrite */
+#if LATER
+    { &vop_getpages_desc, ffs_getpages },       /* getpages */
+    { &vop_putpages_desc, genfs_putpages },    /* putpages */
+#endif
+    {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL}
+};
+struct vnodeopv_desc afs_vnodeop_opv_desc =
+    { &afs_vnodeop_p, afs_vnodeop_entries };
+
+#define GETNAME() \
+    struct componentname *cnp = ap->a_cnp; \
+    char *name; \
+    name = PNBUF_GET();        \
+    bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \
+    name[cnp->cn_namelen] = '\0'
+
+#define DROPNAME() PNBUF_PUT(name)
+#define DROPCNP PNBUF_PUT
+
+/* toss "stale" pages by shrinking the vnode uobj to a 0-length
+ * region (see uvm_vnp_setsize in uvm_vnode.c) */
+#define VNP_UNCACHE(vp) \
+    do {               \
+       struct uvm_object *uobj = &vp->v_uobj; \
+       simple_lock(&uobj->vmobjlock); \
+       VOP_PUTPAGES( (struct vnode *) uobj, 0 /* offlo */, 0 /* offhi */, PGO_FREE | PGO_SYNCIO); \
+       simple_unlock(&uobj->vmobjlock); \
+    } while(0);
+
+/* psuedo-vnop, wherein we learn that obsd and nbsd disagree
+ * about vnode refcounting */
+void
+afs_nbsd_getnewvnode(struct vcache *tvc)
+{
+    while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
+       /* no vnodes available, force an alloc (limits be damned)! */
+       desiredvnodes++;
+    }
+    afs_warn("afs_nbsd_getnewvnode: vp %lx refs %d (soon to be 1)\n", tvc->v,
+            tvc->v->v_usecount);
+    simple_lock(&tvc->v->v_interlock);
+    tvc->v->v_data = (void *)tvc;
+    tvc->v->v_usecount = 1; /* !locked, and vref w/v_usecount < 1 panics */
+    simple_unlock(&tvc->v->v_interlock);
+}
+
+int afs_debug;
+
+int
+afs_nbsd_lookup(void *v)
+{
+    struct vop_lookup_args     /* {
+                                * struct vnodeop_desc * a_desc;
+                                * struct vnode *a_dvp;
+                                * struct vnode **a_vpp;
+                                * struct componentname *a_cnp;
+                                * } */ *ap = v;
+    int code;
+    struct vcache *vcp;
+    struct vnode *vp, *dvp;
+    int flags = ap->a_cnp->cn_flags;
+    int lockparent;            /* 1 => lockparent flag is set */
+
+    afs_warn("afs_nbsd_lookup enter\n");
+
+    GETNAME();
+    lockparent = flags & LOCKPARENT;
+    if (ap->a_dvp->v_type != VDIR) {
+       *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);
+    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) && code == ENOENT)
+           code = EJUSTRETURN;
+       if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
+           cnp->cn_flags |= SAVENAME;
+       DROPNAME();
+       *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.
+     */
+
+    if (vp == dvp) {
+       /* they're the same; afs_lookup() already ref'ed the leaf.
+        * It came in locked, so we don't need to ref OR lock it */
+       if (afs_debug & AFSDEB_VNLAYER)
+           printf("ref'ed %p as .\n", dvp);
+    } else {
+       if (!lockparent || !(flags & ISLASTCN)) {
+           VOP_UNLOCK(dvp, 0); /* done with parent. */
+       }
+
+       simple_lock(&vp->v_interlock);
+       vp->v_usecount = (vp->v_usecount < 1) ? 1 : (vp->v_usecount+1);
+       simple_unlock(&vp->v_interlock);
+       if (!VOP_ISLOCKED(vp)) {
+           vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+           afs_warn("h2\n");
+           /* vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); *//* always return the child locked */
+       } else {
+           afs_warn("lookup: vp %lx is locked\n", vp);
+       }
+       afs_warn("lookup: after islocked\n");
+       if (afs_debug & AFSDEB_VNLAYER)
+           printf("locked ret %p from lookup\n", vp);
+    }
+    *ap->a_vpp = vp;
+
+    if (((cnp->cn_nameiop == RENAME && (flags & ISLASTCN))
+        || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))))
+       cnp->cn_flags |= SAVENAME;
+
+    DROPNAME();
+    if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT))
+       printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount);
+    return code;
+}
+
+int
+afs_nbsd_create(void *v)
+{
+    struct vop_create_args     /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode **a_vpp;
+                                * struct componentname *a_cnp;
+                                * struct vattr *a_vap;
+                                * } */ *ap = v;
+    int code = 0;
+    struct vcache *vcp;
+    struct vnode *dvp = ap->a_dvp;
+    GETNAME();
+
+    if (afs_debug & AFSDEB_VNLAYER)
+       printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount);
+
+    /* vnode layer handles excl/nonexcl */
+
+    AFS_GLOCK();
+    code =
+       afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode,
+                  &vcp, cnp->cn_cred);
+    AFS_GUNLOCK();
+    if (code) {
+       VOP_ABORTOP(dvp, cnp);
+       vput(dvp);
+       DROPNAME();
+       return (code);
+    }
+
+    if (vcp) {
+       *ap->a_vpp = AFSTOV(vcp);
+       vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
+    } else
+       *ap->a_vpp = 0;
+
+    if ((cnp->cn_flags & SAVESTART) == 0)
+       DROPCNP(cnp);
+    vput(dvp);
+    DROPNAME();
+    if (afs_debug & AFSDEB_VNLAYER)
+       printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount);
+    return code;
+}
+
+int
+afs_nbsd_mknod(void *v)
+{
+    struct vop_mknod_args      /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode **a_vpp;
+                                * struct componentname *a_cnp;
+                                * struct vattr *a_vap;
+                                * } */ *ap = v;
+    DROPCNP(ap->a_cnp);
+    vput(ap->a_dvp);
+    return (ENODEV);
+}
+
+int
+afs_nbsd_open(void *v)
+{
+    struct vop_open_args       /* {
+                                * struct vnode *a_vp;
+                                * int  a_mode;
+                                * struct ucred *a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    int code;
+    struct vcache *vc = VTOAFS(ap->a_vp);
+
+    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
+    AFS_GUNLOCK();
+    return code;
+}
+
+int
+afs_nbsd_close(void *v)
+{
+    struct vop_close_args      /* {
+                                * struct vnode *a_vp;
+                                * int  a_fflag;
+                                * kauth_cred_t a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    int code;
+
+    AFS_GLOCK();
+    code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
+}
+
+int
+afs_nbsd_access(void *v)
+{
+    struct vop_access_args     /* {
+                                * struct vnode *a_vp;
+                                * int  a_mode;
+                                * kauth_cred_t a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    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(void *v)
+{
+    struct vop_getattr_args    /* {
+                                * struct vnode *a_vp;
+                                * struct vattr *a_vap;
+                                * kauth_cred_t a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    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(void *v)
+{
+    struct vop_setattr_args    /* {
+                                * struct vnode *a_vp;
+                                * struct vattr *a_vap;
+                                * kauth_cred_t a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    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(void *v)
+{
+    struct vop_read_args       /* {
+                                * struct vnode *a_vp;
+                                * struct uio *a_uio;
+                                * int a_ioflag;
+                                * kauth_cred_t a_cred;
+                                * } */ *ap = v;
+    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(void *v)
+{
+    struct vop_write_args      /* {
+                                * struct vnode *a_vp;
+                                * struct uio *a_uio;
+                                * int a_ioflag;
+                                * kauth_cred_t a_cred;
+                                * } */ *ap = v;
+    int code;
+
+#if 1
+    /* all pages are really "stale?" */
+    VNP_UNCACHE(ap->a_vp);
+#else
+    (void)uvm_vnp_uncache(ap->a_vp);   /* toss stale pages */
+#endif
+    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(void *v)
+{
+    struct vop_ioctl_args      /* {
+                                * struct vnode *a_vp;
+                                * int  a_command;
+                                * caddr_t  a_data;
+                                * int  a_fflag;
+                                * kauth_cred_t a_cred;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    int code;
+
+    /* in case we ever get in here... */
+
+    AFS_STATCNT(afs_ioctl);
+    AFS_GLOCK();
+    if (((ap->a_command >> 8) & 0xff) == 'V')
+       /* This is a VICEIOCTL call */
+       code =
+           HandleIoctl(VTOAFS(ap->a_vp), ap->a_command,
+                       (struct afs_ioctl *)ap->a_data);
+    else
+       /* No-op call; just return. */
+       code = ENOTTY;
+    AFS_GUNLOCK();
+    return code;
+}
+
+int
+afs_nbsd_select(void *v)
+{
+    return 1;
+}
+
+int
+afs_nbsd_fsync(void *v)
+{
+    struct vop_fsync_args      /* {
+                                * struct vnode *a_vp;
+                                * kauth_cred_t a_cred;
+                                * int a_waitfor;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+    struct vnode *vp = ap->a_vp;
+    int code, wait;
+
+    wait = (ap->a_flags & FSYNC_WAIT) != 0;
+
+    AFS_GLOCK();
+    vflushbuf(vp, wait);
+    code = afs_fsync(VTOAFS(vp), ap->a_cred);
+    AFS_GUNLOCK();
+
+    return code;
+}
+
+int
+afs_nbsd_remove(void *v)
+{
+    struct vop_remove_args     /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode *a_vp;
+                                * struct componentname *a_cnp;
+                                * } */ *ap = v;
+    int code;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_dvp;
+
+    GETNAME();
+    AFS_GLOCK();
+    code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
+    if (dvp == vp)
+       vrele(vp);
+    else
+       vput(vp);
+    vput(dvp);
+    DROPCNP(cnp);
+    DROPNAME();
+    return code;
+}
+
+int
+afs_nbsd_link(void *v)
+{
+    struct vop_link_args       /* {
+                                * struct vnode *a_vp;
+                                * struct vnode *a_tdvp;
+                                * struct componentname *a_cnp;
+                                * } */ *ap = v;
+    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);
+       code = EXDEV;
+       goto out;
+    }
+    if (vp->v_type == VDIR) {
+       VOP_ABORTOP(vp, cnp);
+       code = EISDIR;
+       goto out;
+    }
+    if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) {
+       VOP_ABORTOP(dvp, cnp);
+       goto out;
+    }
+
+    AFS_GLOCK();
+    code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
+    DROPCNP(cnp);
+    if (dvp != vp)
+       VOP_UNLOCK(vp, 0);
+
+  out:
+    vput(dvp);
+    DROPNAME();
+    return code;
+}
+
+int
+afs_nbsd_rename(void *v)
+{
+    struct vop_rename_args     /* {
+                                * struct vnode *a_fdvp;
+                                * struct vnode *a_fvp;
+                                * struct componentname *a_fcnp;
+                                * struct vnode *a_tdvp;
+                                * struct vnode *a_tvp;
+                                * struct componentname *a_tcnp;
+                                * } */ *ap = v;
+    int code = 0;
+    struct componentname *fcnp = ap->a_fcnp;
+    char *fname;
+    struct componentname *tcnp = ap->a_tcnp;
+    char *tname;
+    struct vnode *tvp = ap->a_tvp;
+    struct vnode *tdvp = ap->a_tdvp;
+    struct vnode *fvp = ap->a_fvp;
+    struct vnode *fdvp = ap->a_fdvp;
+
+    /*
+     * Check for cross-device rename.
+     */
+    if ((fvp->v_mount != tdvp->v_mount)
+       || (tvp && (fvp->v_mount != tvp->v_mount))) {
+       code = EXDEV;
+      abortit:
+       VOP_ABORTOP(tdvp, tcnp);        /* XXX, why not in NFS? */
+       if (tdvp == tvp)
+           vrele(tdvp);
+       else
+           vput(tdvp);
+       if (tvp)
+           vput(tvp);
+       VOP_ABORTOP(fdvp, fcnp);        /* XXX, why not in NFS? */
+       vrele(fdvp);
+       vrele(fvp);
+       return (code);
+    }
+    /*
+     * if fvp == tvp, we're just removing one name of a pair of
+     * directory entries for the same element.  convert call into rename.
+     ( (pinched from NetBSD 1.0's ufs_rename())
+     */
+    if (fvp == tvp) {
+       if (fvp->v_type == VDIR) {
+           code = EINVAL;
+           goto abortit;
+       }
+
+       /* Release destination completely. */
+       VOP_ABORTOP(tdvp, tcnp);
+       vput(tdvp);
+       vput(tvp);
+
+       /* Delete source. */
+       vrele(fdvp);
+       vrele(fvp);
+       fcnp->cn_flags &= ~MODMASK;
+       fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
+       if ((fcnp->cn_flags & SAVESTART) == 0)
+           panic("afs_rename: lost from startdir");
+       fcnp->cn_nameiop = DELETE;
+       (void)relookup(fdvp, &fvp, fcnp);
+       return (VOP_REMOVE(fdvp, fvp, fcnp));
+    }
+
+    if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY)))
+       goto abortit;
+
+    /* XXX GETNAME() ? */
+    MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
+    bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen);
+    fname[fcnp->cn_namelen] = '\0';
+    MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK);
+    bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen);
+    tname[tcnp->cn_namelen] = '\0';
+
+
+    AFS_GLOCK();
+    /* XXX use "from" or "to" creds? NFS uses "to" creds */
+    code =
+       afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname,
+                  tcnp->cn_cred);
+    AFS_GUNLOCK();
+
+    VOP_UNLOCK(fvp, 0);
+    FREE(fname, M_TEMP);
+    FREE(tname, M_TEMP);
+    if (code)
+       goto abortit;           /* XXX */
+    if (tdvp == tvp)
+       vrele(tdvp);
+    else
+       vput(tdvp);
+    if (tvp)
+       vput(tvp);
+    vrele(fdvp);
+    vrele(fvp);
+    return code;
+}
+
+int
+afs_nbsd_mkdir(void *v)
+{
+    struct vop_mkdir_args      /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode **a_vpp;
+                                * struct componentname *a_cnp;
+                                * struct vattr *a_vap;
+                                * } */ *ap = v;
+    struct vnode *dvp = ap->a_dvp;
+    struct vattr *vap = ap->a_vap;
+    int code;
+    struct vcache *vcp;
+
+    GETNAME();
+#ifdef DIAGNOSTIC
+    if ((cnp->cn_flags & HASBUF) == 0)
+       panic("afs_nbsd_mkdir: no name");
+#endif
+    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 (code);
+    }
+    if (vcp) {
+       *ap->a_vpp = AFSTOV(vcp);
+       vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY);
+    } else
+       *ap->a_vpp = 0;
+    DROPCNP(cnp);
+    DROPNAME();
+    vput(dvp);
+    return code;
+}
+
+int
+afs_nbsd_rmdir(void *v)
+{
+    struct vop_rmdir_args      /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode *a_vp;
+                                * struct componentname *a_cnp;
+                                * } */ *ap = v;
+    int code;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *dvp = ap->a_dvp;
+
+    GETNAME();
+    if (dvp == vp) {
+       vrele(dvp);
+       vput(vp);
+       DROPCNP(cnp);
+       DROPNAME();
+       return (EINVAL);
+    }
+
+    AFS_GLOCK();
+    code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred);
+    AFS_GUNLOCK();
+    DROPNAME();
+    vput(dvp);
+    vput(vp);
+    return code;
+}
+
+int
+afs_nbsd_symlink(void *v)
+{
+    struct vop_symlink_args    /* {
+                                * struct vnode *a_dvp;
+                                * struct vnode **a_vpp;
+                                * struct componentname *a_cnp;
+                                * struct vattr *a_vap;
+                                * char *a_target;
+                                * } */ *ap = v;
+    struct vnode *dvp = ap->a_dvp;
+    int code;
+    /* NFS ignores a_vpp; so do we. */
+
+    GETNAME();
+    AFS_GLOCK();
+    code =
+       afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target,
+                   cnp->cn_cred);
+    AFS_GUNLOCK();
+    DROPCNP(cnp);
+    DROPNAME();
+    vput(dvp);
+    return code;
+}
+
+int
+afs_nbsd_readdir(void *v)
+{
+    struct vop_readdir_args    /* {
+                                * struct vnode *a_vp;
+                                * struct uio *a_uio;
+                                * kauth_cred_t a_cred;
+                                * int *a_eofflag;
+                                * int *a_ncookies;
+                                * u_long **a_cookies;
+                                * } */ *ap = v;
+    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
+afs_nbsd_readlink(void *v)
+{
+    struct vop_readlink_args   /* {
+                                * struct vnode *a_vp;
+                                * struct uio *a_uio;
+                                * kauth_cred_t a_cred;
+                                * } */ *ap = v;
+    int code;
+
+    AFS_GLOCK();
+    code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred);
+    AFS_GUNLOCK();
+    return code;
+}
+
+extern int prtactive;
+
+int
+afs_nbsd_inactive(void *v)
+{
+    struct vop_inactive_args   /* {
+                                * struct vnode *a_vp;
+                                * } */ *ap = v;
+    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);
+
+    if (!haveGlock)
+       AFS_GLOCK();
+    afs_InactiveVCache(vc, 0); /* decrs ref counts */
+    if (!haveGlock)
+       AFS_GUNLOCK();
+
+    lockinit(&vc->rwlock, PINOD, "vcache", 0, 0);
+    return 0;
+}
+
+int
+afs_nbsd_reclaim(void *v)
+{
+    struct vop_reclaim_args    /* {
+                                * struct vnode *a_vp;
+                                * } */ *ap = v;
+    int code, slept;
+    struct vnode *vp = ap->a_vp;
+    struct vcache *avc = VTOAFS(vp);
+    int haveGlock = ISAFS_GLOCK();
+    int haveVlock = CheckLock(&afs_xvcache);
+
+#if 0
+    printf("reclaim usecount %d\n", vp->v_usecount);
+    /* OK, there are no internal vrefCounts, so there shouldn't
+     * be any more refs here. */
+    vp->v_data = NULL;         /* remove from vnode */
+    avc->v = NULL;             /* also drop the ptr to vnode */
+    return 0;
+#else
+    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 */
+    code = afs_FlushVS(avc);
+#endif
+    if (!haveVlock)
+       ReleaseWriteLock(&afs_xvcache);
+    if (!haveGlock)
+       AFS_GUNLOCK();
+    return code;
+#endif
+}
+
+int
+afs_nbsd_lock(void *v)
+{
+    struct vop_lock_args       /* {
+                                * struct vnode *a_vp;
+                                * int a_flags;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+
+    return (genfs_lock(v));
+}
+
+int
+afs_nbsd_unlock(void *v)
+{
+    struct vop_unlock_args     /* {
+                                * struct vnode *a_vp;
+                                * int a_flags;
+                                * struct lwp *a_l;
+                                * } */ *ap = v;
+
+    return (genfs_unlock(v));
+}
+
+int
+afs_nbsd_bmap(void *v)
+{
+    struct vop_bmap_args       /* {
+                                * struct vnode *a_vp;
+                                * daddr_t  a_bn;
+                                * struct vnode **a_vpp;
+                                * daddr_t *a_bnp;
+                                * int *a_runp;
+                                * } */ *ap = v;
+    struct vcache *vcp = VTOAFS(ap->a_vp);
+
+    AFS_STATCNT(afs_bmap);
+
+    /* borrowed from DARWIN--why notyet? */
+    if (ap->a_bnp) {
+       *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE);
+    }
+    if (ap->a_vpp) {
+       *ap->a_vpp = ap->a_vp;
+    }
+    if (ap->a_runp != NULL)
+       *ap->a_runp = 0;
+#ifdef notyet
+    if (ap->a_runb != NULL)
+       *ap->a_runb = 0;
+#endif
+
+    return 0;
+}
+
+int
+afs_nbsd_strategy(void *v)
+{
+    struct vop_strategy_args   /* {
+                                * struct buf *a_bp;
+                                * } */ *ap = v;
+    struct buf *abp = ap->a_bp;
+    struct uio tuio;
+    struct iovec tiovec[1];
+    struct vcache *tvc = VTOAFS(abp->b_vp);
+    afs_ucred_t credp = osi_curcred();
+    long len = abp->b_bcount;
+    int code;
+
+    AFS_STATCNT(afs_strategy);
+
+    tuio.afsio_iov = tiovec;
+    tuio.afsio_iovcnt = 1;
+    tuio.afsio_resid = len;
+    tiovec[0].iov_base = abp->b_un.b_addr;
+    tiovec[0].iov_len = len;
+    UIO_SETUP_SYSSPACE(&tuio);
+
+    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));
+    return code;
+}
+
+int
+afs_nbsd_print(void *v)
+{
+    struct vop_print_args      /* {
+                                * struct vnode *a_vp;
+                                * } */ *ap = v;
+    struct vnode *vp = ap->a_vp;
+    struct vcache *vc = VTOAFS(ap->a_vp);
+
+    printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell,
+          (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode,
+          (int)vc->f.fid.Fid.Unique);
+    lockmgr_printinfo(&vc->rwlock);
+    printf("\n");
+    return 0;
+}
+
+int
+afs_nbsd_islocked(void *v)
+{
+    struct vop_islocked_args   /* {
+                                * struct vnode *a_vp;
+                                * } */ *ap = v;
+    return (genfs_islocked(v));
+}
+
+/*
+ * Return POSIX pathconf information applicable to ufs filesystems.
+ */
+int
+afs_nbsd_pathconf(void *v)
+{
+    struct vop_pathconf_args   /* {
+                                * struct vnode *a_vp;
+                                * int a_name;
+                                * int *a_retval;
+                                * } */ *ap = v;
+    AFS_STATCNT(afs_cntl);
+    switch (ap->a_name) {
+    case _PC_LINK_MAX:
+       *ap->a_retval = LINK_MAX;
+       break;
+    case _PC_NAME_MAX:
+       *ap->a_retval = NAME_MAX;
+       break;
+    case _PC_PATH_MAX:
+       *ap->a_retval = PATH_MAX;
+       break;
+    case _PC_CHOWN_RESTRICTED:
+       *ap->a_retval = 1;
+       break;
+    case _PC_NO_TRUNC:
+       *ap->a_retval = 1;
+       break;
+    case _PC_PIPE_BUF:
+       return EINVAL;
+       break;
+    default:
+       return EINVAL;
+    }
+    return 0;
+}
+
+extern int
+  afs_lockctl(struct vcache *avc, struct AFS_FLOCK *af, int acmd,
+             afs_ucred_t *acred, pid_t clid);
+
+/*
+ * Advisory record locking support (fcntl() POSIX style)
+ */
+int
+afs_nbsd_advlock(void *v)
+{
+    struct vop_advlock_args    /* {
+                                * struct vnode *a_vp;
+                                * caddr_t  a_id;
+                                * int  a_op;
+                                * struct flock *a_fl;
+                                * int  a_flags;
+                                * } */ *ap = v;
+    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;
+}
index cf7bfa1..1bccc22 100644 (file)
@@ -131,7 +131,7 @@ afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs)
     attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
        attrs->va_ctime.tv_nsec = 0;
     attrs->va_gen = hgetlo(avc->f.m.DataVersion);
-#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV)
+#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV)
     attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec =
        attrs->va_ctime.tv_nsec =
        (hgetlo(avc->f.m.DataVersion) & 0x7ffff) * 1000;
index 69ead8d..9f52a37 100644 (file)
@@ -17,7 +17,7 @@
 #include "afs/param.h"
 
 
-#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_OBSD_ENV)
+#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD_ENV)
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* statistics */
index f2a9ed6..6b5b509 100644 (file)
@@ -889,6 +889,13 @@ afs_UFSRead(register struct vcache *avc, struct uio *auio,
            code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp);
            VOP_UNLOCK(tfile->vnode, 0, curthread);
            AFS_GLOCK();
+#elif defined(AFS_NBSD_ENV)
+           AFS_GUNLOCK();
+           VOP_LOCK(tfile->vnode, LK_EXCLUSIVE);
+           code = VOP_READ(tfile->vnode, &tuio, 0, afs_osi_credp);
+           VOP_UNLOCK(tfile->vnode, 0);
+           AFS_GLOCK();
+
 #elif defined(AFS_XBSD_ENV)
            AFS_GUNLOCK();
            VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc);
index 779f3d0..4e00dfd 100644 (file)
 #include "afs/afs_cbqueue.h"
 #include "afs/nfsclient.h"
 #include "afs/afs_osidnlc.h"
+#if defined(AFS_NBSD40_ENV)
+#include <ufs/ufs/ufs_extern.h> /* direct_pool */
+#endif
 
-
-#if    defined(AFS_HPUX1122_ENV)
+#if defined(AFS_HPUX1122_ENV)
 #define DIRPAD 7
+#elif defined(AFS_NBSD40_ENV)
+#define DIRPAD 4
 #else
 #define DIRPAD 3
 #endif
@@ -99,6 +103,7 @@ BlobScan(struct dcache * afile, afs_int32 ablob)
     /* never get here */
 }
 
+
 #if !defined(AFS_LINUX20_ENV)
 /* Changes to afs_readdir which affect dcache or vcache handling or use of
  * bulk stat data should also be reflected in the Linux specific verison of
@@ -141,6 +146,11 @@ struct min_direct {                /* miniature direct structure */
     u_short d_reclen;
     u_char d_type;
     u_char d_namlen;
+#elif defined(AFS_NBSD40_ENV)
+    ino_t d_fileno;            /* file number of entry */
+    uint16_t d_reclen;         /* length of this record */
+    uint16_t d_namlen;         /* length of string in d_name */
+    uint8_t  d_type;           /* file type, see below */
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
     afs_uint32 d_fileno;
     u_short d_reclen;
@@ -490,20 +500,30 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio,
                    auio, code);
 #else /* AFS_SGI_ENV */
     AFS_MOVE_UNLOCK();
-    AFS_UIOMOVE((char *)&sdirEntry, sizeof(sdirEntry), UIO_READ, auio, code);
-
+#if defined(AFS_NBSD40_ENV)
+    {
+       struct dirent *dp;
+       dp = (struct dirent *) pool_get(&ufs_direct_pool, PR_WAITOK);
+       dp->d_ino =  (Volume << 16) + ntohl(Vnode);
+       FIXUPSTUPIDINODE(dp->d_ino);
+       dp->d_reclen = rlen;
+       strcpy(dp->d_name, de->name);
+       AFS_UIOMOVE((char*) dp, sizeof(struct dirent), UIO_READ, auio, code);
+       pool_put(&ufs_direct_pool, dp);
+    }
+#else
+    AFS_UIOMOVE((char *) &sdirEntry, sizeof(sdirEntry), UIO_READ, auio, code);
     if (code == 0) {
        AFS_UIOMOVE(de->name, slen, UIO_READ, auio, code);
     }
-
     /* pad out the remaining characters with zeros */
     if (code == 0) {
        AFS_UIOMOVE(bufofzeros, ((slen + 1 + DIRPAD) & ~DIRPAD) - slen,
                    UIO_READ, auio, code);
     }
+#endif
     AFS_MOVE_LOCK();
 #endif /* AFS_SGI_ENV */
-
     /* pad out the difference between rlen and slen... */
     if (DIRSIZ_LEN(slen) < rlen) {
        AFS_MOVE_UNLOCK();
@@ -768,7 +788,6 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred)
            goto dirend;
        }
        /* by here nde is set */
-
        /* Do we have enough user space to carry out our mission? */
 #if defined(AFS_SGI_ENV)
        n_slen = strlen(nde->name) + 1; /* NULL terminate */
index 4bc98f4..a79e52a 100644 (file)
@@ -86,7 +86,11 @@ int afs_ustrategy(register struct buf *abp)
 #else
        tuio.afsio_offset = DEV_BSIZE * abp->b_blkno;
 #endif
+#if defined(AFS_NBSD40_ENV)
+       UIO_SETUP_SYSSPACE(&tuio);
+#else
        tuio.afsio_seg = AFS_UIOSYS;
+#endif
 #ifdef AFS_UIOFMODE
        tuio.afsio_fmode = 0;
 #endif
@@ -152,7 +156,11 @@ int afs_ustrategy(register struct buf *abp)
 #else
        tuio.afsio_offset = DEV_BSIZE * abp->b_blkno;
 #endif
+#if defined(AFS_NBSD40_ENV)
+       UIO_SETUP_SYSSPACE(&tuio);
+#else
        tuio.afsio_seg = AFS_UIOSYS;
+#endif
 #ifdef AFS_UIOFMODE
        tuio.afsio_fmode = 0;
 #endif
index a33e12d..da3ca8e 100644 (file)
@@ -516,6 +516,12 @@ afs_UFSWrite(register struct vcache *avc, struct uio *auio, int aio,
        code = VOP_WRITE(tfile->vnode, &tuio, 0, afs_osi_credp);
        VOP_UNLOCK(tfile->vnode, 0, curthread);
        AFS_GLOCK();
+#elif defined(AFS_NBSD_ENV)
+       AFS_GUNLOCK();
+       VOP_LOCK(tfile->vnode, LK_EXCLUSIVE);
+       code = VOP_WRITE(tfile->vnode, &tuio, 0, afs_osi_credp);
+       VOP_UNLOCK(tfile->vnode, 0);
+       AFS_GLOCK();
 #elif defined(AFS_XBSD_ENV)
        AFS_GUNLOCK();
        VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc);
index 5b86807..de8e774 100644 (file)
@@ -1431,7 +1431,9 @@ extern int afsd_dynamic_vcaches;
  * Linux uses the kernel cred structure if available, with the
  * wrappers defined in LINUX/osi_machdep.h
  */
-#if !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
+#if defined(AFS_NBSD40_ENV)
+/* in osi_machdep.h as expected */
+#elif !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
 #define afs_cr_uid(cred) ((cred)->cr_uid)
 #define afs_cr_gid(cred) ((cred)->cr_gid)
 #define afs_cr_ruid(cred) ((cred)->cr_ruid)
index 0ed6116..9ca08e3 100644 (file)
@@ -391,7 +391,7 @@ afs_InitCacheInfo(register char *afile)
        struct statvfs64 st;
 #elif  defined(AFS_HPUX102_ENV)
        struct k_statvfs st;
-#elif  defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) ||defined(AFS_HPUX100_ENV)
+#elif  defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX100_ENV) || defined(AFS_NBSD40_ENV)
        struct statvfs st;
 #elif defined(AFS_DARWIN80_ENV)
        struct vfsstatfs st;
index 9f4784e..e482a63 100644 (file)
@@ -86,7 +86,8 @@ osi_Init(void)
 #endif
 #if defined(AFS_XBSD_ENV)
        /* Can't just invent one, must use crget() because of mutex */
-       afs_osi_credp = crdup(osi_curcred());
+       afs_osi_credp =
+         crdup(osi_curcred());
 #else
        memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
 #if defined(AFS_LINUX26_ENV)
@@ -286,7 +287,7 @@ shutdown_osi(void)
     }
 }
 
-#ifndef AFS_OBSD_ENV
+#if !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD40_ENV)
 int
 afs_osi_suser(void *cr)
 {
index 20e3c54..7ada6e9 100644 (file)
 #include <sys/condvar.h>
 #endif
 
+#ifdef AFS_NBSD_ENV
+#include <sys/lock.h>
+#endif
+
 #ifdef AFS_LINUX20_ENV
 #ifndef _LINUX_CODA_FS_I
 #define _LINUX_CODA_FS_I
@@ -116,7 +120,7 @@ struct afs_osi_WaitHandle {
 /*
  * Alloc declarations.
  */
-#if !defined(AFS_OBSD44_ENV)
+#if !defined(AFS_OBSD44_ENV) && !defined(AFS_NBSD_ENV)
 #define afs_osi_Alloc_NoSleep afs_osi_Alloc
 #endif
 
index bc0fa20..f5e6d8b 100644 (file)
@@ -29,8 +29,6 @@
 
 afs_lock_t osi_fsplock;
 
-
-
 static struct osi_packet {
     struct osi_packet *next;
 } *freePacketList = NULL, *freeSmallList;
@@ -42,7 +40,7 @@ struct osimem {
     struct osimem *next;
 };
 
-
+#if !defined(AFS_NBSD_ENV)
 void *
 afs_osi_Alloc(size_t x)
 {
@@ -124,8 +122,6 @@ afs_osi_FreeStr(char *x)
     afs_osi_Free(x, strlen(x) + 1);
 }
 
-
-
 /* free space allocated by AllocLargeSpace.  Also called by mclput when freeing
  * a packet allocated by osi_NetReceive. */
 
@@ -222,7 +218,7 @@ osi_AllocSmallSpace(size_t size)
     return (char *)tp;
 }
 
-
+#endif /* !AFS_NBSD_ENV */
 
 void
 shutdown_osinet(void)
@@ -257,4 +253,3 @@ shutdown_osinet(void)
                 afs_stats_cmperf.SmallBlocksActive);
     }
 }
-
index ec02da4..8a3d94f 100644 (file)
@@ -224,6 +224,9 @@ afs_setpag(void)
     code = AddPag(genpag(), credpp);
 #elif  defined(AFS_FBSD_ENV)
     code = AddPag(td, genpag(), &td->td_ucred);
+#elif   defined(AFS_NBSD40_ENV)
+    /* XXXX won't work */
+    code = AddPag(p, genpag(), (afs_ucred_t **) osi_curcred());
 #elif  defined(AFS_XBSD_ENV)
     code = AddPag(p, genpag(), &p->p_rcred);
 #elif  defined(AFS_AIX41_ENV)
@@ -430,6 +433,8 @@ AddPag(afs_int32 aval, afs_ucred_t **credpp)
     AFS_STATCNT(AddPag);
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
     if ((code = setpag(p, credpp, aval, &newpag, 0)))
+#elif defined(AFS_NBSD40_ENV)
+    if ((code = setpag(p, (void *) credpp, aval, &newpag, 0)))
 #else
     if ((code = setpag(credpp, aval, &newpag, 0)))
 #endif
@@ -552,7 +557,15 @@ osi_get_group_pag(afs_ucred_t *cred)
     gids = crgetgroups(cred);
     ngroups = crgetngroups(cred);
 #endif
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+#if defined(AFS_NBSD40_ENV)
+#warning com afs_ucred_t w/magic won't work
+    if (cred == NOCRED || cred == FSCRED)
+      return NOPAG;
+    if (osi_crngroups(cred) < 3)
+      return NOPAG;
+    g0 = osi_crgroupbyid(cred, 0);
+    g1 = osi_crgroupbyid(cred, 1);
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
     if (cred == NOCRED || cred == FSCRED)
        return NOPAG;
     if (cred->cr_ngroups < 3)
index 38658d9..b17f425 100644 (file)
 #ifdef AFS_FBSD50_ENV
 #include "h/sysproto.h"
 #endif
+#ifdef AFS_NBSD40_ENV
+#include <sys/ioctl.h>
+#include <sys/ioccom.h>
+#endif
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* afs statistics */
 #include "afs/vice.h"
@@ -818,7 +822,11 @@ afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
     struct file *fd;
 
     AFS_STATCNT(afs_xioctl);
+#   if defined(AFS_NBSD40_ENV)
+     fdp = p->l_proc->p_fd;
+#   else
     fdp = p->p_fd;
+#endif
     if ((u_int) uap->fd >= fdp->fd_nfiles
        || (fd = fdp->fd_ofiles[uap->fd]) == NULL)
        return EBADF;
@@ -861,6 +869,9 @@ afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
        return ioctl(p, uap);
 # elif defined(AFS_OBSD_ENV)
        code = sys_ioctl(p, uap, retval);
+# elif defined(AFS_NBSD_ENV)
+           struct lwp *l = osi_curproc();
+           code = sys_ioctl(l, uap, retval);
 # endif
     }
 
@@ -974,7 +985,7 @@ afs_pioctl(afs_proc_t *p, void *args, int *retval)
     } *uap = (struct a *)args;
 
     AFS_STATCNT(afs_pioctl);
-# ifdef AFS_DARWIN80_ENV
+# if defined(AFS_DARWIN80_ENV) || defined(AFS_NBSD40_ENV)
     return (afs_syscall_pioctl
            (uap->path, uap->cmd, uap->cmarg, uap->follow,
             kauth_cred_get()));
@@ -1863,6 +1874,9 @@ DECL_PIOCTL(PSetTokens)
 # elif defined(AFS_FBSD_ENV)
        struct thread *p = curthread;
        char *procname = p->td_proc->p_comm;
+# elif defined(AFS_NBSD40_ENV)
+       afs_proc_t *p = curproc;        /* XXX */
+       char *procname = p->l_proc->p_comm;
 # else
        afs_proc_t *p = curproc;        /* XXX */
        char *procname = p->p_comm;
index cbaef5b..221dcd2 100644 (file)
@@ -553,6 +553,7 @@ extern const afs_ucred_t *afs_osi_proc2cred(afs_proc_t * pr);
 extern afs_lock_t osi_fsplock;
 extern afs_lock_t osi_flplock;
 #endif
+
 extern void *afs_osi_Alloc_debug(size_t x, char *func, int line);
 #ifndef afs_osi_Alloc_NoSleep
 extern void *afs_osi_Alloc_NoSleep(size_t x);
@@ -708,6 +709,10 @@ extern int usr_setpag(afs_ucred_t **cred, afs_uint32 pagvalue,
 #   if defined(AFS_FBSD_ENV)
 extern int setpag(struct thread *td, struct ucred **cred, afs_uint32 pagvalue,
                  afs_uint32 * newpag, int change_parent);
+
+#   elif defined(AFS_NBSD40_ENV)
+extern int setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue,
+                 afs_uint32 * newpag, int change_parent);
 #   else
 extern int setpag(afs_proc_t *proc, struct ucred **cred, afs_uint32 pagvalue,
                  afs_uint32 * newpag, int change_parent);
@@ -899,6 +904,8 @@ extern int copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst);
 extern int afs3_syscall(afs_proc_t *p, void *args, unsigned int *retval);
 #elif defined(AFS_FBSD_ENV)
 extern int afs3_syscall(struct thread *p, void *args);
+#elif defined(AFS_NBSD40_ENV)
+extern int afs3_syscall(struct lwp *p, void *args);
 #else
 extern int afs3_syscall(afs_proc_t *p, void *args, long *retval);
 #endif
index 6b4a02c..7b5949c 100644 (file)
@@ -1566,6 +1566,13 @@ afs_SetServerPrefs(struct srvAddr *sa)
        for (ifa = in_ifaddr.tqh_first; ifa; ifa = ifa->ia_list.tqe_next)
            afsi_SetServerIPRank(sa, ifa);
     }
+#elif defined(AFS_NBSD40_ENV)
+     {
+       extern struct in_ifaddrhead in_ifaddrhead;
+       struct in_ifaddr *ifa;
+       for (ifa = in_ifaddrhead.tqh_first; ifa; ifa = ifa->ia_list.tqe_next)
+           afsi_SetServerIPRank(sa, ifa);
+     }
 #else
     {
        struct in_ifaddr *ifa;
index bc73da7..1236b2d 100644 (file)
@@ -507,6 +507,13 @@ afs3_syscall(struct thread *p, void *args)
        long parm6;
     } *uap = (struct a *)args;
     long *retval;
+#elif defined(AFS_NBSD40_ENV)
+int
+afs3_syscall(struct lwp *p, void *args)
+{
+    /* see osi_machdep.h */
+    struct afs_sysargs *uap = (struct afs_sysargs *) args;
+    long *retval;
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
 int
 afs3_syscall(afs_proc_t *p, void *args, long *retval)
@@ -680,6 +687,15 @@ Afs_syscall()
      */
        osi_InitGlock();
 #endif
+
+#if defined(AFS_NBSD40_ENV)
+       if (SCARG(uap, syscall) == AFSCALL_CALL) {
+           code =
+               afs_syscall_call(SCARG(uap, parm1), SCARG(uap, parm2),
+                                 SCARG(uap, parm3), SCARG(uap, parm4),
+                                 SCARG(uap, parm5), SCARG(uap, parm6));
+       } else if (SCARG(uap, syscall) == AFSCALL_SETPAG) {
+#else
        if (uap->syscall == AFSCALL_CALL) {
            code =
                afs_syscall_call(uap->parm1, uap->parm2, uap->parm3,
@@ -692,6 +708,7 @@ Afs_syscall()
            }
 #endif
        } else if (uap->syscall == AFSCALL_SETPAG) {
+#endif
 #ifdef AFS_SUN5_ENV
            register proc_t *procp;
 
@@ -710,7 +727,12 @@ Afs_syscall()
 #endif
            AFS_GUNLOCK();
 #endif
-       } else if (uap->syscall == AFSCALL_PIOCTL) {
+       } else if
+#if defined(AFS_NBSD40_ENV)
+               (SCARG(uap, syscall) == AFSCALL_PIOCTL) {
+#else
+           (uap->syscall == AFSCALL_PIOCTL) {
+#endif
            AFS_GLOCK();
 #if defined(AFS_SUN5_ENV)
            code =
@@ -724,6 +746,11 @@ Afs_syscall()
            code =
                afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
                                   uap->parm4, kauth_cred_get());
+#elif defined(AFS_NBSD40_ENV)
+           code =
+               afs_syscall_pioctl(SCARG(uap, parm1), SCARG(uap, parm2),
+                                  SCARG(uap, parm3), SCARG(uap, parm4),
+                                  kauth_cred_get());
 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
            code =
                afs_syscall_pioctl(uap->parm1, uap->parm2, uap->parm3,
@@ -736,20 +763,32 @@ Afs_syscall()
                                   (int) uap->parm4);
 #endif
            AFS_GUNLOCK();
+
+#ifdef AFS_NBSD40_ENV
+           } else if (SCARG(uap, syscall) == AFSCALL_ICREATE) {
+               struct iparam iparams;
+               code = copyin_iparam((char *) SCARG(uap, parm3), &iparams);
+#else
        } else if (uap->syscall == AFSCALL_ICREATE) {
            struct iparam iparams;
 
            code = copyin_iparam((char *)uap->parm3, &iparams);
+#endif
            if (code) {
 #if defined(KERNEL_HAVE_UERROR)
                setuerror(code);
 #endif
            } else {
-#ifdef AFS_SUN5_ENV
+#if defined(AFS_SUN5_ENV)
                code =
                    afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
                                        iparams.param2, iparams.param3,
                                        iparams.param4, rvp, CRED());
+#elif defined(AFS_NBSD40_ENV)
+
+               code = afs_syscall_create(SCARG(uap, parm1), SCARG(uap, parm2),
+                                         SCARG(uap, parm3), SCARG(uap, parm4),
+                                         retval);
 #else
                code =
                    afs_syscall_icreate(uap->parm1, uap->parm2, iparams.param1,
@@ -761,11 +800,18 @@ Afs_syscall()
                        );
 #endif /* AFS_SUN5_ENV */
            }
-       } else if (uap->syscall == AFSCALL_IOPEN) {
-#ifdef AFS_SUN5_ENV
+#if defined(AFS_NBSD40_ENV)
+           } else if (SCARG(uap, syscall) == AFSCALL_IOPEN) {
+#else
+           } else if (uap->syscall == AFSCALL_IOPEN) {
+#endif /* !AFS_NBSD40_ENV */
+#if defined(AFS_SUN5_ENV)
            code =
                afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3, rvp,
                                  CRED());
+#elif defined(AFS_NBSD40_ENV)
+           code = afs_syscall_iopen(SCARG(uap, parm1), SCARG(uap, parm2),
+                                    SCARG(uap, parm3), retval);
 #else
            code = afs_syscall_iopen(uap->parm1, uap->parm2, uap->parm3
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
@@ -773,25 +819,56 @@ Afs_syscall()
 #endif
                );
 #endif /* AFS_SUN5_ENV */
+#if defined(AFS_NBSD40_ENV)
+        } else if (SCARG(uap, syscall) == AFSCALL_IDEC) {
+#else
        } else if (uap->syscall == AFSCALL_IDEC) {
+#endif
+#if defined(AFS_NBSD40_ENV)
+           code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
+                                        SCARG(uap, parm3), -1);
+#else
+
+
            code =
                afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, -1
-#ifdef AFS_SUN5_ENV
+#if defined(AFS_SUN5_ENV)
                                    , rvp, CRED()
 #endif
                    );
-       } else if (uap->syscall == AFSCALL_IINC) {
+
+#endif /* !AFS_NBSD40_ENV */
+#if defined(AFS_NBSD40_ENV)
+           } else if (SCARG(uap, syscall) == AFSCALL_IINC) {
+#else
+           } else if (uap->syscall == AFSCALL_IINC) {
+#endif
+#if defined(AFS_NBSD40_ENV)
+             code = afs_syscall_iincdec(SCARG(uap, parm1), SCARG(uap, parm2),
+                                        SCARG(uap, parm3), 1);
+#else
            code =
                afs_syscall_iincdec(uap->parm1, uap->parm2, uap->parm3, 1
 #ifdef AFS_SUN5_ENV
                                    , rvp, CRED()
 #endif
                    );
-       } else if (uap->syscall == AFSCALL_ICL) {
+#endif /* !AFS_NBSD40_ENV */
+#if defined(AFS_NBSD40_ENV)
+           } else if (SCARG(uap, syscall) == AFSCALL_ICL) {
+#else
+           } else if (uap->syscall == AFSCALL_ICL) {
+#endif
            AFS_GLOCK();
            code =
+#if defined(AFS_NBSD40_ENV)
+             Afscall_icl(SCARG(uap, parm1), SCARG(uap, parm2),
+                         SCARG(uap, parm3), SCARG(uap, parm4),
+                         SCARG(uap, parm5), retval);
+#else
                Afscall_icl(uap->parm1, uap->parm2, uap->parm3, uap->parm4,
                            uap->parm5, (long *)retval);
+#endif /* !AFS_NBSD40_ENV */
            AFS_GUNLOCK();
 #ifdef AFS_LINUX20_ENV
            if (!code) {
index f5f9141..54207f6 100644 (file)
@@ -1015,7 +1015,7 @@ afs_NewVCache_int(struct VenusFid *afid, struct server *serverp, int seq)
     }
     vcachegen++;
     /* it should now be safe to drop the xvcache lock */
-#ifdef AFS_OBSD_ENV
+#if defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV)
     ReleaseWriteLock(&afs_xvcache);
     AFS_GUNLOCK();
     afs_obsd_getnewvnode(tvc); /* includes one refcount */
@@ -1895,7 +1895,6 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        goto loop;
 #endif
     }
-
     if (tvc) {
        if (cached)
            *cached = 1;
@@ -2006,6 +2005,14 @@ afs_GetVCache(register struct VenusFid *afid, struct vrequest *areq,
        uvm_vnp_uncache(vp);
        if (!iheldthelock)
            VOP_UNLOCK(vp, 0, curproc);
+#elif defined(AFS_NBSD40_ENV)
+       iheldthelock = VOP_ISLOCKED(vp);
+       if (!iheldthelock) {
+           VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+       }
+       uvm_vnp_uncache(vp);
+       if (!iheldthelock)
+           VOP_UNLOCK(vp, 0);
 #endif
     }
 #endif
index 4cd68b6..fb85fb3 100644 (file)
@@ -21,7 +21,7 @@
 #include "afs/stds.h"
 #ifdef AFS_AIX_ENV
 #include "osi_vfs.h"
-#elif defined(AFS_HPUX_ENV)
+#elif defined(AFS_HPUX_ENV) || defined(AFS_NBSD_ENV)
 #include "osi_vfs.h"
 #endif
 #if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
index d8ba99a..376bbf4 100644 (file)
@@ -125,6 +125,10 @@ typedef unsigned int afs_lock_tracker_t;
 typedef unsigned int afs_lock_tracker_t;
 # define MyPidxx (curproc->p_pid )
 # define MyPidxx2Pid(x) (x)
+#elif defined(AFS_NBSD40_ENV)
+typedef unsigned int afs_lock_tracker_t;
+#define MyPidxx osi_getpid() /* XXX could generalize this (above) */
+#define MyPidxx2Pid(x) (x)
 #else
 typedef unsigned int afs_lock_tracker_t;
 # define MyPidxx (u.u_procp->p_pid )
index 0daeca6..32e2848 100644 (file)
 # include <sys/ioctl.h>
 # include <sys/timeout.h>
 
+#elif defined(AFS_NBSD40_ENV)
+# include <sys/errno.h>
+# include <sys/types.h>
+# include <sys/mount.h> /* may define MOUNT_AFS */
+# include <sys/param.h>
+# include <sys/systm.h>
+# include <sys/conf.h>
+# include <sys/exec.h>
+# include <sys/lock.h>
+# include <sys/syscall.h>
+# include <sys/syscallargs.h>
+# include <sys/queue.h>
+# include <sys/resourcevar.h>
+# include <sys/kernel.h>
+# include <sys/proc.h>
+# include <sys/time.h>
+# include <sys/filedesc.h>
+# include <sys/exec.h>
+# include <sys/lock.h>
+# include <sys/syscall.h>
+# include <sys/syscallargs.h>
+# include <sys/queue.h>
+# include <sys/resourcevar.h>
+# include <sys/kernel.h>
+# include <sys/proc.h>
+# include <sys/time.h>
+# include <sys/filedesc.h>
+# include <sys/file.h>
+# include <sys/socket.h>
+# include <sys/socketvar.h>
+# include <sys/dirent.h>
+# include <sys/user.h>
+# include <sys/kauth.h>
+# include <sys/uio.h>
+# include <sys/buf.h>
+# include <sys/stat.h>
+# include <sys/file.h>
+# include <sys/namei.h>
+# include <sys/socket.h>
+# include <sys/socketvar.h>
+# include <sys/dirent.h>
+# include <sys/user.h>
+# include <sys/kauth.h>
+# include <sys/uio.h>
+# include <sys/buf.h>
+# include <sys/stat.h>
+# include <sys/file.h>
+# include <sys/namei.h>
+# include <sys/vnode.h>
+# include <ufs/ffs/fs.h>
+# include <ufs/ufs/quota.h>
+# include <ufs/ufs/inode.h>
+# include <ufs/ufs/extattr.h>
+# include <ufs/ufs/ufsmount.h>
+# ifndef MLEN
+#  if 0
+#   include <sys/mbuf.h>
+#  endif /* 0 */
+#  include <net/if.h>
+# endif /* !MLEN */
+# include <sys/protosw.h>
+# include <sys/ioctl.h>
+
 #elif defined(AFS_LINUX22_ENV)
 # include <linux/version.h>
 # ifdef HAVE_LINUX_CONFIG_H
@@ -234,7 +297,8 @@ typedef unsigned short etap_event_t;
 #  include "limits.h"
 # endif
 
-# if defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_FBSD_ENV)
+# if defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || \
+  defined(AFS_FBSD_ENV) || defined(AFS_NBSD40_ENV)
 #  include "h/dirent.h"
 #  ifdef       AFS_SUN5_ENV
 #   include "h/sysmacros.h"
@@ -244,7 +308,8 @@ typedef unsigned short etap_event_t;
 #  include "h/dir.h"
 # endif /* SGI || SUN || HPUX */
 
-# if !defined(AFS_SGI64_ENV) && !defined(AFS_FBSD_ENV) && !defined(AFS_DARWIN80_ENV)
+# if !defined(AFS_SGI64_ENV) && !defined(AFS_FBSD_ENV) && !defined(AFS_DARWIN80_ENV) && \
+  !defined(AFS_NBSD40_ENV)
 #  include "h/user.h"
 # endif /* AFS_SGI64_ENV */
 # define       MACH_USER_API   1
@@ -287,7 +352,9 @@ struct vop_getwritemount_args;
 #  endif
 #  include <sys/vnode.h>
 #  include <sys/queue.h>
-#  include <sys/malloc.h>
+#  ifndef AFS_NBSD40_ENV
+#   include <sys/malloc.h>
+#  endif
 #  ifndef AFS_FBSD_ENV
 #   include <sys/ubc.h>
 #   define timeout_fcn_t mach_timeout_fcn_t
@@ -311,15 +378,17 @@ MALLOC_DECLARE(M_AFS);
 #   include <ufs/ffs/fs.h>
 #  endif
 # else
-#  include "h/vfs.h"
-#  include "h/vnode.h"
+#  ifndef AFS_NBSD40_ENV
+#   include "h/vfs.h"
+#   include "h/vnode.h"
+#  endif
 #  ifdef       AFS_SUN5_ENV
 #   include "h/fs/ufs_inode.h"
 #   include "h/fs/ufs_mount.h"
 #  else
-#   if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
+#   if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) && !defined(AFS_NBSD40_ENV)
 #    include "ufs/inode.h"
-#    if !defined(AFS_SGI_ENV) && !defined(AFS_HPUX_ENV)
+#    if !defined(AFS_SGI_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_NBSD40_ENV)
 #     include "ufs/mount.h"
 #    endif /* !AFS_HPUX_ENV */
 #   endif /* !AFS_AIX32_ENV */
@@ -356,7 +425,7 @@ MALLOC_DECLARE(M_AFS);
 #  include "h/tty.h"
 # endif
 
-# if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV)
+# if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_SUN5_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) && !defined(AFS_NBSD40_ENV)
 
 #  include "h/text.h"
 # endif
index d289531..33a2c28 100644 (file)
@@ -247,9 +247,17 @@ afsd_call_syscall(long param1, long param2, long param3, long param4, long param
                param5, param6, param7);
 # endif /* !AFS_DARWIN80_ENV */
 
-    if (afsd_debug)
+    if (afsd_debug) {
+#ifdef AFS_NBSD40_ENV
+        char *s = strerror(errno);
+        printf("SScall(%d, %d, %d)=%d (%d, %s)\n", AFS_SYSCALL, AFSCALL_CALL,
+                param1, error, errno, s);
+#else
        printf("SScall(%d, %d, %ld)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1,
               error);
+#endif
+    }
+
     return (error);
 }
 #else /* !AFS_SGI_ENV && !AFS_AIX32_ENV */
index ba88ab0..0c685c4 100644 (file)
@@ -9,11 +9,15 @@
 #define AFS_64BIT_CLIENT 1
 
 #define AFS_MOUNT_AFS "afs"    /* The name of the filesystem type. */
-#define AFS_SYSCALL 210
+#define AFS_SYSCALL 318 /* 210 */
 
+#if 0
+/* including this file before sysincludes.h is canonical, but
+ * NBSD40's mount.h defines MOUNT_AFS */
 #ifndef        MOUNT_AFS
 #define        MOUNT_AFS AFS_MOUNT_AFS
 #endif
+#endif
 
 #define AFS_XBSD_ENV 1         /* {Free,Open,Net}BSD */
 
 #define ICHG 0x0040
 #define IMOD 0x0080
 
-#define IN_LOCK(ip)     lockmgr(&ip->i_lock, LK_EXCLUSIVE, \
-                                NULL, curproc)
-#define IN_UNLOCK(ip)   lockmgr(&ip->i_lock, LK_RELEASE, \
-                                NULL, curproc)
+#define RXK_LISTENER_ENV      1
+
 
 #include <afs/afs_sysnames.h>
 
 /* Extra kernel definitions (from kdefs file) */
 #ifdef _KERNEL
 #define AFS_GLOBAL_SUNLOCK        1
+#define        AFS_SHORTGID    1       /* are group id's short? */
+#endif
+
+/* apparently not in 40 */
+#define inline
+
+#ifdef _KERNEL_DEPRECATED
+#define AFS_GLOBAL_SUNLOCK        1
 #define        AFS_VFS34       1       /* What is VFS34??? */
 #define        AFS_SHORTGID    1       /* are group id's short? */
 #define        afsio_iov       uio_iov
@@ -112,7 +122,7 @@ enum vcexcl { NONEXCL, EXCL };
 #endif /* KERNEL */
 
 #endif /* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ && !defined(IGNORE_STDS_H) */ 
-#endif /* _KERNEL */
+#endif /* _KERNEL_DEPRECATED */
 
 #else /* !defined(UKERNEL) */
 
index 3c9dc78..403284c 100644 (file)
@@ -307,6 +307,9 @@ typedef struct afsUUID afsUUID;
 #elif defined(AFS_SGI_ENV) || defined(AFS_USR_SGI_ENV)
 #define static_inline static
 #define hdr_static_inline(x) x
+#elif defined(AFS_NBSD_ENV)
+#define static_inline static __inline __attribute__((always_inline))
+#define hdr_static_inline(x) static __inline __attribute__((always_inline)) x
 #else
 #define static_inline static inline
 #define hdr_static_inline(x) static inline x
index 72fa2b5..74c8c63 100644 (file)
@@ -32,8 +32,15 @@ AFS_OS_NONFSOBJS = \
 
 
 # System specific build commands and flags
-KDEFS=-Wall -fformat-extensions -ansi -nostdinc -I/usr/include -D_KERNEL \
-       -elf -mpreferred-stack-boundary=2 -I/usr/src/sys/sys -I../afs
+KSRC = @BSD_KERNEL_PATH@
+KBLD = @BSD_KERNEL_BUILD@
+KARCHFLAGS = -march=pentiumpro -mtune=pentiumpro -mtune=pentiumpro
+KOPTFLAGS = -D_KERNEL -DLKM -D_LKM -DDEBUG -DLOCKDEBUG
+KDEFS=-Wall -ansi -nostdinc -I/usr/include \
+       ${KARCHFLAGS} ${KOPTFLAGS} \
+       -ffreestanding -Wno-pointer-sign -Wno-strict-aliasing \
+       -I${KSRC} -I${KSRC}/sys \
+       -I${KBLD} -I../afs
 DBUG = -O2
 DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA -DGETMOUNT
 OPTF=${OPT} 
@@ -42,7 +49,7 @@ CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KDEFS) $(K
 
 
 # Name of directory to hold object files and libraries.
-KOBJ = STATIC
+KOBJ = MODLOAD
 
 # This tells Makefile.common to use it's single directory build target.
 COMPDIRS = single_compdir
@@ -58,15 +65,15 @@ setup:
        ln -fs ../Makefile.common $(KOBJ)/Makefile.common
        ln -fs ../config $(KOBJ)/config
        -$(RM) -f  h net netinet rpc ufs nfs  machine sys vm
-       -ln -fs /usr/src/sys/net net
-       -ln -fs /usr/src/sys/i386/include machine
-       -ln -fs /usr/src/sys/netinet netinet
-       -ln -fs /usr/src/sys/nfs nfs
+       -ln -fs ${KSRC}/net net
+       -ln -fs ${KSRC}/i386/include machine
+       -ln -fs ${KSRC}/netinet netinet
+       -ln -fs ${KSRC}/nfs nfs
        -ln -fs /usr/include/rpc rpc
-       -ln -fs /usr/src/sys/sys sys
-       -ln -fs /usr/src/sys/ufs/ufs ufs
-       -ln -fs /usr/src/sys/sys h
-       -ln -fs /usr/src/sys/vm vm
+       -ln -fs ${KSRC}/sys sys
+       -ln -fs ${KSRC}/ufs/ufs ufs
+       -ln -fs ${KSRC}/sys h
+       -ln -fs ${KSRC}/vm vm
        -touch $(KOBJ)/sec_net.h
 
 
@@ -80,13 +87,14 @@ INST_LIBAFSNONFS = ${DESTDIR}${afskerneldir}/${LIBAFSNONFS}
 DEST_LIBAFS = ${DEST}/root.client/bin/${LIBAFS}
 DEST_LIBAFSNONFS = ${DEST}/root.client/bin/${LIBAFSNONFS}
 
-
+<i386_nbsd40>
 # libafs:      $(LIBAFS) $(LIBAFSNONFS)
-# libafs:      $(LIBAFSNONFS)
+libafs:        $(LIBAFSNONFS)
 # install_libafs:      $(INST_LIBAFS) $(INST_LIBAFSNONFS)
-# install_libafs:      $(INST_LIBAFSNONFS)
+install_libafs:        $(INST_LIBAFSNONFS)
 # dest_libafs: $(DEST_LIBAFS) $(DEST_LIBAFSNONFS)
-# dest_libafs: $(DEST_LIBAFSNONFS)
+dest_libafs:   $(DEST_LIBAFSNONFS)
+<all -i386_nbsd40>
 libafs:
        echo WARNING: No kernel module for ${SYS_NAME}
 
@@ -95,10 +103,11 @@ install_libafs:
 
 dest_libafs:
        echo WARNING: No kernel module for ${SYS_NAME}
+<all>
 
-
-${LIBAFS}: $(AFSAOBJS) $(AFSNFSOBJS)
-       $(LD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS}
+# for now, just skip it
+#${LIBAFS}: $(AFSAOBJS) $(AFSNFSOBJS)
+#      $(LD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS}
 
 ${LIBAFSNONFS}:  $(AFSAOBJS) $(AFSNONFSOBJS)
        $(LD) -r -o ${LIBAFSNONFS} ${AFSAOBJS} ${AFSNONFSOBJS}
index 7c81966..721642e 100644 (file)
 /*
  * rx_kmutex.h - mutex and condition variable macros for kernel environment.
  *
- * MACOS implementation.
+ * Based to the degree possible on FreeBSD implementation (which is by
+ * Garrett Wollman (?) and Jim Rees).  I couldn't rework it as I did for
+ * FreeBSD, because NetBSD doesn't have anything like FreeBSD's  new
+ * locking primitives.  So anyway, these are potentially heavier locks than
+ * the *ahem* locking Jim had in the OpenBSD port, although it looks as
+ * if struct lock is evolving into an adaptive mutex implementation (see
+ * LOCK(9)), which should be reasonable for the code we have today.  The
+ * available optimization would be to replace such a lock with a simple_lock
+ * any place we only consider the current CPU, and could not sleep
+ * (Matt).
  */
 
 #ifndef _RX_KMUTEX_H_
 #define _RX_KMUTEX_H_
 
 #include <sys/lock.h>
-#include <kern/thread.h>
-#include <sys/vm.h>
 
-#define RX_ENABLE_LOCKS         1
+/* You can't have AFS_GLOBAL_SUNLOCK and not RX_ENABLE_LOCKS */
+#define RX_ENABLE_LOCKS 1
 #define AFS_GLOBAL_RXLOCK_KERNEL
 
 /*
  *
  * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup
  * mechanism.  The condition variable itself plays no role; we just use its
- * address as a convenient unique number.
- * 
- * XXX in darwin, both mach and bsd facilities are available. Should really
- * stick to one or the other (but mach locks don't have a _try.....)
+ * address as a convenient unique number.  NetBSD has some improvements in
+ * its versions of these mechanisms.
  */
-#define CV_INIT(cv,a,b,c)
+#define CV_INIT(cv, a, b, c)
 #define CV_DESTROY(cv)
 #define CV_WAIT(cv, lck)    { \
-                               int isGlockOwner = ISAFS_GLOCK(); \
-                               if (isGlockOwner) AFS_GUNLOCK();  \
-                               assert_wait((event_t)(cv), 0);  \
-                               MUTEX_EXIT(lck);        \
-                               thread_block(0);                \
-                               if (isGlockOwner) AFS_GLOCK();  \
-                               MUTEX_ENTER(lck); \
-                           }
+       struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
+       simple_lock(&slock);                                            \
+       int glocked = ISAFS_GLOCK();                                    \
+       if (glocked)                                                    \
+           AFS_GUNLOCK();                                              \
+       MUTEX_EXIT(lck);                                                \
+       ltsleep(cv, PSOCK, "afs_rx_cv_wait", 0, &slock);                \
+       if (glocked)                                                    \
+           AFS_GLOCK();                                                \
+       MUTEX_ENTER(lck);                                               \
+       simple_unlock(&slock);                                          \
+    }
 
-#define CV_TIMEDWAIT(cv,lck,t)  { \
-                               int isGlockOwner = ISAFS_GLOCK(); \
-                               if (isGlockOwner) AFS_GUNLOCK();  \
-                               assert_wait((event_t)(cv), 0);  \
-                               thread_set_timer(t, NSEC_PER_SEC/hz);   \
-                               MUTEX_EXIT(lck);        \
-                               thread_block(0);                \
-                               if (isGlockOwner) AFS_GLOCK();  \
-                               MUTEX_ENTER(lck);       \
-                               }
+#define CV_TIMEDWAIT(cv, lck, t)  {                                    \
+       struct simplelock slock = SIMPLELOCK_INITIALIZER;               \
+       simple_lock(&slock);                                            \
+       int glocked = ISAFS_GLOCK();                                    \
+       if (glocked)                                                    \
+           AFS_GUNLOCK();                                              \
+       MUTEX_EXIT(lck);                                                \
+       tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t, &slock);            \
+       if (glocked)                                                    \
+           AFS_GLOCK();                                                \
+       MUTEX_ENTER(lck);                                               \
+       simple_unlock(&slock);                                          \
+    }
 
-#define CV_SIGNAL(cv)           thread_wakeup_one((event_t)(cv))
-#define CV_BROADCAST(cv)        thread_wakeup((event_t)(cv))
+#define CV_SIGNAL(cv)           wakeup_one(cv)
+#define CV_BROADCAST(cv)        wakeup(cv)
 
-typedef struct {
-    struct lock__bsd__ lock;
-    thread_t owner;
-} afs_kmutex_t;
+/* #define osi_rxWakeup(cv)        wakeup(cv) */
 typedef int afs_kcondvar_t;
 
-#define osi_rxWakeup(cv)        thread_wakeup((event_t)(cv))
+typedef struct {
+    struct lock lock;
+    struct lwp *owner;
+} afs_kmutex_t;
 
-#define LOCK_INIT(a,b) \
-    do { \
-       lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \
-       (a)->owner = (thread_t)0; \
-    } while(0);
 #define MUTEX_INIT(a,b,c,d) \
     do { \
-       lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \
-       (a)->owner = (thread_t)0; \
+       lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \
+       (a)->owner = 0; \
     } while(0);
 #define MUTEX_DESTROY(a) \
     do { \
-       (a)->owner = (thread_t)-1; \
+       (a)->owner = (struct lwp *)-1; \
     } while(0);
+
+#if defined(LOCKDEBUG)
 #define MUTEX_ENTER(a) \
     do { \
-       lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \
-       osi_Assert((a)->owner == (thread_t)0); \
-       (a)->owner = current_thread(); \
+       _lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, __FILE__, __LINE__); \
+       osi_Assert((a)->owner == 0); \
+       (a)->owner = curlwp; \
     } while(0);
 #define MUTEX_TRYENTER(a) \
-    ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) )
-#define xMUTEX_TRYENTER(a) \
-    ( osi_Assert((a)->owner == (thread_t)0), (a)->owner = current_thread(), 1)
+    ( _lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0, __FILE__, __LINE__) ? 0        \
+      : ((a)->owner = curlwp, 1) )
 #define MUTEX_EXIT(a) \
     do { \
-       osi_Assert((a)->owner == current_thread()); \
-       (a)->owner = (thread_t)0; \
-       lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \
+       osi_Assert((a)->owner == curlwp); \
+       (a)->owner = 0; \
+       _lockmgr(&(a)->lock, LK_RELEASE, 0, __FILE__, __LINE__); \
     } while(0);
-
-#undef MUTEX_ISMINE
-#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread())
-
-#undef osirx_AssertMine
-extern void osirx_AssertMine(afs_kmutex_t * lockaddr, char *msg);
+#else
+#define MUTEX_ENTER(a) \
+    do { \
+       lockmgr(&(a)->lock, LK_EXCLUSIVE, 0); \
+       osi_Assert((a)->owner == 0); \
+       (a)->owner = curlwp; \
+    } while(0);
+#define MUTEX_TRYENTER(a) \
+    ( lockmgr(&(a)->lock, LK_EXCLUSIVE | LK_NOWAIT, 0) ? 0 \
+      : ((a)->owner = curlwp, 1) )
+#define MUTEX_EXIT(a) \
+    do { \
+       osi_Assert((a)->owner == curlwp); \
+       (a)->owner = 0; \
+       lockmgr(&(a)->lock, LK_RELEASE, 0); \
+    } while(0);
+#endif /* LOCKDEBUG */
+#define MUTEX_ISMINE(a) \
+    (lockstatus(a) == LK_EXCLUSIVE)
+#define MUTEX_LOCKED(a) \
+    (lockstatus(a) == LK_EXCLUSIVE)
 
 #endif /* _RX_KMUTEX_H_ */
index 926c9a7..f4cb558 100644 (file)
@@ -1,71 +1,65 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
 #include <afsconfig.h>
-#include "afs/param.h"
+#include "../afs/param.h"
 
 
-#include "rx/rx_kcommon.h"
+#include "../rx/rx_kcommon.h"
 
 int
-osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
-              int nvecs, int *alength)
+osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr,
+              struct iovec *dvec, int nvecs, int *alength)
 {
-    struct socket *asocket = (struct socket *)so;
     struct uio u;
-    int i;
+    int i, code;
     struct iovec iov[RX_MAXIOVECS];
-    struct sockaddr *sa;
-    int code;
+    struct mbuf *nam = NULL;
 
-    int haveGlock = ISAFS_GLOCK();
-    /*AFS_STATCNT(osi_NetReceive); */
+    int glocked = ISAFS_GLOCK();
 
-    if (nvecs > RX_MAXIOVECS) {
-       osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
-    }
+    if (nvecs > RX_MAXIOVECS)
+       osi_Panic("osi_NetReceive: %d: too many iovecs\n", nvecs);
 
-    for (i = 0; i < nvecs; i++) {
-       iov[i].iov_base = dvec[i].iov_base;
-       iov[i].iov_len = dvec[i].iov_len;
-    }
+    for (i = 0; i < nvecs; i++)
+       iov[i] = dvec[i];
 
     u.uio_iov = &iov[0];
     u.uio_iovcnt = nvecs;
     u.uio_offset = 0;
     u.uio_resid = *alength;
-    u.uio_segflg = UIO_SYSSPACE;
+    UIO_SETUP_SYSSPACE(&u);
     u.uio_rw = UIO_READ;
+#if 0
     u.uio_procp = NULL;
-
-    if (haveGlock) {
-       AFS_GUNLOCK();
-    }
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
 #endif
-    code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-#endif
-    if (haveGlock) {
+    if (glocked)
+       AFS_GUNLOCK();
+    code = soreceive(asocket, (addr ? &nam : NULL), &u, NULL, NULL, NULL);
+    if (glocked)
        AFS_GLOCK();
+
+    if (code) {
+#ifdef RXKNET_DEBUG
+       printf("rx code %d termState %d\n", code, afs_termState);
+#endif
+       while (afs_termState == AFSOP_STOP_RXEVENT)
+           afs_osi_Sleep(&afs_termState);
+       return code;
     }
-    *alength = *alength - u.uio_resid;
-    if (sa) {
-       if (sa->sa_family == AF_INET) {
-           if (addr)
-               *addr = *(struct sockaddr_in *)sa;
-       } else {
-           printf("Unknown socket family %d in NetReceive\n");
-       }
+
+    *alength -= u.uio_resid;
+    if (addr && nam) {
+       memcpy(addr, mtod(nam, caddr_t), nam->m_len);
+       m_freem(nam);
     }
+
     return code;
 }
 
@@ -75,87 +69,54 @@ osi_StopListener(void)
 {
     struct proc *p;
 
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
-#endif
     soclose(rx_socket);
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-#endif
     p = pfind(rxk_ListenerPid);
     if (p)
        psignal(p, SIGUSR1);
 }
 
-/* rx_NetSend - send asize bytes at adata from asocket to host at addr.
- *
- * Now, why do we allocate a new buffer when we could theoretically use the one
- * pointed to by adata?  Because PRU_SEND returns after queueing the message,
- * not after sending it.  If the sender changes the data after queueing it,
- * we'd see the already-queued data change.  One attempt to fix this without
- * adding a copy would be to have this function wait until the datagram is
- * sent; however this doesn't work well.  In particular, if a host is down, and
- * an ARP fails to that host, this packet will be queued until the ARP request
- * comes back, which could be hours later.  We can't block in this routine that
- * long, since it prevents RPC timeouts from happening.
- */
-/* XXX In the brave new world, steal the data bufs out of the rx_packet iovec,
- * and just queue those.  XXX
+/*
+ * rx_NetSend - send asize bytes at adata from asocket to host at addr.
  */
 
-
 int
 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
            int nvecs, afs_int32 alength, int istack)
 {
-    register afs_int32 code;
-    int s;
-    int len;
-    int i;
+    int i, code;
     struct iovec iov[RX_MAXIOVECS];
-    char *tdata;
     struct uio u;
     struct mbuf *nam;
-    int haveGlock = ISAFS_GLOCK();
+    int glocked = ISAFS_GLOCK();
 
     AFS_STATCNT(osi_NetSend);
-    if (nvecs > RX_MAXIOVECS) {
+    if (nvecs > RX_MAXIOVECS)
        osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
-    }
 
-    for (i = 0; i < nvecs; i++) {
-       iov[i].iov_base = dvec[i].iov_base;
-       iov[i].iov_len = dvec[i].iov_len;
-    }
+    for (i = 0; i < nvecs; i++)
+       iov[i] = dvec[i];
 
     u.uio_iov = &iov[0];
     u.uio_iovcnt = nvecs;
     u.uio_offset = 0;
     u.uio_resid = alength;
-    u.uio_segflg = UIO_SYSSPACE;
+    UIO_SETUP_SYSSPACE(&u);
     u.uio_rw = UIO_WRITE;
+#if 0
     u.uio_procp = NULL;
-    if (haveGlock) {
-       AFS_GUNLOCK();
-    }
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
 #endif
     nam = m_get(M_DONTWAIT, MT_SONAME);
-    if (nam == NULL) {
-       code = ENOBUFS;
-       goto bad;
-    }
+    if (!nam)
+       return ENOBUFS;
     nam->m_len = addr->sin_len = sizeof(struct sockaddr_in);
-    memcpy(mtod(nam, caddr_t), (caddr_t) addr, addr->sin_len);
-    code = sosend(asocket, mtod(nam, struct sockaddr *), &u, NULL, NULL, 0);
-    m_freem(nam);
-  bad:
-#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
-    thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
-#endif
-    if (haveGlock) {
+    memcpy(mtod(nam, caddr_t), addr, addr->sin_len);
+
+    if (glocked)
+       AFS_GUNLOCK();
+    code = sosend(asocket, nam, &u, NULL, NULL, 0, osi_curproc());
+    if (glocked)
        AFS_GLOCK();
-    }
+    m_freem(nam);
+
     return code;
 }
index 688c31c..3032711 100644 (file)
@@ -685,7 +685,7 @@ rxi_GetIFInfo(void)
     TAILQ_FOREACH(ifn, &ifnet, if_link) {
        if (i >= ADDRSPERSITE)
            break;
-#elif defined(AFS_OBSD_ENV)
+#elif defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV)
     for (ifn = ifnet.tqh_first; i < ADDRSPERSITE && ifn != NULL;
         ifn = ifn->if_list.tqe_next) {
 #else
@@ -696,7 +696,7 @@ rxi_GetIFInfo(void)
        TAILQ_FOREACH(ifad, &ifn->if_addrhead, ifa_link) {
            if (i >= ADDRSPERSITE)
                break;
-#elif defined(AFS_OBSD_ENV)
+#elif defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV)
        for (ifad = ifn->if_addrlist.tqh_first;
             ifad != NULL && i < ADDRSPERSITE;
             ifad = ifad->ifa_list.tqe_next) {
@@ -879,6 +879,8 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
     code = socreate(AF_INET, &newSocket, SOCK_DGRAM, IPPROTO_UDP, curproc);
 #elif defined(AFS_DARWIN80_ENV)
     code = sock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, NULL, &newSocket);
+#elif defined(AFS_NBSD40_ENV)
+    code = socreate(AF_INET, &newSocket, SOCK_DGRAM, 0, osi_curproc());
 #else
     code = socreate(AF_INET, &newSocket, SOCK_DGRAM, 0);
 #endif /* AFS_HPUX102_ENV */
@@ -902,8 +904,11 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
     memcpy((caddr_t) bindnam->b_rptr + SO_MSGOFFSET, (caddr_t) & myaddr,
           addrsize);
     bindnam->b_wptr = bindnam->b_rptr + (addrsize + SO_MSGOFFSET + 1);
-
+#if defined(AFS_NBSD40_ENV)
+    code = sobind(newSocket, bindnam, addrsize, osi_curproc());
+#else
     code = sobind(newSocket, bindnam, addrsize);
+#endif
     if (code) {
        soclose(newSocket);
 #if !defined(AFS_HPUX1122_ENV)
@@ -970,7 +975,7 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
     BHV_PDATA(&bhv) = (void *)newSocket;
     code = sobind(&bhv, nam);
     m_freem(nam);
-#elif defined(AFS_OBSD44_ENV)
+#elif defined(AFS_OBSD44_ENV) || defined(AFS_NBSD40_ENV)
     code = sobind(newSocket, nam, osi_curproc());
 #else
     code = sobind(newSocket, nam);
index cabb289..2dff7f7 100644 (file)
@@ -69,6 +69,10 @@ typedef unsigned short etap_event_t;
 #include "h/buf.h"
 #include "h/mbuf.h"
 #endif /* AFS_FBSD_ENV */
+#if defined(AFS_NBSD40_ENV)
+#include "h/buf.h"
+#include "h/mbuf.h"
+#endif
 #endif /* !defined(AFS_SUN5_ENV) && !defined(AFS_XBSD_ENV) */
 #endif /* !defined(AFS_LINUX22_ENV) && !defined(AFS_OBSD_ENV) */
 #ifdef AFS_SGI62_ENV