BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / nfs / nfs_node.c
index acb753c..810378e 100644 (file)
@@ -5,36 +5,50 @@
  * 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.
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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_node.c  7.10 (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_node.c  7.34 (Berkeley) 5/15/91
  */
 
 #include "param.h"
 #include "systm.h"
  */
 
 #include "param.h"
 #include "systm.h"
-#include "user.h"
 #include "proc.h"
 #include "mount.h"
 #include "proc.h"
 #include "mount.h"
-#include "vnode.h"
-#include "../ufs/dir.h"
 #include "namei.h"
 #include "namei.h"
-#include "errno.h"
+#include "vnode.h"
+#include "kernel.h"
+#include "malloc.h"
+
 #include "nfsv2.h"
 #include "nfs.h"
 #include "nfsnode.h"
 #include "nfsmount.h"
 #include "nfsv2.h"
 #include "nfs.h"
 #include "nfsnode.h"
 #include "nfsmount.h"
-#include "kernel.h"
-#include "malloc.h"
 
 /* The request list head */
 extern struct nfsreq nfsreqh;
 
 /* The request list head */
 extern struct nfsreq nfsreqh;
@@ -117,7 +131,7 @@ loop:
                        continue;
                if ((np->n_flag & NLOCKED) != 0) {
                        np->n_flag |= NWANT;
                        continue;
                if ((np->n_flag & NLOCKED) != 0) {
                        np->n_flag |= NWANT;
-                       sleep((caddr_t)np, PINOD);
+                       (void) tsleep((caddr_t)np, PINOD, "nfsnode", 0);
                        goto loop;
                }
                vp = NFSTOV(np);
                        goto loop;
                }
                vp = NFSTOV(np);
@@ -136,10 +150,12 @@ loop:
        /*
         * Insert the nfsnode in the hash queue for its new file handle
         */
        /*
         * Insert the nfsnode in the hash queue for its new file handle
         */
-       np->n_flag = NLOCKED;
+       np->n_flag = 0;
        insque(np, nh);
        insque(np, nh);
+       nfs_lock(vp);
        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
        np->n_attrstamp = 0;
        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
        np->n_attrstamp = 0;
+       np->n_direofoffset = 0;
        np->n_sillyrename = (struct sillyrename *)0;
        np->n_size = 0;
        np->n_mtime = 0;
        np->n_sillyrename = (struct sillyrename *)0;
        np->n_size = 0;
        np->n_mtime = 0;
@@ -147,18 +163,18 @@ loop:
        return (0);
 }
 
        return (0);
 }
 
-nfs_inactive(vp)
+nfs_inactive(vp, p)
        struct vnode *vp;
        struct vnode *vp;
+       struct proc *p;
 {
        register struct nfsnode *np;
 {
        register struct nfsnode *np;
-       register struct nameidata *ndp;
        register struct sillyrename *sp;
        struct nfsnode *dnp;
        register struct sillyrename *sp;
        struct nfsnode *dnp;
+       extern int prtactive;
 
        np = VTONFS(vp);
 
        np = VTONFS(vp);
-       if (vp->v_count != 0)
-               printf("nfs_inactive: pushing active fileid %d fsid 0x%x\n",
-                       np->n_vattr.va_fileid, np->n_vattr.va_fsid);
+       if (prtactive && vp->v_usecount != 0)
+               vprint("nfs_inactive: pushing active", vp);
        nfs_lock(vp);
        sp = np->n_sillyrename;
        np->n_sillyrename = (struct sillyrename *)0;
        nfs_lock(vp);
        sp = np->n_sillyrename;
        np->n_sillyrename = (struct sillyrename *)0;
@@ -166,17 +182,17 @@ nfs_inactive(vp)
                /*
                 * Remove the silly file that was rename'd earlier
                 */
                /*
                 * Remove the silly file that was rename'd earlier
                 */
-               ndp = &sp->s_namei;
                if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
                if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
-                       ndp->ni_dvp = NFSTOV(dnp);
-                       nfs_removeit(ndp);
-                       nfs_nput(ndp->ni_dvp);
+                       sp->s_dvp = NFSTOV(dnp);
+                       nfs_removeit(sp, p);
+                       nfs_nput(sp->s_dvp);
                }
                }
-               crfree(ndp->ni_cred);
-               free((caddr_t)sp, M_TEMP);
+               crfree(sp->s_cred);
+               vrele(sp->s_dvp);
+               free((caddr_t)sp, M_NFSREQ);
        }
        nfs_unlock(vp);
        }
        nfs_unlock(vp);
-       np->n_flag &= NBUFFERED;
+       np->n_flag &= NMODIFIED;
 #ifdef notdef
        /*
         * Scan the request list for any requests left hanging about
 #ifdef notdef
        /*
         * Scan the request list for any requests left hanging about
@@ -207,10 +223,10 @@ nfs_reclaim(vp)
        register struct vnode *vp;
 {
        register struct nfsnode *np = VTONFS(vp);
        register struct vnode *vp;
 {
        register struct nfsnode *np = VTONFS(vp);
+       extern int prtactive;
 
 
-       if (vp->v_count != 0)
-               printf("nfs_reclaim: pushing active fileid %d fsid 0x%x\n",
-                       np->n_vattr.va_fileid, np->n_vattr.va_fsid);
+       if (prtactive && vp->v_usecount != 0)
+               vprint("nfs_reclaim: pushing active", vp);
        /*
         * Remove the nfsnode from its hash chain.
         */
        /*
         * Remove the nfsnode from its hash chain.
         */
@@ -218,57 +234,36 @@ nfs_reclaim(vp)
        np->n_forw = np;
        np->n_back = np;
        cache_purge(vp);
        np->n_forw = np;
        np->n_back = np;
        cache_purge(vp);
-       /*
-        * Flush out any associated bio buffers that might be lying about
-        */
-       if (vp->v_type == VREG && (np->n_flag & NBUFFERED)) {
-               np->n_flag |= NLOCKED;
-               nfs_blkflush(vp, (daddr_t)0, np->n_size, TRUE);
-       }
+       np->n_flag = 0;
+       np->n_direofoffset = 0;
        return (0);
 }
 
 /*
        return (0);
 }
 
 /*
- * Remove any nfsnodes in the nfsnode cache belonging to mount.
- *
- * There should not be any active ones, return error if any are found
- * (nb: this is a user error, not a system err).
+ * In theory, NFS does not need locking, but we make provision
+ * for doing it just in case it is needed.
  */
  */
-nfs_nflush(mntp)
-       struct mount *mntp;
-{
-       register struct vnode *nvp, *vp;
-       int busy = 0;
-
-       for (vp = mntp->m_mounth; vp; vp = nvp) {
-               nvp = vp->v_mountf;
-               if (vp->v_count) {
-                       busy++;
-                       continue;
-               }
-               /*
-                * With v_count == 0, all we need to do is clear out the
-                * vnode data structures and we are done.
-                */
-               vgone(vp);
-       }
-       if (busy)
-               return (EBUSY);
-       return (0);
-}
-
+int donfslocking = 0;
 /*
  * Lock an nfsnode
  */
 /*
  * Lock an nfsnode
  */
+
 nfs_lock(vp)
        struct vnode *vp;
 {
        register struct nfsnode *np = VTONFS(vp);
 
 nfs_lock(vp)
        struct vnode *vp;
 {
        register struct nfsnode *np = VTONFS(vp);
 
+       if (!donfslocking)
+               return;
        while (np->n_flag & NLOCKED) {
                np->n_flag |= NWANT;
        while (np->n_flag & NLOCKED) {
                np->n_flag |= NWANT;
-               sleep((caddr_t)np, PINOD);
+               if (np->n_lockholder == curproc->p_pid)
+                       panic("locking against myself");
+               np->n_lockwaiter = curproc->p_pid;
+               (void) tsleep((caddr_t)np, PINOD, "nfslock", 0);
        }
        }
+       np->n_lockwaiter = 0;
+       np->n_lockholder = curproc->p_pid;
        np->n_flag |= NLOCKED;
 }
 
        np->n_flag |= NLOCKED;
 }
 
@@ -280,6 +275,7 @@ nfs_unlock(vp)
 {
        register struct nfsnode *np = VTONFS(vp);
 
 {
        register struct nfsnode *np = VTONFS(vp);
 
+       np->n_lockholder = 0;
        np->n_flag &= ~NLOCKED;
        if (np->n_flag & NWANT) {
                np->n_flag &= ~NWANT;
        np->n_flag &= ~NLOCKED;
        if (np->n_flag & NWANT) {
                np->n_flag &= ~NWANT;
@@ -287,6 +283,18 @@ nfs_unlock(vp)
        }
 }
 
        }
 }
 
+/*
+ * Check for a locked nfsnode
+ */
+nfs_islocked(vp)
+       struct vnode *vp;
+{
+
+       if (VTONFS(vp)->n_flag & NLOCKED)
+               return (1);
+       return (0);
+}
+
 /*
  * Unlock and vrele()
  * since I can't decide if dirs. should be locked, I will check for
 /*
  * Unlock and vrele()
  * since I can't decide if dirs. should be locked, I will check for
@@ -302,32 +310,16 @@ nfs_nput(vp)
        vrele(vp);
 }
 
        vrele(vp);
 }
 
-nfs_abortop(ndp)
-       register struct nameidata *ndp;
-{
-       register struct nfsnode *np;
-
-       if (ndp->ni_vp != NULL) {
-               np = VTONFS(ndp->ni_vp);
-               if (np->n_flag & NLOCKED)
-                       nfs_unlock(ndp->ni_vp);
-               vrele(ndp->ni_vp);
-       }
-       if (ndp->ni_dvp != NULL) {
-               np = VTONFS(ndp->ni_dvp);
-               if (np->n_flag & NLOCKED)
-                       nfs_unlock(ndp->ni_dvp);
-               vrele(ndp->ni_dvp);
-       }
-}
-
 /*
 /*
- * This is silly, but if you use a macro and try and use it in a file
- * that has mbuf.h included, m_data --> m_hdr.mh_data and this is not
- * a good thing
+ * Nfs abort op, called after namei() when a CREATE/DELETE isn't actually
+ * done. Currently nothing to do.
  */
  */
-struct nfsmount *vfs_to_nfs(mp)
-       struct mount *mp;
+/* ARGSUSED */
+nfs_abortop(ndp)
+       struct nameidata *ndp;
 {
 {
-       return ((struct nfsmount *)mp->m_data);
+
+       if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
+               FREE(ndp->ni_pnbuf, M_NAMEI);
+       return (0);
 }
 }