nfs_vfree prototype changed for vn_if
[unix-history] / usr / src / sys / nfs / nfs_node.c
index acb753c..200f7db 100644 (file)
@@ -5,36 +5,26 @@
  * 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.
+ * %sccs.include.redist.c%
  *
  *
- *     @(#)nfs_node.c  7.10 (Berkeley) %G%
+ *     @(#)nfs_node.c  7.38 (Berkeley) %G%
  */
 
 #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 "rpcv2.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"
+#include "nqnfs.h"
 
 /* The request list head */
 extern struct nfsreq nfsreqh;
 
 /* The request list head */
 extern struct nfsreq nfsreqh;
@@ -64,8 +54,8 @@ nfs_nhinit()
        register union  nhead *nh = nhead;
 
 #ifndef lint
        register union  nhead *nh = nhead;
 
 #ifndef lint
-       if (VN_MAXPRIVATE < sizeof(struct nfsnode))
-               panic("nfs_nhinit: too small");
+       if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode))
+               printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode));
 #endif /* not lint */
        for (i = NFSNOHSZ; --i >= 0; nh++) {
                nh->nh_head[0] = nh;
 #endif /* not lint */
        for (i = NFSNOHSZ; --i >= 0; nh++) {
                nh->nh_head[0] = nh;
@@ -104,7 +94,7 @@ nfs_nget(mntp, fhp, npp)
 {
        register struct nfsnode *np;
        register struct vnode *vp;
 {
        register struct nfsnode *np;
        register struct vnode *vp;
-       extern struct vnodeops nfsv2_vnodeops;
+       extern int (**nfsv2_vnodeop_p)();
        struct vnode *nvp;
        union nhead *nh;
        int error;
        struct vnode *nvp;
        union nhead *nh;
        int error;
@@ -115,219 +105,161 @@ loop:
                if (mntp != NFSTOV(np)->v_mount ||
                    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
                        continue;
                if (mntp != NFSTOV(np)->v_mount ||
                    bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH))
                        continue;
-               if ((np->n_flag & NLOCKED) != 0) {
-                       np->n_flag |= NWANT;
-                       sleep((caddr_t)np, PINOD);
-                       goto loop;
-               }
                vp = NFSTOV(np);
                if (vget(vp))
                        goto loop;
                *npp = np;
                return(0);
        }
                vp = NFSTOV(np);
                if (vget(vp))
                        goto loop;
                *npp = np;
                return(0);
        }
-       if (error = getnewvnode(VT_NFS, mntp, &nfsv2_vnodeops, &nvp)) {
+       if (error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &nvp)) {
                *npp = 0;
                return (error);
        }
        vp = nvp;
                *npp = 0;
                return (error);
        }
        vp = nvp;
-       np = VTONFS(vp);
+       MALLOC(np, struct nfsnode *, sizeof *np, M_NFSNODE, M_WAITOK);
+       vp->v_data = np;
        np->n_vnode = vp;
        /*
         * Insert the nfsnode in the hash queue for its new file handle
         */
        np->n_vnode = vp;
        /*
         * Insert the nfsnode in the hash queue for its new file handle
         */
-       np->n_flag = NLOCKED;
+       np->n_flag = 0;
        insque(np, nh);
        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
        np->n_attrstamp = 0;
        insque(np, nh);
        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_sillyrename = (struct sillyrename *)0;
        np->n_size = 0;
-       np->n_mtime = 0;
+       if (VFSTONFS(mntp)->nm_flag & NFSMNT_NQNFS) {
+               ZEROQUAD(np->n_brev);
+               ZEROQUAD(np->n_lrev);
+               np->n_expiry = (time_t)0;
+               np->n_tnext = (struct nfsnode *)0;
+       } else
+               np->n_mtime = 0;
        *npp = np;
        return (0);
 }
 
        *npp = np;
        return (0);
 }
 
-nfs_inactive(vp)
-       struct vnode *vp;
+nfs_inactive (ap)
+       struct vop_inactive_args *ap;
+#define vp (ap->a_vp)
+#define p (ap->a_p)
 {
        register struct nfsnode *np;
 {
        register struct nfsnode *np;
-       register struct nameidata *ndp;
        register struct sillyrename *sp;
        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);
-       nfs_lock(vp);
+       if (prtactive && vp->v_usecount != 0)
+               vprint("nfs_inactive: pushing active", vp);
        sp = np->n_sillyrename;
        np->n_sillyrename = (struct sillyrename *)0;
        if (sp) {
                /*
                 * Remove the silly file that was rename'd earlier
                 */
        sp = np->n_sillyrename;
        np->n_sillyrename = (struct sillyrename *)0;
        if (sp) {
                /*
                 * Remove the silly file that was rename'd earlier
                 */
-               ndp = &sp->s_namei;
-               if (!nfs_nget(vp->v_mount, &sp->s_fh, &dnp)) {
-                       ndp->ni_dvp = NFSTOV(dnp);
-                       nfs_removeit(ndp);
-                       nfs_nput(ndp->ni_dvp);
-               }
-               crfree(ndp->ni_cred);
-               free((caddr_t)sp, M_TEMP);
-       }
-       nfs_unlock(vp);
-       np->n_flag &= NBUFFERED;
-#ifdef notdef
-       /*
-        * Scan the request list for any requests left hanging about
-        */
-       s = splnet();
-       rep = nfsreqh.r_next;
-       while (rep && rep != &nfsreqh) {
-               if (rep->r_vp == vp) {
-                       rep->r_prev->r_next = rep2 = rep->r_next;
-                       rep->r_next->r_prev = rep->r_prev;
-                       m_freem(rep->r_mreq);
-                       if (rep->r_mrep != NULL)
-                               m_freem(rep->r_mrep);
-                       free((caddr_t)rep, M_NFSREQ);
-                       rep = rep2;
-               } else
-                       rep = rep->r_next;
-       }
-       splx(s);
+               nfs_removeit(sp, p);
+               crfree(sp->s_cred);
+               vrele(sp->s_dvp);
+#ifdef SILLYSEPARATE
+               free((caddr_t)sp, M_NFSREQ);
 #endif
 #endif
+       }
+       np->n_flag &= NMODIFIED;
        return (0);
 }
        return (0);
 }
+#undef vp
+#undef p
 
 /*
  * Reclaim an nfsnode so that it can be used for other purposes.
  */
 
 /*
  * Reclaim an nfsnode so that it can be used for other purposes.
  */
-nfs_reclaim(vp)
-       register struct vnode *vp;
+nfs_reclaim (ap)
+       struct vop_reclaim_args *ap;
+#define vp (ap->a_vp)
 {
        register struct nfsnode *np = VTONFS(vp);
 {
        register struct nfsnode *np = VTONFS(vp);
+       register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
+       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.
         */
        remque(np);
        /*
         * Remove the nfsnode from its hash chain.
         */
        remque(np);
-       np->n_forw = np;
-       np->n_back = np;
-       cache_purge(vp);
+
        /*
        /*
-        * Flush out any associated bio buffers that might be lying about
+        * For nqnfs, take it off the timer queue as required.
         */
         */
-       if (vp->v_type == VREG && (np->n_flag & NBUFFERED)) {
-               np->n_flag |= NLOCKED;
-               nfs_blkflush(vp, (daddr_t)0, np->n_size, TRUE);
-       }
-       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).
- */
-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 ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) {
+               if (np->n_tnext == (struct nfsnode *)nmp)
+                       nmp->nm_tprev = np->n_tprev;
+               else
+                       np->n_tnext->n_tprev = np->n_tprev;
+               if (np->n_tprev == (struct nfsnode *)nmp)
+                       nmp->nm_tnext = np->n_tnext;
+               else
+                       np->n_tprev->n_tnext = np->n_tnext;
        }
        }
-       if (busy)
-               return (EBUSY);
+       cache_purge(vp);
+       FREE(vp->v_data, M_NFSNODE);
+       vp->v_data = (void *)0;
        return (0);
 }
        return (0);
 }
+#undef vp
 
 /*
  * Lock an nfsnode
  */
 
 /*
  * Lock an nfsnode
  */
-nfs_lock(vp)
-       struct vnode *vp;
+nfs_lock (ap)
+       struct vop_lock_args *ap;
+#define vp (ap->a_vp)
 {
 {
-       register struct nfsnode *np = VTONFS(vp);
 
 
-       while (np->n_flag & NLOCKED) {
-               np->n_flag |= NWANT;
-               sleep((caddr_t)np, PINOD);
-       }
-       np->n_flag |= NLOCKED;
+       return (0);
 }
 }
+#undef vp
 
 /*
  * Unlock an nfsnode
  */
 
 /*
  * Unlock an nfsnode
  */
-nfs_unlock(vp)
-       struct vnode *vp;
+nfs_unlock (ap)
+       struct vop_unlock_args *ap;
+#define vp (ap->a_vp)
 {
 {
-       register struct nfsnode *np = VTONFS(vp);
 
 
-       np->n_flag &= ~NLOCKED;
-       if (np->n_flag & NWANT) {
-               np->n_flag &= ~NWANT;
-               wakeup((caddr_t)np);
-       }
+       return (0);
 }
 }
+#undef vp
 
 /*
 
 /*
- * Unlock and vrele()
- * since I can't decide if dirs. should be locked, I will check for
- * the lock and be flexible
+ * Check for a locked nfsnode
  */
  */
-nfs_nput(vp)
-       struct vnode *vp;
-{
-       register struct nfsnode *np = VTONFS(vp);
-
-       if (np->n_flag & NLOCKED)
-               nfs_unlock(vp);
-       vrele(vp);
-}
-
-nfs_abortop(ndp)
-       register struct nameidata *ndp;
+nfs_islocked (ap)
+       struct vop_islocked_args *ap;
+#define vp (ap->a_vp)
 {
 {
-       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);
-       }
+       return (0);
 }
 }
+#undef vp
 
 /*
 
 /*
- * 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 */
+int
+nfs_abortop (ap)
+       struct vop_abortop_args *ap;
+#define dvp (ap->a_dvp)
+#define cnp (ap->a_cnp)
 {
 {
-       return ((struct nfsmount *)mp->m_data);
+
+       if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
+               FREE(cnp->cn_pnbuf, M_NAMEI);
+       return (0);
 }
 }
+#undef dvp
+#undef cnp