diff -uNr openafs-1.3.81-dist/src/afs/VNOPS/afs_vnop_symlink.c openafs-1.3.81-mkmount-pioctl/src/afs/VNOPS/afs_vnop_symlink.c
--- openafs-1.3.81-dist/src/afs/VNOPS/afs_vnop_symlink.c	2005-01-30 22:49:15.000000000 -0500
+++ openafs-1.3.81-mkmount-pioctl/src/afs/VNOPS/afs_vnop_symlink.c	2005-04-11 10:38:47.792844223 -0400
@@ -49,6 +49,24 @@
      struct vattr *attrs;
      struct AFS_UCRED *acred;
 {
+    AFS_STATCNT(afs_symlink);
+    afs_Trace2(afs_iclSetp, CM_TRACE_SYMLINK, ICL_TYPE_POINTER, adp,
+	       ICL_TYPE_STRING, aname);
+
+    return afs_symlinkOrMount(adp, aname, attrs, atargetName, acred, 0);
+}
+
+
+/* don't set CDirty in here because RPC is called synchronously */
+int afs_symlinkOrMount
+  (OSI_VC_ARG(adp), aname, attrs, atargetName, acred, isMount)
+     OSI_VC_DECL(adp);
+     char *atargetName;
+     char *aname;
+     struct vattr *attrs;
+     struct AFS_UCRED *acred;
+     int isMount;
+{
     afs_uint32 now = 0;
     struct vrequest treq;
     afs_int32 code;
@@ -68,9 +86,11 @@
     XSTATS_DECLS;
     OSI_VC_CONVERT(adp);
 
-    AFS_STATCNT(afs_symlink);
-    afs_Trace2(afs_iclSetp, CM_TRACE_SYMLINK, ICL_TYPE_POINTER, adp,
-	       ICL_TYPE_STRING, aname);
+    afs_Trace4(afs_iclSetp, CM_TRACE_SYMLINKORMOUNT, 
+	       ICL_TYPE_POINTER, adp,
+	       ICL_TYPE_STRING, aname,
+	       ICL_TYPE_STRING, atargetName,
+	       ICL_TYPE_INT32, isMount);
 
     if ((code = afs_InitReq(&treq, acred)))
 	goto done2;
@@ -107,7 +127,7 @@
     InStatus.Mask = AFS_SETMODTIME | AFS_SETMODE;
     InStatus.ClientModTime = osi_Time();
     alen = strlen(atargetName);	/* we want it to include the null */
-    if (*atargetName == '#' || *atargetName == '%') {
+    if (isMount) {
 	InStatus.UnixModeBits = 0644;	/* mt pt: null from "." at end */
 	if (alen == 1)
 	    alen++;		/* Empty string */
diff -uNr openafs-1.3.81-dist/src/afs/afs_pioctl.c openafs-1.3.81-mkmount-pioctl/src/afs/afs_pioctl.c
--- openafs-1.3.81-dist/src/afs/afs_pioctl.c	2005-04-04 00:01:14.000000000 -0400
+++ openafs-1.3.81-mkmount-pioctl/src/afs/afs_pioctl.c	2005-04-11 16:14:09.227413903 -0400
@@ -89,6 +89,7 @@
 DECL_PIOCTL(PPrefetchFromTape);
 DECL_PIOCTL(PResidencyCmd);
 DECL_PIOCTL(PCallBackAddr);
+DECL_PIOCTL(PCreateMount);
 
 /*
  * A macro that says whether we're going to need HandleClientContext().
@@ -183,6 +184,7 @@
 	PPrefetchFromTape,	/* 66 -- MR-AFS: prefetch file from tape */
 	PResidencyCmd,		/* 67 -- MR-AFS: generic commnd interface */
 	PBogus,			/* 68 -- arla: fetch stats */
+	PCreateMount,		/* 69 -- create mount point */
 };
 
 static int (*(CpioctlSw[])) () = {
@@ -2472,6 +2474,36 @@
     return code;
 }
 
+DECL_PIOCTL(PCreateMount)
+{
+    char * aname, * atarget;
+    int i, null_count = 0, null_pos[2];
+
+    afs_Trace3(afs_iclSetp, CM_TRACE_PCREATEMOUNT, ICL_TYPE_POINTER, avc,
+	       ICL_TYPE_POINTER, ain, ICL_TYPE_INT32, ainSize);
+
+    AFS_STATCNT(PCreateMount);
+    if (!avc || !ain)
+        return EINVAL;
+
+    /* verify that we were passed 2 null-terminated strings */
+    for (i=0; (i < ainSize) && (null_count < 2); i++) {
+        if (ain[i] == '\0')
+	    null_pos[null_count++] = i;
+    }
+
+    if (null_count < 2)
+        return EINVAL;
+
+    aname = ain;
+    atarget = &ain[null_pos[0]+1];
+
+    if ((*atarget != '#') && (*atarget != '%'))
+        return EINVAL;
+
+    return afs_symlinkOrMount(avc, aname, NULL, atarget, *acred, 1);
+}
+
 DECL_PIOCTL(PVenusLogging)
 {
     return EINVAL;		/* OBSOLETE */
diff -uNr openafs-1.3.81-dist/src/afs/afs_prototypes.h openafs-1.3.81-mkmount-pioctl/src/afs/afs_prototypes.h
--- openafs-1.3.81-dist/src/afs/afs_prototypes.h	2005-04-03 14:18:54.000000000 -0400
+++ openafs-1.3.81-mkmount-pioctl/src/afs/afs_prototypes.h	2005-04-11 02:49:45.709906236 -0400
@@ -1037,6 +1037,7 @@
 extern int afs_ustrategy();
 extern int afs_lockctl();
 
+extern int afs_symlinkOrMount();
 
 /* afs_volume.c */
 extern afs_int32 afs_FVIndex;
diff -uNr openafs-1.3.81-dist/src/afs/afs_stats.h openafs-1.3.81-mkmount-pioctl/src/afs/afs_stats.h
--- openafs-1.3.81-dist/src/afs/afs_stats.h	2004-12-07 01:12:12.000000000 -0500
+++ openafs-1.3.81-mkmount-pioctl/src/afs/afs_stats.h	2005-04-11 05:33:09.840316402 -0400
@@ -639,6 +639,7 @@
     afs_int32 C_SRXAFSCB_GetCacheConfig;	/* afs_callback.c */
     afs_int32 C_SRXAFSCB_GetCE64;	/* afs_callback.c */
     afs_int32 C_SRXAFSCB_GetCellByNum;	/* afs_callback.c */
+    afs_int32 C_PCreateMount;	/* afs_pioctl.c */
 };
 
 struct afs_CMMeanStats {
diff -uNr openafs-1.3.81-dist/src/afs/afs_trace.et openafs-1.3.81-mkmount-pioctl/src/afs/afs_trace.et
--- openafs-1.3.81-dist/src/afs/afs_trace.et	2003-07-16 18:22:54.000000000 -0400
+++ openafs-1.3.81-mkmount-pioctl/src/afs/afs_trace.et	2005-04-11 11:06:39.702956404 -0400
@@ -172,5 +172,7 @@
 	ec	CM_TRACE_LOCKWAIT,"%s line %d: Waiting for lock 0x%lx level %d"
 	ec	CM_TRACE_WRITEFAILED, "osi_Write failed len %ld resid %ld err %ld"
 	ec	CM_TRACE_ADJUSTSIZE2, "AdjustSize dc = 0x%lx, chunkBytes = 0x%x used = %ld, diff = %ld"
+	ec	CM_TRACE_PCREATEMOUNT, "PCreateMount start avc = 0x%lx, ain = 0x%lx, ainSize = %d"
+	ec	CM_TRACE_SYMLINKORMOUNT, "afs_symlinkOrMount: dir = 0x%lx, name = %s, target = %s, isMount = %d"
 end
 
diff -uNr openafs-1.3.81-dist/src/config/venus.h openafs-1.3.81-mkmount-pioctl/src/config/venus.h
--- openafs-1.3.81-dist/src/config/venus.h	2004-06-02 04:43:02.000000000 -0400
+++ openafs-1.3.81-mkmount-pioctl/src/config/venus.h	2005-04-11 16:14:29.025468238 -0400
@@ -175,6 +175,7 @@
 #define VIOC_PREFETCHTAPE       _VICEIOCTL(66)	/* MR-AFS prefetch from tape */
 #define VIOC_RESIDENCY_CMD      _VICEIOCTL(67)	/* generic MR-AFS cmds */
 #define VIOC_STATISTICS         _VICEIOCTL(68)	/* arla: fetch statistics */
+#define VIOC_AFS_CREATE_MT_PT   _VICEIOCTL(69)	/* [AFS] Create mount point */
 
 /* Coordinated 'C' pioctl's */
 #define VIOC_NEWALIAS		_CVICEIOCTL(1)	/* create new cell alias */
diff -uNr openafs-1.3.81-dist/src/venus/fs.c openafs-1.3.81-mkmount-pioctl/src/venus/fs.c
--- openafs-1.3.81-dist/src/venus/fs.c	2004-10-18 03:12:20.000000000 -0400
+++ openafs-1.3.81-mkmount-pioctl/src/venus/fs.c	2005-04-11 16:18:51.311167047 -0400
@@ -54,7 +54,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <afs/ptclient.h>
-
+#include <afs/afs.h>
 
 #define	MAXHOSTS 13
 #define	OMAXHOSTS 8
@@ -1615,7 +1615,8 @@
     struct afsconf_cell info;
     struct vldbentry vldbEntry;
     struct ViceIoctl blob;
-
+    char blob_buffer[4096];
+    int name_len, target_len;
 /*
 
 defect #3069
@@ -1701,7 +1702,19 @@
     }
     strcat(space, volName);	/* append volume name */
     strcat(space, ".");		/* stupid convention; these end with a period */
-    code = symlink(space, as->parms[0].items->data);
+
+    /* stuff the mountpoint name and target into the buffer */
+    memset(blob_buffer, 0, sizeof(blob_buffer));
+    name_len = strlen(as->parms[0].items->data);
+    target_len = strlen(space);
+    strncpy(blob_buffer, as->parms[0].items->data, name_len);
+    strncpy(&blob_buffer[name_len+1], space, target_len);
+
+    /* stuff our buffer into the viceioctl input field */
+    blob.out_size = 0;
+    blob.in = blob_buffer;
+    blob.in_size = name_len + target_len + 2;
+    code = pioctl(Parent(as->parms[0].items->data), VIOC_AFS_CREATE_MT_PT, &blob, 0);
     if (code) {
 	Die(errno, as->parms[0].items->data);
 	return 1;
