]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/miscfs/synthfs/synthfs_vfsops.c
xnu-792.tar.gz
[apple/xnu.git] / bsd / miscfs / synthfs / synthfs_vfsops.c
index 530239f6157396e870b2627058a4faceaf3d61db..39e8d6a6cdc26e701735d20a52683fdcc9fad8c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <sys/systm.h>
 #include <sys/namei.h>
 #include <sys/filedesc.h>
 #include <sys/systm.h>
 #include <sys/namei.h>
 #include <sys/filedesc.h>
-#include <sys/proc.h>
+#include <sys/proc_internal.h>
 #include <sys/kernel.h>
 #include <mach/machine/vm_types.h>
 #include <sys/kernel.h>
 #include <mach/machine/vm_types.h>
-#include <sys/vnode.h>
+#include <sys/vnode_internal.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
-#include <sys/mount.h>
-#include <sys/buf.h>
+#include <sys/mount_internal.h>
 #include <sys/mbuf.h>
 #include <sys/file.h>
 #include <sys/disk.h>
 #include <sys/mbuf.h>
 #include <sys/file.h>
 #include <sys/disk.h>
@@ -45,6 +44,7 @@
 #include <sys/errno.h>
 #include <sys/malloc.h>
 #include <sys/attr.h>
 #include <sys/errno.h>
 #include <sys/malloc.h>
 #include <sys/attr.h>
+#include <sys/uio_internal.h>
 
 #include <miscfs/specfs/specdev.h>
 
 
 #include <miscfs/specfs/specdev.h>
 
@@ -59,8 +59,8 @@ struct vfsops synthfs_vfsops = {
        synthfs_start,
        synthfs_unmount,
        synthfs_root,
        synthfs_start,
        synthfs_unmount,
        synthfs_root,
-       synthfs_quotactl,
-       synthfs_statfs,
+       NULL,                           /* quotactl */
+       synthfs_vfs_getattr,
        synthfs_sync,
        synthfs_vget,
        synthfs_fhtovp,
        synthfs_sync,
        synthfs_vget,
        synthfs_fhtovp,
@@ -71,7 +71,7 @@ struct vfsops synthfs_vfsops = {
 
 #define ROOTMPMODE 0755
 #define ROOTPLACEHOLDERMODE 0700
 
 #define ROOTMPMODE 0755
 #define ROOTPLACEHOLDERMODE 0700
-static char synthfs_fs_name[MFSNAMELEN] = "synthfs";
+static char synthfs_fs_name[MFSTYPENAMELEN] = "synthfs";
 static char synthfs_fake_mntfromname[] = "<synthfs>";
 
 
 static char synthfs_fake_mntfromname[] = "<synthfs>";
 
 
@@ -91,130 +91,14 @@ int vn_symlink(struct proc *p, char *path, char *link);
 #if LOADABLE_FS
 void
 synthfs_load(int loadArgument) {
 #if LOADABLE_FS
 void
 synthfs_load(int loadArgument) {
-       struct vfsconf *newvfsconf = NULL;
-       int j;
-       int (***opv_desc_vector_p)() = NULL;
-       int (**opv_desc_vector)();
-       struct vnodeopv_entry_desc *opve_descp;
-    int error = 0;
-       
-#pragma unused(loadArgument)
-
-    /*
-     * This routine is responsible for all the initialization that would
-     * ordinarily be done as part of the system startup; it calls synthfs_init
-     * to do the initialization that is strictly synthfs-specific.
-     */
-
-    DBG_VOP(("load_synthfs: starting ...\n"));
-
-    MALLOC(newvfsconf, void *, sizeof(struct vfsconf), M_SYNTHFS, M_WAITOK);
-    DBG_VOP(("load_synthfs: Allocated new vfsconf list entry, newvfsconf = 0x%08lx.\n", (unsigned long)newvfsconf));
-    bzero(newvfsconf, sizeof(struct vfsconf));
-
-    if (newvfsconf) {
-        DBG_VOP(("load_synthfs: filling in newly allocated vfsconf entry at 0x%08lX.\n", (long)newvfsconf));
-        newvfsconf->vfc_vfsops = &synthfs_vfsops;
-        strncpy(&newvfsconf->vfc_name[0], synthfs_fs_name, MFSNAMELEN);
-        newvfsconf->vfc_typenum = maxvfsconf++;
-        newvfsconf->vfc_refcount = 0;
-        newvfsconf->vfc_flags = 0;
-        newvfsconf->vfc_mountroot = NULL;       /* Can't mount root of file system [yet] */
-
-       newvfsconf->vfc_next = NULL;
-
-        /* Based on vfs_op_init and ... */
-        opv_desc_vector_p = synthfs_vnodeop_opv_desc.opv_desc_vector_p;
-
-        DBG_VOP(("load_synthfs: Allocating and initializing VNode ops vector...\n"));
-
-        /*
-         * Allocate and init the vector.
-         * Also handle backwards compatibility.
-         */
-
-        MALLOC(*opv_desc_vector_p, PFI *, vfs_opv_numops*sizeof(PFI), M_SYNTHFS, M_WAITOK);
-        bzero (*opv_desc_vector_p, vfs_opv_numops*sizeof(PFI));
-        opv_desc_vector = *opv_desc_vector_p;
-        for (j=0; synthfs_vnodeop_opv_desc.opv_desc_ops[j].opve_op; j++) {
-            opve_descp = &(synthfs_vnodeop_opv_desc.opv_desc_ops[j]);
-
-            /*
-             * Sanity check:  is this operation listed
-             * in the list of operations?  We check this
-             * by seeing if its offest is zero.  Since
-             * the default routine should always be listed
-             * first, it should be the only one with a zero
-             * offset.  Any other operation with a zero
-             * offset is probably not listed in
-             * vfs_op_descs, and so is probably an error.
-             *
-             * A panic here means the layer programmer
-             * has committed the all-too common bug
-             * of adding a new operation to the layer's
-             * list of vnode operations but
-             * not adding the operation to the system-wide
-             * list of supported operations.
-             */
-            if (opve_descp->opve_op->vdesc_offset == 0 &&
-                opve_descp->opve_op->vdesc_offset != VOFFSET(vop_default)) {
-                DBG_VOP(("load_synthfs: operation %s not listed in %s.\n",
-                       opve_descp->opve_op->vdesc_name,
-                       "vfs_op_descs"));
-                panic ("load_synthfs: bad operation");
-                }
-            /*
-             * Fill in this entry.
-             */
-            opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
-                opve_descp->opve_impl;
-            }
-
-        /*
-         * Finally, go back and replace unfilled routines
-         * with their default.  (Sigh, an O(n^3) algorithm.  I
-                                 * could make it better, but that'd be work, and n is small.)
-         */
-        opv_desc_vector_p = synthfs_vnodeop_opv_desc.opv_desc_vector_p;
-
-        /*
-         * Force every operations vector to have a default routine.
-         */
-        opv_desc_vector = *opv_desc_vector_p;
-        if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
-            panic("load_vp;fs: operation vector without default routine.");
-            }
-        for (j = 0;j<vfs_opv_numops; j++)
-            if (opv_desc_vector[j] == NULL)
-                opv_desc_vector[j] =
-                    opv_desc_vector[VOFFSET(vop_default)];
-
-               if (error = vfsconf_add(newvfsconf)) {
-                       goto ErrExit;
-               };
-               goto InitFS;
-
-
-ErrExit: ;
-               if (opv_desc_vector_p && *opv_desc_vector_p) FREE(*opv_desc_vector_p, M_SYNTHFS);
-               
-        if (newvfsconf) FREE (newvfsconf, M_SYNTHFS);
-               goto StdExit;
-
-
-InitFS: ;
-        DBG_VOP(("load_synthfs: calling synthfs_init()...\n"));
-        synthfs_init(newvfsconf);
-        };
-
-StdExit: ;
+       /* Should use vfs_fsadd kpi */
 }
 
 
 
 int synthfs_unload(void) {
 }
 
 
 
 int synthfs_unload(void) {
-    DBG_VOP(("synthfs: Entering synthfs_unload...\n"));
 
 
+       /* should use fs_fsremove kpi */
     return 0;
 }
 #endif
     return 0;
 }
 #endif
@@ -227,7 +111,7 @@ int synthfs_unload(void) {
  * mount system call
  */
 int
  * mount system call
  */
 int
-synthfs_mount_fs(struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p)
+synthfs_mount_fs(struct mount *mp, vnode_t devvp, __unused user_addr_t data,  struct proc *p)
 {
        struct synthfs_mntdata *priv_mnt_data;
     int        error;
 {
        struct synthfs_mntdata *priv_mnt_data;
     int        error;
@@ -237,9 +121,8 @@ synthfs_mount_fs(struct mount *mp, char *path, caddr_t data, struct nameidata *n
        MALLOC(priv_mnt_data, struct synthfs_mntdata *, sizeof(struct synthfs_mntdata), M_SYNTHFS, M_WAITOK);
        DBG_VOP(("MALLOC succeeded...\n"));
 
        MALLOC(priv_mnt_data, struct synthfs_mntdata *, sizeof(struct synthfs_mntdata), M_SYNTHFS, M_WAITOK);
        DBG_VOP(("MALLOC succeeded...\n"));
 
-       strncpy(mp->mnt_stat.f_fstypename, synthfs_fs_name, sizeof(mp->mnt_stat.f_fstypename));
-    (void) copyinstr(path, mp->mnt_stat.f_mntonname, sizeof(mp->mnt_stat.f_mntonname) - 1, &size);
-       strncpy(mp->mnt_stat.f_mntfromname, synthfs_fake_mntfromname, sizeof(mp->mnt_stat.f_mntfromname));
+       strncpy(mp->mnt_vfsstat.f_fstypename, synthfs_fs_name, sizeof(mp->mnt_vfsstat.f_fstypename));
+       strncpy(mp->mnt_vfsstat.f_mntfromname, synthfs_fake_mntfromname, sizeof(mp->mnt_vfsstat.f_mntfromname));
     priv_mnt_data->synthfs_mounteddev = (dev_t)0;
     priv_mnt_data->synthfs_nextid = FIRST_SYNTHFS_ID;
     priv_mnt_data->synthfs_filecount = 0;
     priv_mnt_data->synthfs_mounteddev = (dev_t)0;
     priv_mnt_data->synthfs_nextid = FIRST_SYNTHFS_ID;
     priv_mnt_data->synthfs_filecount = 0;
@@ -263,7 +146,7 @@ synthfs_mount_fs(struct mount *mp, char *path, caddr_t data, struct nameidata *n
 
     /* Drop the freshly acquired reference on the root, leaving v_usecount=1 to prevent
        the vnode from beeing freed: */
 
     /* Drop the freshly acquired reference on the root, leaving v_usecount=1 to prevent
        the vnode from beeing freed: */
-    vput(priv_mnt_data->synthfs_rootvp);
+    vnode_put(priv_mnt_data->synthfs_rootvp);
 
     return (0);
 }
 
     return (0);
 }
@@ -271,17 +154,15 @@ synthfs_mount_fs(struct mount *mp, char *path, caddr_t data, struct nameidata *n
 
 
 int
 
 
 int
-synthfs_mount(mp, path, data, ndp, p)
+synthfs_mount(mp, devvp, data, context)
        register struct mount *mp;
        register struct mount *mp;
-       char *path;
-       caddr_t data;
-       struct nameidata *ndp;
-       struct proc *p;
+       vnode_t devvp;
+       user_addr_t data;
+       vfs_context_t context;
 {
        size_t size;
 
 {
        size_t size;
 
-       (void) copyinstr(path, mp->mnt_stat.f_mntonname, sizeof(mp->mnt_stat.f_mntonname) - 1, &size);
-       return (synthfs_mount_fs(mp, path, data, ndp, p));
+       return (synthfs_mount_fs(mp, devvp, data, vfs_context_proc(context)));
 }
 
 
 }
 
 
@@ -301,10 +182,10 @@ synthfs_init(vfsp)
 }
 
 int
 }
 
 int
-synthfs_start(mp, flags, p)
+synthfs_start(mp, flags, context)
 struct mount * mp;
 int    flags;
 struct mount * mp;
 int    flags;
-struct proc * p;
+vfs_context_t context;
 {
     DBG_VOP(("synthfs_start called.\n"));
     return 0;
 {
     DBG_VOP(("synthfs_start called.\n"));
     return 0;
@@ -314,38 +195,27 @@ struct proc * p;
  * Return the root of a filesystem.
  */
 int
  * Return the root of a filesystem.
  */
 int
-synthfs_root(mp, vpp)
+synthfs_root(mp, vpp, context)
         struct mount *mp;
         struct vnode **vpp;
         struct mount *mp;
         struct vnode **vpp;
+        vfs_context_t context;
 {
     unsigned long root_nodeid = ROOT_DIRID;
 
     DBG_VOP(("synthfs_root called.\n"));
 
        *vpp = VFSTOSFS(mp)->synthfs_rootvp;
 {
     unsigned long root_nodeid = ROOT_DIRID;
 
     DBG_VOP(("synthfs_root called.\n"));
 
        *vpp = VFSTOSFS(mp)->synthfs_rootvp;
-       return vget(VFSTOSFS(mp)->synthfs_rootvp, LK_EXCLUSIVE | LK_RETRY, current_proc());
-}
-
-int
-synthfs_quotactl(mp, cmds, uid, arg, p)
-struct mount *mp;
-int cmds;
-uid_t uid;
-caddr_t arg;
-struct proc * p;
-{
-       DBG_VOP(("synthfs_quotactl called.\n"));
-       return (0);
+       return vnode_get(VFSTOSFS(mp)->synthfs_rootvp);
 }
 
 /*
  * unmount system call
  */
 int
 }
 
 /*
  * unmount system call
  */
 int
-synthfs_unmount(mp, mntflags, p)
+synthfs_unmount(mp, mntflags, context)
        struct mount *mp;
        int mntflags;
        struct mount *mp;
        int mntflags;
-       struct proc *p;
+       vfs_context_t context;
 {
     struct synthfs_mntdata *synth;
     struct vnode *root_vp;
 {
     struct synthfs_mntdata *synth;
     struct vnode *root_vp;
@@ -359,16 +229,13 @@ synthfs_unmount(mp, mntflags, p)
     if (retval && ((mntflags & MNT_FORCE) == 0)) goto Err_Exit;
 
     /* Free the root vnode.
     if (retval && ((mntflags & MNT_FORCE) == 0)) goto Err_Exit;
 
     /* Free the root vnode.
-       Note that there's no need to vget() or vref() it before locking it here:
        the ref. count has been maintained at +1 ever since mount time. */
     if (root_vp) {
        the ref. count has been maintained at +1 ever since mount time. */
     if (root_vp) {
-        retval = vn_lock(root_vp, LK_EXCLUSIVE | LK_RETRY, p);
         if ((mntflags & MNT_FORCE) == 0) {
                        if (retval) goto Err_Exit;
         
                if (root_vp->v_usecount > 1) {
                    DBG_VOP(("synthfs ERROR: root vnode = %x, usecount = %d\n", (int)root_vp, synth->synthfs_rootvp->v_usecount));
         if ((mntflags & MNT_FORCE) == 0) {
                        if (retval) goto Err_Exit;
         
                if (root_vp->v_usecount > 1) {
                    DBG_VOP(("synthfs ERROR: root vnode = %x, usecount = %d\n", (int)root_vp, synth->synthfs_rootvp->v_usecount));
-                   VOP_UNLOCK(root_vp, 0, p);
                    retval = EBUSY;
                    goto Err_Exit;
                };
                    retval = EBUSY;
                    goto Err_Exit;
                };
@@ -377,8 +244,10 @@ synthfs_unmount(mp, mntflags, p)
         synth->synthfs_rootvp = NULL;
         
         if (retval == 0) {
         synth->synthfs_rootvp = NULL;
         
         if (retval == 0) {
-               vput(root_vp);                  /* This drops synthfs's own refcount */
-               vgone(root_vp);
+               vnode_get(root_vp);
+               vnode_rele(root_vp);
+               vnode_recycle(root_vp);
+               vnode_put(root_vp);                     /* This drops synthfs's own refcount */
         };
     };
 
         };
     };
 
@@ -398,24 +267,22 @@ Err_Exit:
  * Get file system statistics.
  */
 int
  * Get file system statistics.
  */
 int
-synthfs_statfs(mp, sbp, p)
-       struct mount *mp;
-       register struct statfs *sbp;
-       struct proc *p;
+synthfs_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t context)
 {
 {
-       DBG_VOP(("synthfs_statfs called.\n"));
-
-       sbp->f_bsize = 512;
-       sbp->f_iosize = 512;
-       sbp->f_blocks = 1024;   // lies, darn lies and virtual file systems
-       sbp->f_bfree = 0;               // Nope, can't write here!
-       sbp->f_bavail = 0;
-    sbp->f_files =  VFSTOSFS(mp)->synthfs_filecount + VFSTOSFS(mp)->synthfs_dircount;
-       sbp->f_ffree = 0;
-    strncpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, sizeof(sbp->f_mntonname));
-    strncpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, sizeof(sbp->f_mntfromname));
-
-       return (0);
+       struct synthfs_mntdata *synthfs_mp = VFSTOSFS(mp);
+       DBG_VOP(("synthfs_vfs_getattr called.\n"));
+
+       VFSATTR_RETURN(fsap, f_bsize, 512);
+       VFSATTR_RETURN(fsap, f_iosize, 512);
+       VFSATTR_RETURN(fsap, f_blocks, 1024);
+       VFSATTR_RETURN(fsap, f_bfree, 0);
+       VFSATTR_RETURN(fsap, f_bavail, 0);
+       VFSATTR_RETURN(fsap, f_bused, 1024);
+       VFSATTR_RETURN(fsap, f_files, synthfs_mp->synthfs_filecount + synthfs_mp->synthfs_dircount);
+       VFSATTR_RETURN(fsap, f_ffree, 0);
+       VFSATTR_RETURN(fsap, f_fssubtype, 0);
+
+       return 0;
 }
 
 /*
 }
 
 /*
@@ -423,11 +290,10 @@ synthfs_statfs(mp, sbp, p)
  * structures, so don't do anything
  */
 int
  * structures, so don't do anything
  */
 int
-synthfs_sync(mp, waitfor, cred, p)
+synthfs_sync(mp, waitfor, context)
        struct mount *mp;
        int waitfor;
        struct mount *mp;
        int waitfor;
-       struct ucred *cred;
-       struct proc *p;
+       vfs_context_t context;
 {
 //     DBG_VOP(("synthfs_sync called\n"));
        return 0;
 {
 //     DBG_VOP(("synthfs_sync called\n"));
        return 0;
@@ -436,12 +302,14 @@ synthfs_sync(mp, waitfor, cred, p)
  * Look up a synthfs node by node number.
  */
 int
  * Look up a synthfs node by node number.
  */
 int
-synthfs_vget(mp, ino, vpp)
+synthfs_vget(mp, ino, vpp, context)
        struct mount *mp;
        struct mount *mp;
-       void *ino;
+       ino64_t ino;
        struct vnode **vpp;
        struct vnode **vpp;
+       vfs_context_t context;
 {
        struct vnode *vp;
 {
        struct vnode *vp;
+       int     vid = 0;
        
 //     DBG_VOP(("synthfs_vget called\n"));
 
        
 //     DBG_VOP(("synthfs_vget called\n"));
 
@@ -452,19 +320,25 @@ synthfs_vget(mp, ino, vpp)
        }
 
 loop:
        }
 
 loop:
-       simple_lock(&mntvnode_slock);
-       LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
-               if (VTOS(vp)->s_nodeid == *((unsigned long *)ino)) {
-            if (vget(vp, LK_EXCLUSIVE, current_proc()) != 0) {
-                               simple_unlock(&mntvnode_slock);
-                goto loop;
-            };
-                       simple_unlock(&mntvnode_slock);
+       TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+               if (VTOS(vp)->s_nodeid == (unsigned long)ino) {
+                       /*
+                        * doing a vnode_getwithvid isn't technically 
+                        * necessary since synthfs is an unsafe filesystem
+                        * and we're running behind a funnel at this point
+                        * however, vnode_get always succeeds, which isn't
+                        * what we want if this vnode is in the process of
+                        * being terminated
+                        */
+                       vid = vnode_vid(vp);
+
+                       if (vnode_getwithvid(vp, vid) != 0) {
+                               goto loop;
+                       };
                        *vpp = vp;
                        return 0;
                };
        };
                        *vpp = vp;
                        return 0;
                };
        };
-       simple_unlock(&mntvnode_slock);
        *vpp = NULL;
        return -1;
 }
        *vpp = NULL;
        return -1;
 }
@@ -473,17 +347,11 @@ loop:
  * fast filesystem related variables.
  */
 int
  * fast filesystem related variables.
  */
 int
-synthfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
-       int *name;
-       u_int namelen;
-       void *oldp;
-       size_t *oldlenp;
-       void *newp;
-       size_t newlen;
-       struct proc *p;
+synthfs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp, 
+               user_addr_t newp, size_t newlen, vfs_context_t context)
 {
        DBG_VOP(("synthfs_sysctl called.\n"));
 {
        DBG_VOP(("synthfs_sysctl called.\n"));
-       return (EOPNOTSUPP);
+       return (ENOTSUP);
 }
 
 /*
 }
 
 /*
@@ -491,16 +359,15 @@ synthfs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
  *
  */
 int
  *
  */
 int
-synthfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
+synthfs_fhtovp(mp, fhlen, fhp, vpp, context)
        register struct mount *mp;
        register struct mount *mp;
-       struct fid *fhp;
-       struct mbuf *nam;
+       int fhlen;
+       unsigned char *fhp;
        struct vnode **vpp;
        struct vnode **vpp;
-       int *exflagsp;
-       struct ucred **credanonp;
+       vfs_context_t context;
 {
        DBG_VOP(("synthfs_fhtovp called.\n"));
 {
        DBG_VOP(("synthfs_fhtovp called.\n"));
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 /*
 }
 
 /*
@@ -508,12 +375,14 @@ synthfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
  */
 /* ARGSUSED */
 int
  */
 /* ARGSUSED */
 int
-synthfs_vptofh(vp, fhp)
+synthfs_vptofh(vp, fhlenp, fhp, context)
        struct vnode *vp;
        struct vnode *vp;
-       struct fid *fhp;
+       int *fhlenp;
+       unsigned char *fhp;
+       vfs_context_t context;
 {
        DBG_VOP(("synthfs_vptofh called.\n"));
 {
        DBG_VOP(("synthfs_vptofh called.\n"));
-    return EOPNOTSUPP;
+    return ENOTSUP;
 }
 
 
 }
 
 
@@ -522,38 +391,42 @@ synthfs_vptofh(vp, fhp)
 
 
 int
 
 
 int
-vn_mkdir(struct proc *p, char *path, int mode) {
+vn_mkdir(struct proc *p, char *path, int mode)
+{
        struct nameidata nd;
        struct vnode *vp;
        struct nameidata nd;
        struct vnode *vp;
-       struct vattr vattr;
+       struct vnode_attr va;
+       struct vfs_context context;
        int error;
 
        int error;
 
-       NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, path, p);
-       if (error = namei(&nd)) {
+       context.vc_proc = p;
+       context.vc_ucred = proc_ucred(p);       /* XXX kauth_cred_get() ??? proxy */
+
+       NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE32, CAST_USER_ADDR_T(path), &context);
+       error = namei(&nd);
+       if (error) {
                DBG_VOP(("vn_mkdir: error from namei, error = %d.\n", error));
                return (error);
        };
        vp = nd.ni_vp;
                DBG_VOP(("vn_mkdir: error from namei, error = %d.\n", error));
                return (error);
        };
        vp = nd.ni_vp;
-       if (vp != NULL) {
-               VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-               if (nd.ni_dvp == vp)
-                       vrele(nd.ni_dvp);
-               else
-                       vput(nd.ni_dvp);
-               vrele(vp);
+
+       if (vp == NULL) {
+               VATTR_INIT(&va);
+               VATTR_SET(&va, va_type, VDIR);
+               VATTR_SET(&va, va_mode, (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask);
+
+               error = vn_create(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va, 0, &context);
+               if (error)
+                       DBG_VOP(("vn_mkdir: error from vnop_mkdir (%d).\n", error));
+       } else {
                DBG_VOP(("vn_mkdir: target already exists; returning EEXIST.\n"));
                DBG_VOP(("vn_mkdir: target already exists; returning EEXIST.\n"));
-               return (EEXIST);
+               error = EEXIST;
        }
        }
-       VATTR_NULL(&vattr);
-       vattr.va_type = VDIR;
-       vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask;
-       VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
-       error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
-       if (error) {
-               DBG_VOP(("vn_mkdir: error from VOP_MKDIR (%d).\n", error));
-       } else {
-               vput(nd.ni_vp);
-       };
+       vnode_put(nd.ni_dvp);
+       if (nd.ni_vp)
+               vnode_put(nd.ni_vp);
+       nameidone(&nd);
+
        return (error);
 }
 
        return (error);
 }
 
@@ -562,25 +435,31 @@ vn_mkdir(struct proc *p, char *path, int mode) {
 int
 vn_symlink(struct proc *p, char *path, char *link) {
        struct nameidata nd;
 int
 vn_symlink(struct proc *p, char *path, char *link) {
        struct nameidata nd;
-       struct vattr vattr;
+       struct vnode_attr va;
+       struct vfs_context context;
        int error;
 
        int error;
 
-       NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, link, p);
-       if (error = namei(&nd)) return error;
-
-       if (nd.ni_vp) {
-               VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-               if (nd.ni_dvp == nd.ni_vp)
-                       vrele(nd.ni_dvp);
-               else
-                       vput(nd.ni_dvp);
-               vrele(nd.ni_vp);
-               return EEXIST;
-       }
-       VATTR_NULL(&vattr);
-       vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
-       VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
-       return VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
+       context.vc_proc = p;
+       context.vc_ucred = proc_ucred(p);       /* XXX kauth_cred_get() ??? proxy */
+
+       NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE32, CAST_USER_ADDR_T(link), &context);
+       if ((error = namei(&nd))) return error;
+
+       if (nd.ni_vp == NULL) {
+               VATTR_INIT(&va);
+               VATTR_SET(&va, va_type, VLNK);
+               VATTR_SET(&va, va_mode, ACCESSPERMS &~ p->p_fd->fd_cmask);
+
+               error = VNOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va, path, &context);
+       } else
+               error = EEXIST;
+
+       vnode_put(nd.ni_dvp);
+       if (nd.ni_vp)
+               vnode_put(nd.ni_vp);
+       nameidone(&nd);
+
+       return (error);
 }
 
 
 }