BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / nfs / nfs_vnops.c
index ed72c0e..3e55e48 100644 (file)
@@ -5,9 +5,35 @@
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
  * This code is derived from software contributed to Berkeley by
  * Rick Macklem at The University of Guelph.
  *
- * %sccs.include.redist.c%
+ * 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.
  *
  *
- *     @(#)nfs_vnops.c 7.57 (Berkeley) %G%
+ * 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.
+ *
+ *     @(#)nfs_vnops.c 7.60 (Berkeley) 5/24/91
  */
 
 /*
  */
 
 /*
@@ -31,6 +57,7 @@
 
 #include "../ufs/quota.h"
 #include "../ufs/inode.h"
 
 #include "../ufs/quota.h"
 #include "../ufs/inode.h"
+#include "../ufs/dir.h"
 
 #include "nfsv2.h"
 #include "nfs.h"
 
 #include "nfsv2.h"
 #include "nfs.h"
@@ -415,10 +442,6 @@ nfs_lookup(vp, ndp, p)
                struct vattr vattr;
                int vpid;
 
                struct vattr vattr;
                int vpid;
 
-#ifdef PARANOID
-               if (vp == ndp->ni_rdir && ndp->ni_isdotdot)
-                       panic("nfs_lookup: .. through root");
-#endif
                vdp = ndp->ni_vp;
                vpid = vdp->v_id;
                /*
                vdp = ndp->ni_vp;
                vpid = vdp->v_id;
                /*
@@ -443,6 +466,8 @@ nfs_lookup(vp, ndp, p)
                           if (!nfs_dogetattr(vdp, &vattr, ndp->ni_cred, 0, p)&&
                               vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime) {
                                nfsstats.lookupcache_hits++;
                           if (!nfs_dogetattr(vdp, &vattr, ndp->ni_cred, 0, p)&&
                               vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime) {
                                nfsstats.lookupcache_hits++;
+                               if (flag != LOOKUP && *ndp->ni_next == 0)
+                                       ndp->ni_nameiop |= SAVENAME;
                                return (0);
                           }
                           cache_purge(vdp);
                                return (0);
                           }
                           cache_purge(vdp);
@@ -467,6 +492,8 @@ nfsmout:
                if (lockparent || (flag != CREATE && flag != RENAME) ||
                    *ndp->ni_next != 0)
                        nfs_lock(vp);
                if (lockparent || (flag != CREATE && flag != RENAME) ||
                    *ndp->ni_next != 0)
                        nfs_lock(vp);
+               if (flag != LOOKUP && *ndp->ni_next == 0)
+                       ndp->ni_nameiop |= SAVENAME;
                return (error);
        }
        nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH);
                return (error);
        }
        nfsm_disect(fhp,nfsv2fh_t *,NFSX_FH);
@@ -501,6 +528,7 @@ nfsmout:
                if (lockparent || vp == newvp)
                        nfs_lock(vp);
                m_freem(mrep);
                if (lockparent || vp == newvp)
                        nfs_lock(vp);
                m_freem(mrep);
+               ndp->ni_nameiop |= SAVENAME;
                return (0);
        }
 
                return (0);
        }
 
@@ -527,6 +555,7 @@ nfsmout:
                if (lockparent)
                        nfs_lock(vp);
                m_freem(mrep);
                if (lockparent)
                        nfs_lock(vp);
                m_freem(mrep);
+               ndp->ni_nameiop |= SAVENAME;
                return (0);
        }
 
                return (0);
        }
 
@@ -563,6 +592,8 @@ nfsmout:
        if (vp == newvp || (lockparent && *ndp->ni_next == '\0'))
                nfs_lock(vp);
        ndp->ni_vp = newvp;
        if (vp == newvp || (lockparent && *ndp->ni_next == '\0'))
                nfs_lock(vp);
        ndp->ni_vp = newvp;
+       if (flag != LOOKUP && *ndp->ni_next == 0)
+               ndp->ni_nameiop |= SAVENAME;
        if (error == 0 && ndp->ni_makeentry) {
                np->n_ctime = np->n_vattr.va_ctime.tv_sec;
                cache_enter(ndp);
        if (error == 0 && ndp->ni_makeentry) {
                np->n_ctime = np->n_vattr.va_ctime.tv_sec;
                cache_enter(ndp);
@@ -744,9 +775,9 @@ nfs_mknod(ndp, vap, cred, p)
        }
        nfsstats.rpccnt[NFSPROC_CREATE]++;
        nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
        }
        nfsstats.rpccnt[NFSPROC_CREATE]++;
        nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
-         NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR);
+         NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_SATTR);
        nfsm_fhtom(ndp->ni_dvp);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
@@ -757,6 +788,7 @@ nfs_mknod(ndp, vap, cred, p)
        txdr_time(&vap->va_mtime, &sp->sa_mtime);
        nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
        nfsm_reqdone;
        txdr_time(&vap->va_mtime, &sp->sa_mtime);
        nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
        nfsm_reqdone;
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        return (error);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        return (error);
@@ -781,9 +813,9 @@ nfs_create(ndp, vap, p)
 
        nfsstats.rpccnt[NFSPROC_CREATE]++;
        nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
 
        nfsstats.rpccnt[NFSPROC_CREATE]++;
        nfsm_reqhead(nfs_procids[NFSPROC_CREATE], ndp->ni_cred,
-         NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_SATTR);
+         NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_SATTR);
        nfsm_fhtom(ndp->ni_dvp);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(vap->va_type, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
@@ -795,6 +827,7 @@ nfs_create(ndp, vap, p)
        nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
        nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
        nfsm_reqdone;
        nfsm_request(ndp->ni_dvp, NFSPROC_CREATE, p, 1);
        nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
        nfsm_reqdone;
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        return (error);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        return (error);
@@ -827,15 +860,16 @@ nfs_remove(ndp, p)
 
        if (vp->v_usecount > 1) {
                if (!np->n_sillyrename)
 
        if (vp->v_usecount > 1) {
                if (!np->n_sillyrename)
-                       error = nfs_sillyrename(ndp, REMOVE, p);
+                       error = nfs_sillyrename(ndp, p);
        } else {
                nfsstats.rpccnt[NFSPROC_REMOVE]++;
                nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
        } else {
                nfsstats.rpccnt[NFSPROC_REMOVE]++;
                nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
-                       NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
+                       NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
                nfsm_fhtom(ndp->ni_dvp);
                nfsm_fhtom(ndp->ni_dvp);
-               nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+               nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
                nfsm_request(ndp->ni_dvp, NFSPROC_REMOVE, p, 1);
                nfsm_reqdone;
                nfsm_request(ndp->ni_dvp, NFSPROC_REMOVE, p, 1);
                nfsm_reqdone;
+               FREE(ndp->ni_pnbuf, M_NAMEI);
                VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
                /*
                 * Kludge City: If the first reply to the remove rpc is lost..
                VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
                /*
                 * Kludge City: If the first reply to the remove rpc is lost..
@@ -858,8 +892,8 @@ nfs_remove(ndp, p)
 /*
  * nfs file remove rpc called from nfs_inactive
  */
 /*
  * nfs file remove rpc called from nfs_inactive
  */
-nfs_removeit(ndp, p)
-       register struct nameidata *ndp;
+nfs_removeit(sp, p)
+       register struct sillyrename *sp;
        struct proc *p;
 {
        register u_long *tl;
        struct proc *p;
 {
        register u_long *tl;
@@ -871,13 +905,13 @@ nfs_removeit(ndp, p)
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
        nfsstats.rpccnt[NFSPROC_REMOVE]++;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
        nfsstats.rpccnt[NFSPROC_REMOVE]++;
-       nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], ndp->ni_cred,
-               NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
-       nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
-       nfsm_request(ndp->ni_dvp, NFSPROC_REMOVE, p, 1);
+       nfsm_reqhead(nfs_procids[NFSPROC_REMOVE], sp->s_cred,
+               NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(sp->s_namlen));
+       nfsm_fhtom(sp->s_dvp);
+       nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
+       nfsm_request(sp->s_dvp, NFSPROC_REMOVE, p, 1);
        nfsm_reqdone;
        nfsm_reqdone;
-       VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
+       VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;
        return (error);
 }
 
        return (error);
 }
 
@@ -898,12 +932,12 @@ nfs_rename(sndp, tndp, p)
 
        nfsstats.rpccnt[NFSPROC_RENAME]++;
        nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
 
        nfsstats.rpccnt[NFSPROC_RENAME]++;
        nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
-               (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+
-               nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/
+               (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_namelen) +
+               nfsm_rndup(tndp->ni_namelen)); /* or sndp->ni_cred?*/
        nfsm_fhtom(sndp->ni_dvp);
        nfsm_fhtom(sndp->ni_dvp);
-       nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
+       nfsm_strtom(sndp->ni_ptr, sndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_fhtom(tndp->ni_dvp);
        nfsm_fhtom(tndp->ni_dvp);
-       nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
+       nfsm_strtom(tndp->ni_ptr, tndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
        nfsm_reqdone;
        VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
        nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
        nfsm_reqdone;
        VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
@@ -913,14 +947,12 @@ nfs_rename(sndp, tndp, p)
                        cache_purge(tndp->ni_dvp);
                cache_purge(sndp->ni_dvp);
        }
                        cache_purge(tndp->ni_dvp);
                cache_purge(sndp->ni_dvp);
        }
-       VOP_ABORTOP(tndp);
        if (tndp->ni_dvp == tndp->ni_vp)
                vrele(tndp->ni_dvp);
        else
                vput(tndp->ni_dvp);
        if (tndp->ni_vp)
                vput(tndp->ni_vp);
        if (tndp->ni_dvp == tndp->ni_vp)
                vrele(tndp->ni_dvp);
        else
                vput(tndp->ni_dvp);
        if (tndp->ni_vp)
                vput(tndp->ni_vp);
-       VOP_ABORTOP(sndp);
        vrele(sndp->ni_dvp);
        vrele(sndp->ni_vp);
        /*
        vrele(sndp->ni_dvp);
        vrele(sndp->ni_vp);
        /*
@@ -934,8 +966,9 @@ nfs_rename(sndp, tndp, p)
 /*
  * nfs file rename rpc called from nfs_remove() above
  */
 /*
  * nfs file rename rpc called from nfs_remove() above
  */
-nfs_renameit(sndp, tndp, p)
-       register struct nameidata *sndp, *tndp;
+nfs_renameit(sndp, sp, p)
+       register struct nameidata *sndp;
+       register struct sillyrename *sp;
        struct proc *p;
 {
        register u_long *tl;
        struct proc *p;
 {
        register u_long *tl;
@@ -947,17 +980,18 @@ nfs_renameit(sndp, tndp, p)
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
        nfsstats.rpccnt[NFSPROC_RENAME]++;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
        nfsstats.rpccnt[NFSPROC_RENAME]++;
-       nfsm_reqhead(nfs_procids[NFSPROC_RENAME], tndp->ni_cred,
-               (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_dent.d_namlen)+
-               nfsm_rndup(tndp->ni_dent.d_namlen)); /* or sndp->ni_cred?*/
+       nfsm_reqhead(nfs_procids[NFSPROC_RENAME], sp->s_cred,
+               (NFSX_FH+NFSX_UNSIGNED)*2+nfsm_rndup(sndp->ni_namelen) +
+               nfsm_rndup(sp->s_namlen)); /* or sndp->ni_cred?*/
        nfsm_fhtom(sndp->ni_dvp);
        nfsm_fhtom(sndp->ni_dvp);
-       nfsm_strtom(sndp->ni_dent.d_name,sndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
-       nfsm_fhtom(tndp->ni_dvp);
-       nfsm_strtom(tndp->ni_dent.d_name,tndp->ni_dent.d_namlen,NFS_MAXNAMLEN);
+       nfsm_strtom(sndp->ni_ptr, sndp->ni_namelen, NFS_MAXNAMLEN);
+       nfsm_fhtom(sp->s_dvp);
+       nfsm_strtom(sp->s_name, sp->s_namlen, NFS_MAXNAMLEN);
        nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
        nfsm_reqdone;
        nfsm_request(sndp->ni_dvp, NFSPROC_RENAME, p, 1);
        nfsm_reqdone;
+       FREE(sndp->ni_pnbuf, M_NAMEI);
        VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
        VTONFS(sndp->ni_dvp)->n_flag |= NMODIFIED;
-       VTONFS(tndp->ni_dvp)->n_flag |= NMODIFIED;
+       VTONFS(sp->s_dvp)->n_flag |= NMODIFIED;
        return (error);
 }
 
        return (error);
 }
 
@@ -981,12 +1015,13 @@ nfs_link(vp, ndp, p)
                nfs_lock(vp);
        nfsstats.rpccnt[NFSPROC_LINK]++;
        nfsm_reqhead(nfs_procids[NFSPROC_LINK], ndp->ni_cred,
                nfs_lock(vp);
        nfsstats.rpccnt[NFSPROC_LINK]++;
        nfsm_reqhead(nfs_procids[NFSPROC_LINK], ndp->ni_cred,
-               NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
+               NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
        nfsm_fhtom(vp);
        nfsm_fhtom(ndp->ni_dvp);
        nfsm_fhtom(vp);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_request(vp, NFSPROC_LINK, p, 1);
        nfsm_reqdone;
        nfsm_request(vp, NFSPROC_LINK, p, 1);
        nfsm_reqdone;
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        VTONFS(vp)->n_attrstamp = 0;
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        if (ndp->ni_dvp != vp)
        VTONFS(vp)->n_attrstamp = 0;
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        if (ndp->ni_dvp != vp)
@@ -1020,9 +1055,9 @@ nfs_symlink(ndp, vap, nm, p)
 
        nfsstats.rpccnt[NFSPROC_SYMLINK]++;
        nfsm_reqhead(nfs_procids[NFSPROC_SYMLINK], ndp->ni_cred,
 
        nfsstats.rpccnt[NFSPROC_SYMLINK]++;
        nfsm_reqhead(nfs_procids[NFSPROC_SYMLINK], ndp->ni_cred,
-       NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen)+NFSX_UNSIGNED);
+       NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen)+NFSX_UNSIGNED);
        nfsm_fhtom(ndp->ni_dvp);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_strtom(nm, strlen(nm), NFS_MAXPATHLEN);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode);
        nfsm_strtom(nm, strlen(nm), NFS_MAXPATHLEN);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(VLNK, vap->va_mode);
@@ -1033,6 +1068,7 @@ nfs_symlink(ndp, vap, nm, p)
        txdr_time(&vap->va_mtime, &sp->sa_mtime);       /* or VNOVAL ?? */
        nfsm_request(ndp->ni_dvp, NFSPROC_SYMLINK, p, 1);
        nfsm_reqdone;
        txdr_time(&vap->va_mtime, &sp->sa_mtime);       /* or VNOVAL ?? */
        nfsm_request(ndp->ni_dvp, NFSPROC_SYMLINK, p, 1);
        nfsm_reqdone;
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        /*
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        nfs_nput(ndp->ni_dvp);
        /*
@@ -1061,12 +1097,12 @@ nfs_mkdir(ndp, vap, p)
        int error = 0, firsttry = 1;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
        int error = 0, firsttry = 1;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
 
-       len = ndp->ni_dent.d_namlen;
+       len = ndp->ni_namelen;
        nfsstats.rpccnt[NFSPROC_MKDIR]++;
        nfsm_reqhead(nfs_procids[NFSPROC_MKDIR], ndp->ni_cred,
          NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR);
        nfsm_fhtom(ndp->ni_dvp);
        nfsstats.rpccnt[NFSPROC_MKDIR]++;
        nfsm_reqhead(nfs_procids[NFSPROC_MKDIR], ndp->ni_cred,
          NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len)+NFSX_SATTR);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, len, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
        nfsm_build(sp, struct nfsv2_sattr *, NFSX_SATTR);
        sp->sa_mode = vtonfs_mode(VDIR, vap->va_mode);
        sp->sa_uid = txdr_unsigned(ndp->ni_cred->cr_uid);
@@ -1092,7 +1128,7 @@ nfs_mkdir(ndp, vap, p)
                nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred,
                    NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
                nfsm_fhtom(ndp->ni_dvp);
                nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred,
                    NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
                nfsm_fhtom(ndp->ni_dvp);
-               nfsm_strtom(ndp->ni_dent.d_name, len, NFS_MAXNAMLEN);
+               nfsm_strtom(ndp->ni_ptr, len, NFS_MAXNAMLEN);
                nfsm_request(ndp->ni_dvp, NFSPROC_LOOKUP, p, 1);
                nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
                if (ndp->ni_vp->v_type != VDIR) {
                nfsm_request(ndp->ni_dvp, NFSPROC_LOOKUP, p, 1);
                nfsm_mtofh(ndp->ni_dvp, ndp->ni_vp);
                if (ndp->ni_vp->v_type != VDIR) {
@@ -1101,6 +1137,7 @@ nfs_mkdir(ndp, vap, p)
                }
                m_freem(mrep);
        }
                }
                m_freem(mrep);
        }
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        nfs_nput(ndp->ni_dvp);
        return (error);
 }
        nfs_nput(ndp->ni_dvp);
        return (error);
 }
@@ -1127,11 +1164,12 @@ nfs_rmdir(ndp, p)
        }
        nfsstats.rpccnt[NFSPROC_RMDIR]++;
        nfsm_reqhead(nfs_procids[NFSPROC_RMDIR], ndp->ni_cred,
        }
        nfsstats.rpccnt[NFSPROC_RMDIR]++;
        nfsm_reqhead(nfs_procids[NFSPROC_RMDIR], ndp->ni_cred,
-               NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_dent.d_namlen));
+               NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(ndp->ni_namelen));
        nfsm_fhtom(ndp->ni_dvp);
        nfsm_fhtom(ndp->ni_dvp);
-       nfsm_strtom(ndp->ni_dent.d_name, ndp->ni_dent.d_namlen, NFS_MAXNAMLEN);
+       nfsm_strtom(ndp->ni_ptr, ndp->ni_namelen, NFS_MAXNAMLEN);
        nfsm_request(ndp->ni_dvp, NFSPROC_RMDIR, p, 1);
        nfsm_reqdone;
        nfsm_request(ndp->ni_dvp, NFSPROC_RMDIR, p, 1);
        nfsm_reqdone;
+       FREE(ndp->ni_pnbuf, M_NAMEI);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        cache_purge(ndp->ni_dvp);
        cache_purge(ndp->ni_vp);
        VTONFS(ndp->ni_dvp)->n_flag |= NMODIFIED;
        cache_purge(ndp->ni_dvp);
        cache_purge(ndp->ni_vp);
@@ -1341,52 +1379,51 @@ static char hextoasc[] = "0123456789abcdef";
  * to create the same funny name between the nfs_lookitup() fails and the
  * nfs_rename() completes, but...
  */
  * to create the same funny name between the nfs_lookitup() fails and the
  * nfs_rename() completes, but...
  */
-nfs_sillyrename(ndp, flag, p)
+nfs_sillyrename(ndp, p)
        register struct nameidata *ndp;
        register struct nameidata *ndp;
-       int flag;
        struct proc *p;
 {
        register struct nfsnode *np;
        register struct sillyrename *sp;
        struct proc *p;
 {
        register struct nfsnode *np;
        register struct sillyrename *sp;
-       register struct nameidata *tndp;
        int error;
        short pid;
 
        np = VTONFS(ndp->ni_dvp);
        cache_purge(ndp->ni_dvp);
        MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
        int error;
        short pid;
 
        np = VTONFS(ndp->ni_dvp);
        cache_purge(ndp->ni_dvp);
        MALLOC(sp, struct sillyrename *, sizeof (struct sillyrename),
-               M_TEMP, M_WAITOK);
-       sp->s_flag = flag;
+               M_NFSREQ, M_WAITOK);
        bcopy((caddr_t)&np->n_fh, (caddr_t)&sp->s_fh, NFSX_FH);
        np = VTONFS(ndp->ni_vp);
        bcopy((caddr_t)&np->n_fh, (caddr_t)&sp->s_fh, NFSX_FH);
        np = VTONFS(ndp->ni_vp);
-       tndp = &sp->s_namei;
-       tndp->ni_cred = crdup(ndp->ni_cred);
+       sp->s_cred = crdup(ndp->ni_cred);
+       sp->s_dvp = ndp->ni_dvp;
+       VREF(sp->s_dvp);
 
        /* Fudge together a funny name */
        pid = p->p_pid;
 
        /* Fudge together a funny name */
        pid = p->p_pid;
-       bcopy(".nfsAxxxx4.4", tndp->ni_dent.d_name, 13);
-       tndp->ni_dent.d_namlen = 12;
-       tndp->ni_dent.d_name[8] = hextoasc[pid & 0xf];
-       tndp->ni_dent.d_name[7] = hextoasc[(pid >> 4) & 0xf];
-       tndp->ni_dent.d_name[6] = hextoasc[(pid >> 8) & 0xf];
-       tndp->ni_dent.d_name[5] = hextoasc[(pid >> 12) & 0xf];
+       bcopy(".nfsAxxxx4.4", sp->s_name, 13);
+       sp->s_namlen = 12;
+       sp->s_name[8] = hextoasc[pid & 0xf];
+       sp->s_name[7] = hextoasc[(pid >> 4) & 0xf];
+       sp->s_name[6] = hextoasc[(pid >> 8) & 0xf];
+       sp->s_name[5] = hextoasc[(pid >> 12) & 0xf];
 
        /* Try lookitups until we get one that isn't there */
 
        /* Try lookitups until we get one that isn't there */
-       while (nfs_lookitup(ndp->ni_dvp, tndp, (nfsv2fh_t *)0, p) == 0) {
-               tndp->ni_dent.d_name[4]++;
-               if (tndp->ni_dent.d_name[4] > 'z') {
+       while (nfs_lookitup(sp, (nfsv2fh_t *)0, p) == 0) {
+               sp->s_name[4]++;
+               if (sp->s_name[4] > 'z') {
                        error = EINVAL;
                        goto bad;
                }
        }
                        error = EINVAL;
                        goto bad;
                }
        }
-       if (error = nfs_renameit(ndp, tndp, p))
+       if (error = nfs_renameit(ndp, sp, p))
                goto bad;
                goto bad;
-       nfs_lookitup(ndp->ni_dvp, tndp, &np->n_fh, p);
+       nfs_lookitup(sp, &np->n_fh, p);
        np->n_sillyrename = sp;
        return (0);
 bad:
        np->n_sillyrename = sp;
        return (0);
 bad:
-       crfree(tndp->ni_cred);
-       free((caddr_t)sp, M_TEMP);
+       vrele(sp->s_dvp);
+       crfree(sp->s_cred);
+       free((caddr_t)sp, M_NFSREQ);
        return (error);
 }
 
        return (error);
 }
 
@@ -1396,12 +1433,12 @@ bad:
  * into the nfsnode table.
  * If fhp != NULL it copies the returned file handle out
  */
  * into the nfsnode table.
  * If fhp != NULL it copies the returned file handle out
  */
-nfs_lookitup(vp, ndp, fhp, p)
-       register struct vnode *vp;
-       register struct nameidata *ndp;
+nfs_lookitup(sp, fhp, p)
+       register struct sillyrename *sp;
        nfsv2fh_t *fhp;
        struct proc *p;
 {
        nfsv2fh_t *fhp;
        struct proc *p;
 {
+       register struct vnode *vp = sp->s_dvp;
        register u_long *tl;
        register caddr_t cp;
        register long t1, t2;
        register u_long *tl;
        register caddr_t cp;
        register long t1, t2;
@@ -1412,12 +1449,10 @@ nfs_lookitup(vp, ndp, fhp, p)
        long len;
 
        nfsstats.rpccnt[NFSPROC_LOOKUP]++;
        long len;
 
        nfsstats.rpccnt[NFSPROC_LOOKUP]++;
-       ndp->ni_dvp = vp;
-       ndp->ni_vp = NULL;
-       len = ndp->ni_dent.d_namlen;
-       nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], ndp->ni_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
+       len = sp->s_namlen;
+       nfsm_reqhead(nfs_procids[NFSPROC_LOOKUP], sp->s_cred, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));
        nfsm_fhtom(vp);
        nfsm_fhtom(vp);
-       nfsm_strtom(ndp->ni_dent.d_name, len, NFS_MAXNAMLEN);
+       nfsm_strtom(sp->s_name, len, NFS_MAXNAMLEN);
        nfsm_request(vp, NFSPROC_LOOKUP, p, 1);
        if (fhp != NULL) {
                nfsm_disect(cp, caddr_t, NFSX_FH);
        nfsm_request(vp, NFSPROC_LOOKUP, p, 1);
        if (fhp != NULL) {
                nfsm_disect(cp, caddr_t, NFSX_FH);