FBSD: cast lkmnosys appropriately
[openafs.git] / src / afs / FBSD / osi_vfsops.c
index 193e2bd..35b6fca 100644 (file)
-/*
- * 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_vfsops.c for DUX
- */
 #include <afsconfig.h>
-#include "../afs/param.h"
-
-RCSID("$Header$");
-
-#include "../afs/sysincludes.h"        /* Standard vendor system headers */
-#include "../afs/afsincludes.h"        /* Afs-based standard headers */
-#include "../afs/afs_stats.h"   /* statistics stuff */
-#include <sys/types.h>
-#include <kern/mach_param.h>
-#include <sys/sysconfig.h>
-#include <sys/systm.h>
-#include <sys/resource.h>
-#include <sys/errno.h>
+#include <afs/param.h>
+
+
+#include <afs/sysincludes.h>   /* Standard vendor system headers */
+#include <afsincludes.h>       /* Afs-based standard headers */
+#include <afs/afs_stats.h>     /* statistics */
+#include <sys/malloc.h>
+#include <sys/namei.h>
 #include <sys/conf.h>
-#include <machine/machlimits.h>
+#include <sys/module.h>
+#include <sys/sysproto.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+
+struct vcache *afs_globalVp = NULL;
+struct mount *afs_globalVFS = NULL;
+int afs_pbuf_freecnt = -1;
+
+extern int Afs_xsetgroups();
+extern int afs_xioctl();
+
+#if !defined(AFS_FBSD90_ENV) && !defined(AFS_FBSD82_ENV)
+static sy_call_t *old_handler;
+#else
+static struct sysent old_sysent;
+
+static struct sysent afs_sysent = {
+    5,                 /* int sy_narg */
+    (sy_call_t *) afs3_syscall,        /* sy_call_t *sy_call */
+#ifdef AFS_FBSD60_ENV
+    AUE_NULL,          /* au_event_t sy_auevent */
+#ifdef AFS_FBSD70_ENV
+    NULL,              /* systrace_args_funt_t sy_systrace_args_func */
+    0,                 /* u_int32_t sy_entry */
+    0,                 /* u_int32_t sy_return */
+#ifdef AFS_FBSD90_ENV
+    0,                 /* u_int32_t sy_flags */
+    0                  /* u_int32_t sy_thrcnt */
+#endif
+#endif
+#endif /* FBSD60 */
+};
+#endif /* FBSD90 */
 
+int
+afs_init(struct vfsconf *vfc)
+{
+    int code;
+    int offset = AFS_SYSCALL;
+#if defined(AFS_FBSD90_ENV) || defined(AFS_FBSD82_ENV)
+    code = syscall_register(&offset, &afs_sysent, &old_sysent);
+    if (code) {
+       printf("AFS_SYSCALL in use, error %i. aborting\n", code);
+       return code;
+    }
+#else
+    if (sysent[AFS_SYSCALL].sy_call != nosys
+        && sysent[AFS_SYSCALL].sy_call != (sy_call_t *)lkmnosys) {
+        printf("AFS_SYSCALL in use. aborting\n");
+        return EBUSY;
+    }
+#endif
+    osi_Init();
+    afs_pbuf_freecnt = nswbuf / 2 + 1;
+#if !defined(AFS_FBSD90_ENV) && !defined(AFS_FBSD82_ENV)
+    old_handler = sysent[AFS_SYSCALL].sy_call;
+    sysent[AFS_SYSCALL].sy_call = afs3_syscall;
+    sysent[AFS_SYSCALL].sy_narg = 5;
+#endif
+    return 0;
+}
 
-struct vcache *afs_globalVp = 0;
-struct mount *afs_globalVFS = 0;
+int
+afs_uninit(struct vfsconf *vfc)
+{
+#if defined(AFS_FBSD90_ENV) || defined(AFS_FBSD82_ENV)
+    int offset = AFS_SYSCALL;
+#endif
 
-static u_char afs_mntid;
-int afs_vfsdev = 0;
-udecl_simple_lock_data(, afsmntid_lock)
-#define AFSMNTID_LOCK()         usimple_lock(&afsmntid_lock)
-#define AFSMNTID_UNLOCK()       usimple_unlock(&afsmntid_lock)
-#define AFSMNTID_LOCK_INIT()    usimple_lock_init(&afsmntid_lock)
+    if (afs_globalVFS)
+       return EBUSY;
+#if defined(AFS_FBSD90_ENV) || defined(AFS_FBSD82_ENV)
+    syscall_deregister(&offset, &old_sysent);
+#else
+    sysent[AFS_SYSCALL].sy_narg = 0;
+    sysent[AFS_SYSCALL].sy_call = old_handler;
+#endif
+    return 0;
+}
 
+int
+afs_start(struct mount *mp, int flags, struct thread *p)
+{
+    return (0);                        /* nothing to do. ? */
+}
 
-int mp_afs_mount(struct mount *afsp,char * path, caddr_t data,
-                struct nameidata *ndp)
+int
+#if defined(AFS_FBSD80_ENV)
+afs_omount(struct mount *mp, char *path, caddr_t data)
+#elif defined(AFS_FBSD53_ENV)
+afs_omount(struct mount *mp, char *path, caddr_t data, struct thread *p)
+#else
+afs_omount(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp,
+       struct thread *p)
+#endif
 {
-    u_int size;
+    /* ndp contains the mounted-from device.  Just ignore it.
+     * we also don't care about our thread struct. */
+    size_t size;
 
-    fsid_t tfsid;
-    struct mount *xmp, *getvfs();
-    int code;
+    if (mp->mnt_flag & MNT_UPDATE)
+       return EINVAL;
 
     AFS_GLOCK();
     AFS_STATCNT(afs_mount);
 
-    if (afs_globalVFS) { /* Don't allow remounts. */
+    if (afs_globalVFS) {       /* Don't allow remounts. */
        AFS_GUNLOCK();
-       return (EBUSY);
+       return EBUSY;
     }
 
-    afs_globalVFS = afsp;
-    afsp->vfs_bsize = 8192;
-/*
- * Generate a unique afs mount i.d. ( see nfs_mount() ).
- */
-    afsp->m_stat.f_fsid.val[0] = makedev(130, 0);
-    afsp->m_stat.f_fsid.val[1] = MOUNT_AFS;
-    AFSMNTID_LOCK();
-    if (++afs_mntid == 0)
-        ++afs_mntid;
-    AFSMNTID_UNLOCK();
-    BM(AFSMNTID_LOCK());
-    tfsid.val[0] = makedev(130, afs_mntid);
-    tfsid.val[1] = MOUNT_AFS;
-    BM(AFSMNTID_UNLOCK());
-
-    while (xmp = getvfs(&tfsid)) {
-        UNMOUNT_READ_UNLOCK(xmp);
-        tfsid.val[0]++;
-        AFSMNTID_LOCK();
-        afs_mntid++;
-        AFSMNTID_UNLOCK();
-    }
-    if (major(tfsid.val[0]) != 130) {
-       AFS_GUNLOCK();
-        return (ENOENT);
-    }
-    afsp->m_stat.f_fsid.val[0] = tfsid.val[0];
-
-    afsp->m_stat.f_mntonname = AFS_KALLOC(MNAMELEN);
-    afsp->m_stat.f_mntfromname = AFS_KALLOC(MNAMELEN); 
-    if ( !afsp->m_stat.f_mntonname || !afsp->m_stat.f_mntfromname)
-       panic("malloc failure in afs_mount\n");
-
-    bzero(afsp->m_stat.f_mntonname, MNAMELEN);
-    bzero(afsp->m_stat.f_mntfromname, MNAMELEN);
-    AFS_COPYINSTR(path, (caddr_t)afsp->m_stat.f_mntonname, MNAMELEN, &size, code);
-    bcopy("AFS", afsp->m_stat.f_mntfromname, 4);
-    AFS_GUNLOCK();
-    (void) mp_afs_statfs(afsp);
-    AFS_GLOCK();
-    afs_vfsdev = afsp->m_stat.f_fsid.val[0];
-
-#ifndef        AFS_NONFSTRANS
-    /* Set up the xlator in case it wasn't done elsewhere */
-    afs_xlatorinit_v2();
-    afs_xlatorinit_v3();
+    afs_globalVFS = mp;
+    mp->vfs_bsize = 8192;
+    vfs_getnewfsid(mp);
+    /*
+     * This is kind of ugly, as the interlock has grown to encompass
+     * more fields over time and there's not a good way to group the
+     * code without duplication.
+     */
+#ifdef AFS_FBSD62_ENV
+    MNT_ILOCK(mp);
+#endif
+    mp->mnt_flag &= ~MNT_LOCAL;
+#if defined(AFS_FBSD61_ENV) && !defined(AFS_FBSD62_ENV)
+    MNT_ILOCK(mp);
+#endif
+    mp->mnt_kern_flag |= MNTK_MPSAFE; /* solid steel */
+#ifndef AFS_FBSD61_ENV
+    MNT_ILOCK(mp);
 #endif
+    /*
+     * XXX mnt_stat "is considered stable as long as a ref is held".
+     * We should check that we hold the only ref.
+     */
+    mp->mnt_stat.f_iosize = 8192;
+
+    if (path != NULL)
+       copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
+    else
+       bcopy("/afs", mp->mnt_stat.f_mntonname, size = 4);
+    memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
+    memset(mp->mnt_stat.f_mntfromname, 0, 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");
+    MNT_IUNLOCK(mp);
     AFS_GUNLOCK();
+#ifdef AFS_FBSD80_ENV
+    afs_statfs(mp, &mp->mnt_stat);
+#else
+    afs_statfs(mp, &mp->mnt_stat, p);
+#endif
+
     return 0;
 }
 
+#ifdef AFS_FBSD53_ENV
+int
+#ifdef AFS_FBSD80_ENV
+afs_mount(struct mount *mp)
+#else
+afs_mount(struct mount *mp, struct thread *td)
+#endif
+{
+#ifdef AFS_FBSD80_ENV
+    return afs_omount(mp, NULL, NULL);
+#else
+    return afs_omount(mp, NULL, NULL, td);
+#endif
+}
+#endif
+
+#ifdef AFS_FBSD60_ENV
+static int
+#ifdef AFS_FBSD80_ENV
+afs_cmount(struct mntarg *ma, void *data, int flags)
+#else
+afs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
+#endif
+{
+    return kernel_mount(ma, flags);
+}
+#endif
 
-int mp_afs_unmount (struct mount *afsp, int flag)
+int
+#ifdef AFS_FBSD80_ENV
+afs_unmount(struct mount *mp, int flags)
+#else
+afs_unmount(struct mount *mp, int flags, struct thread *p)
+#endif
 {
+    int error = 0;
+
+    AFS_GLOCK();
+    if (afs_globalVp &&
+       ((flags & MNT_FORCE) || !VREFCOUNT_GT(afs_globalVp, 1))) {
+       /* Put back afs_root's ref */
+       struct vcache *gvp = afs_globalVp;
+       afs_globalVp = NULL;
+       afs_PutVCache(gvp);
+    }
+    if (afs_globalVp)
+       error = EBUSY;
+    AFS_GUNLOCK();
+
+    /*
+     * Release any remaining vnodes on this mount point.
+     * The `1' means that we hold one extra reference on
+     * the root vnode (this is just a guess right now).
+     * This has to be done outside the global lock.
+     */
+    if (!error) {
+#if defined(AFS_FBSD80_ENV)
+       error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, curthread);
+#elif defined(AFS_FBSD53_ENV)
+       error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0, p);
+#else
+       error = vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0);
+#endif
+    }
+    if (error)
+       goto out;
     AFS_GLOCK();
     AFS_STATCNT(afs_unmount);
     afs_globalVFS = 0;
     afs_shutdown();
     AFS_GUNLOCK();
-    return 0;
-}
-
 
-int mp_afs_start(struct mount *mp, int flags)
-{
-    return(0);
+out:
+    return error;
 }
 
-int mp_afs_root (struct mount *afsp, struct vnode **avpp)
+int
+#if defined(AFS_FBSD80_ENV)
+afs_root(struct mount *mp, int flags, struct vnode **vpp)
+#elif defined(AFS_FBSD60_ENV)
+afs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
+#elif defined(AFS_FBSD53_ENV)
+afs_root(struct mount *mp, struct vnode **vpp, struct thread *td)
+#else
+afs_root(struct mount *mp, struct vnode **vpp)
+#endif
 {
-    register afs_int32 code = 0;
+    int error;
     struct vrequest treq;
-    register struct vcache *tvp=0;
+    struct vcache *tvp = 0;
+    struct vcache *gvp;
+#if !defined(AFS_FBSD53_ENV) || defined(AFS_FBSD80_ENV)
+    struct thread *td = curthread;
+#endif
+    struct ucred *cr = osi_curcred();
 
     AFS_GLOCK();
     AFS_STATCNT(afs_root);
-    if (afs_globalVp && (afs_globalVp->states & CStatd)) {
+    crhold(cr);
+tryagain:
+    if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
        tvp = afs_globalVp;
+       error = 0;
     } else {
-       if (!(code = afs_InitReq(&treq, cred)) &&
-           !(code = afs_CheckInit())) {
-           tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0,
-                               (struct vcache*)0, WRITE_LOCK);
+       if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
+           tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
            /* we really want this to stay around */
            if (tvp) {
+               gvp = afs_globalVp;
                afs_globalVp = tvp;
+               if (gvp) {
+                   afs_PutVCache(gvp);
+                   if (tvp != afs_globalVp) {
+                       /* someone raced us and won */
+                       afs_PutVCache(tvp);
+                       goto tryagain;
+                   }
+               }
            } else
-               code = ENOENT;
+               error = ENOENT;
        }
     }
     if (tvp) {
+       struct vnode *vp = AFSTOV(tvp);
+
+       ASSERT_VI_UNLOCKED(vp, "afs_root");
        AFS_GUNLOCK();
-       VN_HOLD((struct vnode *)tvp);
-       VN_LOCK((struct vnode *)tvp);
-       tvp->v.v_flag |= VROOT;     /* No-op on Ultrix 2.2 */
-       VN_UNLOCK((struct vnode *)tvp);
+       error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
        AFS_GLOCK();
+       /* we dropped the glock, so re-check everything it had serialized */
+       if (!afs_globalVp || !(afs_globalVp->f.states & CStatd) ||
+               tvp != afs_globalVp) {
+           vput(vp);
+           afs_PutVCache(tvp);
+           goto tryagain;
+       }
+       if (error != 0)
+           goto tryagain;
+       /*
+        * I'm uncomfortable about this.  Shouldn't this happen at a
+        * higher level, and shouldn't we busy the top-level directory
+        * to prevent recycling?
+        */
+       vp->v_vflag |= VV_ROOT;
 
-       afs_globalVFS = afsp;
-       *avpp = (struct vnode *) tvp;
+       afs_globalVFS = mp;
+       *vpp = vp;
     }
 
-    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp,
-              ICL_TYPE_INT32, code);
+    afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, tvp ? AFSTOV(tvp) : NULL,
+              ICL_TYPE_INT32, error);
     AFS_GUNLOCK();
-    return code;
+    crfree(cr);
+    return error;
 }
 
-
-mp_afs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg)
-{
-    return EOPNOTSUPP;
-}
-
-int mp_afs_statfs(struct mount *afsp)
+int
+#ifdef AFS_FBSD80_ENV
+afs_statfs(struct mount *mp, struct statfs *abp)
+#else
+afs_statfs(struct mount *mp, struct statfs *abp, struct thread *p)
+#endif
 {
-    struct nstatfs *abp = &afsp->m_stat;
-
     AFS_GLOCK();
     AFS_STATCNT(afs_statfs);
 
-    abp->f_type = MOUNT_AFS;
-    abp->f_bsize = afsp->vfs_bsize;
+    abp->f_bsize = mp->vfs_bsize;
+    abp->f_iosize = mp->vfs_bsize;
 
     /* Fake a high number below to satisfy programs that use the statfs call
      * to make sure that there's enough space in the device partition before
      * storing something there.
      */
     abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
-       abp->f_ffree  = 2000000;
-    abp->f_fsize = 1024;
-
-    abp->f_fsid.val[0] = afsp->m_stat.f_fsid.val[0];
-    abp->f_fsid.val[1] = afsp->m_stat.f_fsid.val[1];
-
-    AFS_GUNLOCK();
-    return 0;
-}
-
-
-int mp_afs_sync(struct mount *mp, int flags)
-{
-    AFS_STATCNT(afs_sync);
-    return 0;
-}
-
-
-int mp_afs_fhtovp(struct mount *afsp, struct fid *fidp, struct vnode **avcp)
-{
-    struct vrequest treq;
-    register code = 0;
-
-    AFS_GLOCK();
-    AFS_STATCNT(afs_vget);
-
-    *avcp = NULL;
-
-    if ((code = afs_InitReq(&treq, cred)) == 0) {
-       code = afs_osi_vget((struct vcache**)avcp, fidp, &treq);
+       abp->f_ffree = 2000000;
+
+    abp->f_fsid.val[0] = mp->mnt_stat.f_fsid.val[0];
+    abp->f_fsid.val[1] = mp->mnt_stat.f_fsid.val[1];
+    if (abp != &mp->mnt_stat) {
+       abp->f_type = mp->mnt_vfc->vfc_typenum;
+       memcpy((caddr_t) & abp->f_mntonname[0],
+              (caddr_t) mp->mnt_stat.f_mntonname, MNAMELEN);
+       memcpy((caddr_t) & abp->f_mntfromname[0],
+              (caddr_t) mp->mnt_stat.f_mntfromname, MNAMELEN);
     }
 
-    afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp,
-              ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp);
-
-    code = afs_CheckCode(code, &treq, 42);
-    AFS_GUNLOCK();
-    return code;
-}
-
-
-/*
- *  afs_vptofh
- * 
- * afs_vptofh can return two flavors of NFS fid, depending on if submounts are
- * allowed. The reason for this is that we can't guarantee that we found all 
- * the entry points any OS might use to get the fid for the NFS mountd.
- * Hence we return a "magic" fid for all but /afs. If it goes through the
- * translator code, it will get transformed into a SmallFid that we recognize.
- * So, if submounts are disallowed, and an NFS client tries a submount, it will
- * get a fid which we don't recognize and the mount will either fail or we
- * will ignore subsequent requests for that mount.
- *
- * The Alpha fid is organized differently than for other platforms. Their
- * intention was to have the data portion of the fid aligned on a 4 byte
- * boundary. To do so, the fid is organized as:
- * u_short reserved
- * u_short len
- * char data[8]
- * The len field is the length of the entire fid, from reserved through data.
- * This length is used by fid_copy to include copying the reserved field. 
- * Alpha's zero the reserved field before handing us the fid, but they use
- * it in fid_cmp. We use the reserved field to store the 16 bits of the Vnode.
- *
- * Note that the SmallFid only allows for 8 bits of the cell index and
- * 16 bits of the vnode. 
- */
-
-#define AFS_FIDDATASIZE 8
-#define AFS_SIZEOFSMALLFID 12 /* full size of fid, including len field */
-extern int afs_NFSRootOnly; /* 1 => only allow NFS mounts of /afs. */
-int afs_fid_vnodeoverflow=0, afs_fid_uniqueoverflow=0;
-
-int mp_afs_vptofh(struct vnode *avn, struct fid *fidp)
-{
-    struct SmallFid Sfid;
-    long addr[2];
-    register struct cell *tcell;
-    int rootvp = 0;
-    struct vcache *avc = (struct vcache *)avn;
-
-    AFS_GLOCK();
-    AFS_STATCNT(afs_fid);
-
-    if (afs_shuttingdown) {
-       AFS_GUNLOCK();
-       return EIO;
-    }
-
-    if (afs_NFSRootOnly && (avc == afs_globalVp)) rootvp = 1;
-    if (!afs_NFSRootOnly || rootvp) {
-       tcell = afs_GetCell(avc->fid.Cell, READ_LOCK);
-       Sfid.Volume = avc->fid.Fid.Volume;
-       fidp->fid_reserved = avc->fid.Fid.Vnode;
-       Sfid.CellAndUnique = ((tcell->cellIndex << 24) +
-                             (avc->fid.Fid.Unique & 0xffffff));
-       afs_PutCell(tcell, READ_LOCK);
-       if (avc->fid.Fid.Vnode > 0xffff)
-           afs_fid_vnodeoverflow++;
-       if (avc->fid.Fid.Unique > 0xffffff)
-           afs_fid_uniqueoverflow++;
-    } else {
-       fidp->fid_reserved = AFS_XLATOR_MAGIC;
-       addr[0] = (long)avc;
-       AFS_GUNLOCK();
-       VN_HOLD((struct vnode *)avc);
-       AFS_GLOCK();
-    }
-
-    /* Use the fid pointer passed to us. */
-    fidp->fid_len = AFS_SIZEOFSMALLFID;
-    if (afs_NFSRootOnly) {
-       if (rootvp) {
-           bcopy((caddr_t)&Sfid, fidp->fid_data, AFS_FIDDATASIZE);   
-       } else {
-           bcopy((caddr_t)addr, fidp->fid_data, AFS_FIDDATASIZE);   
-       }
-    } else {
-       bcopy((caddr_t)&Sfid, fidp->fid_data, AFS_FIDDATASIZE);   
-    }
     AFS_GUNLOCK();
     return 0;
 }
 
-
-int mp_Afs_init(void); /* vfs_init - defined below */
-
-
-/* This is only called by vfs_mount when afs is going to be mounted as root.
- * Since we don't support diskless clients we shouldn't come here.
- */
-int afsmountroot=0;
-int mp_afs_mountroot(struct mount *afsp, struct vnode **vp)
-{
-    AFS_GLOCK();
-    AFS_STATCNT(afs_mountroot);
-    afsmountroot++;
-    AFS_GUNLOCK();
-    return EINVAL;
-}
-
-
-/* It's called to setup swapping over the net for diskless clients; again
- * not for us.
- */
-int afsswapvp=0;
-int mp_afs_swapvp(void)
+int
+#if defined(AFS_FBSD80_ENV)
+afs_sync(struct mount *mp, int waitfor)
+#elif defined(AFS_FBSD60_ENV)
+afs_sync(struct mount *mp, int waitfor, struct thread *td)
+#else
+afs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct thread *p)
+#endif
 {
-    AFS_GLOCK();
-    AFS_STATCNT(afs_swapvp);
-    afsswapvp++;
-    AFS_GUNLOCK();
-    return EINVAL;
+    return 0;
 }
 
-
+#ifdef AFS_FBSD60_ENV
 struct vfsops afs_vfsops = {
-    mp_afs_mount,
-    mp_afs_start,
-    mp_afs_unmount,
-    mp_afs_root,
-    mp_afs_quotactl,
-    mp_afs_statfs,
-    mp_afs_sync,
-    mp_afs_fhtovp,     /* afs_vget */
-    mp_afs_vptofh,
-    mp_Afs_init,
-    mp_afs_mountroot,
-    mp_afs_swapvp
+       .vfs_init =             afs_init,
+       .vfs_mount =            afs_mount,
+       .vfs_cmount =           afs_cmount,
+       .vfs_root =             afs_root,
+       .vfs_statfs =           afs_statfs,
+       .vfs_sync =             afs_sync,
+       .vfs_uninit =           afs_uninit,
+       .vfs_unmount =          afs_unmount,
+       .vfs_sysctl =           vfs_stdsysctl,
 };
-
-
-/*
- * System Call Entry Points
- */
-#define NULL_FUNC          (int (*)(int))0
-
-int     (*afs_syscall_func)() = NULL_FUNC;
-int     (*afs_xsetgroups_func)() = NULL_FUNC;
-int     (*afs_xioctl_func)() = NULL_FUNC;
-
-afssyscall(p, args, retval)
-    struct proc *p;
-    void *args;
-    long *retval;
-{
-    int     (*func)();
-    int code;
-
-    AFS_GLOCK();
-    func = afs_syscall_func;
-    if (func == NULL_FUNC) {
-       code = nosys(p, args, retval);
-    } else {
-       code = (*func)(p, args, retval);
-    }
-    AFS_GUNLOCK();
-    return code;
-}
-
-afsxsetgroups(p, args, retval)
-    struct proc *p;
-    void *args;
-    long *retval;
-{
-    int     (*func)();
-    int code;
-
-    AFS_GLOCK();
-    func = afs_xsetgroups_func;
-    if (func == NULL_FUNC) {
-       code = nosys(p, args, retval);
-    } else {
-       code = (*func)(p, args, retval);
-    }
-    AFS_GUNLOCK();
-    return code;
-}
-
-afsxioctl(p, args, retval)
-    struct proc *p;
-    void *args;
-    long *retval;
-{
-    int     (*func)();
-    int code;
-
-    AFS_GLOCK();
-    func = afs_xioctl_func;
-    if (func == NULL_FUNC) {
-       code = nosys(p, args, retval);
-    } else {
-       code = (*func)(p, args, retval);
-    }
-    AFS_GUNLOCK();
-    return code;
-}
-
-
-/*
- * VFS initialization and unload
- */
-
-afs_unconfig()
-{
-    return EBUSY;
-}
-
-
-cfg_subsys_attr_t afs_attributes[]  = {
-    {"", 0, 0, 0, 0, 0, 0}     /* must be the last element */
+#else
+struct vfsops afs_vfsops = {
+#ifdef AFS_FBSD53_ENV
+    afs_mount,
+#endif
+    afs_omount,
+    afs_start,
+    afs_unmount,
+    afs_root,
+    vfs_stdquotactl,
+    afs_statfs,
+    afs_sync,
+    vfs_stdvget,
+    vfs_stdfhtovp,
+    vfs_stdcheckexp,
+    vfs_stdvptofh,
+    afs_init,
+    afs_uninit,
+    vfs_stdextattrctl,
+    vfs_stdsysctl,
 };
-
-afs_configure(cfg_op_t op, caddr_t indata, size_t indata_size, caddr_t outdata, size_t outdata_size)
-{
-    cfg_attr_t *attributes;
-    int        ret = ESUCCESS;
-    int        i, j, size;
-    caddr_t p;
-
-    switch (op) {
-    case CFG_OP_CONFIGURE:
-       /*
-        * The indata parameter is a list of attributes to be configured, and 
-        * indata_size is the count of attributes.
-        */
-       if ((ret = vfssw_add_fsname(MOUNT_AFS, &afs_vfsops, "afs")) != 0)
-           return(ret);
-       break;
-    case CFG_OP_UNCONFIGURE:
-       if ((ret = afs_unconfig()) != 0)
-           return(ret);
-       break;
-    default:
-       ret = EINVAL;
-       break;
-    }
-    return ret;
-}
-
-
-int mp_Afs_init(void)
-{
-    extern int Afs_xsetgroups(), afs_xioctl(), afs3_syscall();
-    
-    AFS_GLOCK();
-    sysent[AFS_SYSCALL].sy_call = afs3_syscall;
-    sysent[AFS_SYSCALL].sy_parallel = 0;
-    sysent[AFS_SYSCALL].sy_narg = 6;
-    sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
-    afs_xioctl_func = afsxioctl;    
-    afs_xsetgroups_func = afsxsetgroups;
-    afs_syscall_func = afssyscall;
-    AFS_GUNLOCK();
-
-    return 0;
-}
+#endif