update to current hashing techniques
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 23 Jul 1992 06:25:12 +0000 (22:25 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Thu, 23 Jul 1992 06:25:12 +0000 (22:25 -0800)
SCCS-vsn: sys/nfs/nfsrvcache.h 7.5
SCCS-vsn: sys/nfs/nfsnode.h 7.27
SCCS-vsn: sys/nfs/nfs_subs.c 7.61
SCCS-vsn: sys/nfs/nfs_srvcache.c 7.16
SCCS-vsn: sys/nfs/nfs_node.c 7.42
SCCS-vsn: sys/nfs/nfs_nqlease.c 7.10
SCCS-vsn: sys/nfs/nqnfs.h 7.4

usr/src/sys/nfs/nfs_node.c
usr/src/sys/nfs/nfs_nqlease.c
usr/src/sys/nfs/nfs_srvcache.c
usr/src/sys/nfs/nfs_subs.c
usr/src/sys/nfs/nfsnode.h
usr/src/sys/nfs/nfsrvcache.h
usr/src/sys/nfs/nqnfs.h

index ce1da56..6c412b1 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_node.c  7.41 (Berkeley) %G%
+ *     @(#)nfs_node.c  7.42 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
 #include "nfsmount.h"
 #include "nqnfs.h"
 
 #include "nfsmount.h"
 #include "nqnfs.h"
 
-/* The request list head */
-extern struct nfsreq nfsreqh;
-
-#define        NFSNOHSZ        512
-#if    ((NFSNOHSZ&(NFSNOHSZ-1)) == 0)
-#define        NFSNOHASH(fhsum)        ((fhsum)&(NFSNOHSZ-1))
-#else
-#define        NFSNOHASH(fhsum)        (((unsigned)(fhsum))%NFSNOHSZ)
-#endif
-
-union nhead {
-       union  nhead *nh_head[2];
-       struct nfsnode *nh_chain[2];
-} nhead[NFSNOHSZ];
+struct nfsnode **nheadhashtbl;
+u_long nheadhash;
+#define        NFSNOHASH(fhsum)        ((fhsum)&nheadhash)
 
 #define TRUE   1
 #define        FALSE   0
 
 #define TRUE   1
 #define        FALSE   0
@@ -50,23 +39,18 @@ union nhead {
  */
 nfs_nhinit()
 {
  */
 nfs_nhinit()
 {
-       register int i;
-       register union  nhead *nh = nhead;
 
 #ifndef lint
        if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode))
                printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode));
 #endif /* not lint */
 
 #ifndef lint
        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;
-               nh->nh_head[1] = nh;
-       }
+       nheadhashtbl = hashinit(desiredvnodes, M_NFSNODE, &nheadhash);
 }
 
 /*
  * Compute an entry in the NFS hash table structure
  */
 }
 
 /*
  * Compute an entry in the NFS hash table structure
  */
-union nhead *
+struct nfsnode **
 nfs_hash(fhp)
        register nfsv2fh_t *fhp;
 {
 nfs_hash(fhp)
        register nfsv2fh_t *fhp;
 {
@@ -78,7 +62,7 @@ nfs_hash(fhp)
        fhsum = 0;
        for (i = 0; i < NFSX_FH; i++)
                fhsum += *fhpp++;
        fhsum = 0;
        for (i = 0; i < NFSX_FH; i++)
                fhsum += *fhpp++;
-       return (&nhead[NFSNOHASH(fhsum)]);
+       return (&nheadhashtbl[NFSNOHASH(fhsum)]);
 }
 
 /*
 }
 
 /*
@@ -92,16 +76,15 @@ nfs_nget(mntp, fhp, npp)
        register nfsv2fh_t *fhp;
        struct nfsnode **npp;
 {
        register nfsv2fh_t *fhp;
        struct nfsnode **npp;
 {
-       register struct nfsnode *np;
+       register struct nfsnode *np, *nq, **nhpp;
        register struct vnode *vp;
        extern int (**nfsv2_vnodeop_p)();
        struct vnode *nvp;
        register struct vnode *vp;
        extern int (**nfsv2_vnodeop_p)();
        struct vnode *nvp;
-       union nhead *nh;
        int error;
 
        int error;
 
-       nh = nfs_hash(fhp);
+       nhpp = nfs_hash(fhp);
 loop:
 loop:
-       for (np = nh->nh_chain[0]; np != (struct nfsnode *)nh; np = np->n_forw) {
+       for (np = *nhpp; np; np = np->n_forw) {
                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;
@@ -123,7 +106,11 @@ loop:
         * Insert the nfsnode in the hash queue for its new file handle
         */
        np->n_flag = 0;
         * Insert the nfsnode in the hash queue for its new file handle
         */
        np->n_flag = 0;
-       insque(np, nh);
+       if (nq = *nhpp)
+               nq->n_back = &np->n_forw;
+       np->n_forw = nq;
+       np->n_back = nhpp;
+       *nhpp = np;
        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
        np->n_attrstamp = 0;
        np->n_direofoffset = 0;
        bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH);
        np->n_attrstamp = 0;
        np->n_direofoffset = 0;
@@ -180,6 +167,7 @@ nfs_reclaim(ap)
        register struct vnode *vp = ap->a_vp;
        register struct nfsnode *np = VTONFS(vp);
        register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
        register struct vnode *vp = ap->a_vp;
        register struct nfsnode *np = VTONFS(vp);
        register struct nfsmount *nmp = VFSTONFS(vp->v_mount);
+       register struct nfsnode *nq;
        extern int prtactive;
 
        if (prtactive && vp->v_usecount != 0)
        extern int prtactive;
 
        if (prtactive && vp->v_usecount != 0)
@@ -187,7 +175,9 @@ nfs_reclaim(ap)
        /*
         * Remove the nfsnode from its hash chain.
         */
        /*
         * Remove the nfsnode from its hash chain.
         */
-       remque(np);
+       if (nq = np->n_forw)
+               nq->n_back = np->n_back;
+       *np->n_back = nq;
 
        /*
         * For nqnfs, take it off the timer queue as required.
 
        /*
         * For nqnfs, take it off the timer queue as required.
index 44427d7..089e424 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_nqlease.c       7.9 (Berkeley) %G%
+ *     @(#)nfs_nqlease.c       7.10 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  * List head for the lease queue and other global data.
  * At any time a lease is linked into a list ordered by increasing expiry time.
  */
  * List head for the lease queue and other global data.
  * At any time a lease is linked into a list ordered by increasing expiry time.
  */
-#if    ((NQLCHSZ&(NQLCHSZ-1)) == 0)
-#define        NQFHHASH(f)     ((*((u_long *)(f)))&(NQLCHSZ-1))
-#else
-#define        NQFHHASH(f)     ((*((u_long *)(f)))%NQLCHSZ)
-#endif
+#define        NQFHHASH(f)     ((*((u_long *)(f)))&nqfheadhash)
 
 union nqsrvthead nqthead;
 
 union nqsrvthead nqthead;
-union nqsrvthead nqfhead[NQLCHSZ];
+struct nqlease **nqfhead;
+u_long nqfheadhash;
 time_t nqnfsstarttime = (time_t)0;
 u_long nqnfs_prog, nqnfs_vers;
 int nqsrv_clockskew = NQ_CLOCKSKEW;
 time_t nqnfsstarttime = (time_t)0;
 u_long nqnfs_prog, nqnfs_vers;
 int nqsrv_clockskew = NQ_CLOCKSKEW;
@@ -140,12 +137,11 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
        u_quad_t *frev;
        struct ucred *cred;
 {
        u_quad_t *frev;
        struct ucred *cred;
 {
-       register struct nqlease *lp;
+       register struct nqlease *lp, *lq, **lpp;
        register struct nqhost *lph;
        register struct nqhost *lph;
-       struct nqlease *tlp = (struct nqlease *)0;
+       struct nqlease *tlp;
        struct nqm **lphp;
        struct vattr vattr;
        struct nqm **lphp;
        struct vattr vattr;
-       union nqsrvthead *lhp;
        fhandle_t fh;
        int i, ok, error, s;
 
        fhandle_t fh;
        int i, ok, error, s;
 
@@ -170,9 +166,8 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred)
                        splx(s);
                        return (error);
                }
                        splx(s);
                        return (error);
                }
-               lhp = &nqfhead[NQFHHASH(fh.fh_fid.fid_data)];
-               for (lp = lhp->th_chain[0]; lp != (struct nqlease *)lhp;
-                       lp = lp->lc_fhnext)
+               lpp = &nqfhead[NQFHHASH(fh.fh_fid.fid_data)];
+               for (lp = *lpp; lp; lp = lp->lc_fhnext)
                        if (fh.fh_fsid.val[0] == lp->lc_fsid.val[0] &&
                            fh.fh_fsid.val[1] == lp->lc_fsid.val[1] &&
                            !bcmp(fh.fh_fid.fid_data, lp->lc_fiddata,
                        if (fh.fh_fsid.val[0] == lp->lc_fsid.val[0] &&
                            fh.fh_fsid.val[1] == lp->lc_fsid.val[1] &&
                            !bcmp(fh.fh_fid.fid_data, lp->lc_fiddata,
@@ -276,13 +271,11 @@ doreply:
        lp->lc_vp = vp;
        lp->lc_fsid = fh.fh_fsid;
        bcopy(fh.fh_fid.fid_data, lp->lc_fiddata, fh.fh_fid.fid_len - sizeof (long));
        lp->lc_vp = vp;
        lp->lc_fsid = fh.fh_fsid;
        bcopy(fh.fh_fid.fid_data, lp->lc_fiddata, fh.fh_fid.fid_len - sizeof (long));
-       lp->lc_fhnext = lhp->th_chain[0];
-       if (lhp->th_head[0] == lhp)
-               lhp->th_chain[1] = lp;
-       else
-               lhp->th_chain[0]->lc_fhprev = lp;
-       lp->lc_fhprev = (struct nqlease *)lhp;
-       lhp->th_chain[0] = lp;
+       if (lq = *lpp)
+               lq->lc_fhprev = &lp->lc_fhnext;
+       lp->lc_fhnext = lq;
+       lp->lc_fhprev = lpp;
+       *lpp = lp;
        vp->v_lease = lp;
        s = splsoftclock();
        nqsrv_instimeq(lp, *duration);
        vp->v_lease = lp;
        s = splsoftclock();
        nqsrv_instimeq(lp, *duration);
@@ -576,7 +569,7 @@ tryagain:
 void
 nqnfs_serverd()
 {
 void
 nqnfs_serverd()
 {
-       register struct nqlease *lp;
+       register struct nqlease *lp, *lq;
        register struct nqhost *lph;
        struct nqlease *nextlp;
        struct nqm *lphnext, *olphnext;
        register struct nqhost *lph;
        struct nqlease *nextlp;
        struct nqm *lphnext, *olphnext;
@@ -610,15 +603,9 @@ nqnfs_serverd()
                        nqsrv_instimeq(lp, nqsrv_writeslack);
                    } else {
                        remque(lp);
                        nqsrv_instimeq(lp, nqsrv_writeslack);
                    } else {
                        remque(lp);
-                       lhp = &nqfhead[NQFHHASH(lp->lc_fiddata)];
-                       if (lp->lc_fhprev == (struct nqlease *)lhp)
-                               lhp->th_chain[0] = lp->lc_fhnext;
-                       else
-                               lp->lc_fhprev->lc_fhnext = lp->lc_fhnext;
-                       if (lp->lc_fhnext == (struct nqlease *)lhp)
-                               lhp->th_chain[1] = lp->lc_fhprev;
-                       else
-                               lp->lc_fhnext->lc_fhprev = lp->lc_fhprev;
+                       if (lq = lp->lc_fhnext)
+                               lq->lc_fhprev = lp->lc_fhprev;
+                       *lp->lc_fhprev = lq;
                        /*
                         * This soft reference may no longer be valid, but
                         * no harm done. The worst case is if the vnode was
                        /*
                         * This soft reference may no longer be valid, but
                         * no harm done. The worst case is if the vnode was
@@ -750,9 +737,8 @@ nqnfsrv_vacated(nfsd, mrep, md, dpos, cred, nam, mrq)
                /*
                 * Find the lease by searching the hash list.
                 */
                /*
                 * Find the lease by searching the hash list.
                 */
-               lhp = &nqfhead[NQFHHASH(fhp->fh_fid.fid_data)];
-               for (lp = lhp->th_chain[0]; lp != (struct nqlease *)lhp;
-                       lp = lp->lc_fhnext)
+               for (lp = nqfhead[NQFHHASH(fhp->fh_fid.fid_data)]; lp;
+                    lp = lp->lc_fhnext)
                        if (fhp->fh_fsid.val[0] == lp->lc_fsid.val[0] &&
                            fhp->fh_fsid.val[1] == lp->lc_fsid.val[1] &&
                            !bcmp(fhp->fh_fid.fid_data, lp->lc_fiddata,
                        if (fhp->fh_fsid.val[0] == lp->lc_fsid.val[0] &&
                            fhp->fh_fsid.val[1] == lp->lc_fsid.val[1] &&
                            !bcmp(fhp->fh_fid.fid_data, lp->lc_fiddata,
index 3020c38..ce7c519 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_srvcache.c      7.15 (Berkeley) %G%
+ *     @(#)nfs_srvcache.c      7.16 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -22,6 +22,7 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/mbuf.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/mbuf.h>
+#include <sys/malloc.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <netinet/in.h>
 #include <nfs/nfsrvcache.h>
 #include <nfs/nqnfs.h>
 
 #include <nfs/nfsrvcache.h>
 #include <nfs/nqnfs.h>
 
-#if    ((NFSRCHSZ&(NFSRCHSZ-1)) == 0)
-#define        NFSRCHASH(xid)          (((xid)+((xid)>>16))&(NFSRCHSZ-1))
-#else
-#define        NFSRCHASH(xid)          (((unsigned)((xid)+((xid)>>16)))%NFSRCHSZ)
-#endif
-
-union rhead {
-       union  rhead *rh_head[2];
-       struct nfsrvcache *rh_chain[2];
-} rhead[NFSRCHSZ];
+long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ;
 
 
-static struct nfsrvcache nfsrvcachehead;
-static struct nfsrvcache nfsrvcache[NFSRVCACHESIZ];
+#define        NFSRCHASH(xid)          (((xid) + ((xid) >> 16)) & rheadhash)
+static struct nfsrvcache *nfsrvlruhead, **nfsrvlrutail = &nfsrvlruhead;
+static struct nfsrvcache **rheadhtbl;
+static u_long rheadhash;
 
 #define TRUE   1
 #define        FALSE   0
 
 #define TRUE   1
 #define        FALSE   0
@@ -114,27 +108,8 @@ static int repliesstatus[NFS_NPROCS] = {
  */
 nfsrv_initcache()
 {
  */
 nfsrv_initcache()
 {
-       register int i;
-       register struct nfsrvcache *rp = nfsrvcache;
-       register struct nfsrvcache *hp = &nfsrvcachehead;
-       register union  rhead *rh = rhead;
 
 
-       for (i = NFSRCHSZ; --i >= 0; rh++) {
-               rh->rh_head[0] = rh;
-               rh->rh_head[1] = rh;
-       }
-       hp->rc_next = hp->rc_prev = hp;
-       for (i = NFSRVCACHESIZ; i-- > 0; ) {
-               rp->rc_state = RC_UNUSED;
-               rp->rc_flag = 0;
-               rp->rc_forw = rp;
-               rp->rc_back = rp;
-               rp->rc_next = hp->rc_next;
-               hp->rc_next->rc_prev = rp;
-               rp->rc_prev = hp;
-               hp->rc_next = rp;
-               rp++;
-       }
+       rheadhtbl = hashinit(desirednfsrvcache, M_NFSD, &rheadhash);
 }
 
 /*
 }
 
 /*
@@ -156,8 +131,7 @@ nfsrv_getcache(nam, nd, repp)
        register struct nfsd *nd;
        struct mbuf **repp;
 {
        register struct nfsd *nd;
        struct mbuf **repp;
 {
-       register struct nfsrvcache *rp;
-       register union  rhead *rh;
+       register struct nfsrvcache *rp, *rq, **rpp;
        struct mbuf *mb;
        struct sockaddr_in *saddr;
        caddr_t bpos;
        struct mbuf *mb;
        struct sockaddr_in *saddr;
        caddr_t bpos;
@@ -165,9 +139,9 @@ nfsrv_getcache(nam, nd, repp)
 
        if (nd->nd_nqlflag != NQL_NOVAL)
                return (RC_DOIT);
 
        if (nd->nd_nqlflag != NQL_NOVAL)
                return (RC_DOIT);
-       rh = &rhead[NFSRCHASH(nd->nd_retxid)];
+       rpp = &rheadhtbl[NFSRCHASH(nd->nd_retxid)];
 loop:
 loop:
-       for (rp = rh->rh_chain[0]; rp != (struct nfsrvcache *)rh; rp = rp->rc_forw) {
+       for (rp = *rpp; rp; rp = rp->rc_forw) {
            if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
                netaddr_match(NETFAMILY(rp), &rp->rc_haddr, (union nethostaddr *)0, nam)) {
                        if ((rp->rc_flag & RC_LOCKED) != 0) {
            if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
                netaddr_match(NETFAMILY(rp), &rp->rc_haddr, (union nethostaddr *)0, nam)) {
                        if ((rp->rc_flag & RC_LOCKED) != 0) {
@@ -176,13 +150,16 @@ loop:
                                goto loop;
                        }
                        rp->rc_flag |= RC_LOCKED;
                                goto loop;
                        }
                        rp->rc_flag |= RC_LOCKED;
-                       if (rp->rc_prev != &nfsrvcachehead) {
+                       /* If not at end of LRU chain, move it there */
+                       if (rp->rc_next) {
+                               /* remove from LRU chain */
+                               *rp->rc_prev = rp->rc_next;
                                rp->rc_next->rc_prev = rp->rc_prev;
                                rp->rc_next->rc_prev = rp->rc_prev;
-                               rp->rc_prev->rc_next = rp->rc_next;
-                               rp->rc_next = nfsrvcachehead.rc_next;
-                               nfsrvcachehead.rc_next = rp;
-                               rp->rc_prev = &nfsrvcachehead;
-                               rp->rc_next->rc_prev = rp;
+                               /* and replace at end of it */
+                               rp->rc_next = NULL;
+                               rp->rc_prev = nfsrvlrutail;
+                               *nfsrvlrutail = rp;
+                               nfsrvlrutail = &rp->rc_next;
                        }
                        if (rp->rc_state == RC_UNUSED)
                                panic("nfsrv cache");
                        }
                        if (rp->rc_state == RC_UNUSED)
                                panic("nfsrv cache");
@@ -216,27 +193,38 @@ loop:
                }
        }
        nfsstats.srvcache_misses++;
                }
        }
        nfsstats.srvcache_misses++;
-       rp = nfsrvcachehead.rc_prev;
-       while ((rp->rc_flag & RC_LOCKED) != 0) {
-               rp->rc_flag |= RC_WANTED;
-               (void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
-               rp = nfsrvcachehead.rc_prev;
-       }
-       rp->rc_flag |= RC_LOCKED;
-       remque(rp);
-       if (rp->rc_prev != &nfsrvcachehead) {
+       if (numnfsrvcache < desirednfsrvcache) {
+               rp = (struct nfsrvcache *)malloc((u_long)sizeof *rp,
+                   M_NFSD, M_WAITOK);
+               bzero((char *)rp, sizeof *rp);
+               numnfsrvcache++;
+               rp->rc_flag = RC_LOCKED;
+       } else {
+               rp = nfsrvlruhead;
+               while ((rp->rc_flag & RC_LOCKED) != 0) {
+                       rp->rc_flag |= RC_WANTED;
+                       (void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0);
+                       rp = nfsrvlruhead;
+               }
+               rp->rc_flag |= RC_LOCKED;
+               /* remove from hash chain */
+               if (rq = rp->rc_forw)
+                       rq->rc_back = rp->rc_back;
+               *rp->rc_back = rq;
+               /* remove from LRU chain */
+               *rp->rc_prev = rp->rc_next;
                rp->rc_next->rc_prev = rp->rc_prev;
                rp->rc_next->rc_prev = rp->rc_prev;
-               rp->rc_prev->rc_next = rp->rc_next;
-               rp->rc_next = nfsrvcachehead.rc_next;
-               nfsrvcachehead.rc_next = rp;
-               rp->rc_prev = &nfsrvcachehead;
-               rp->rc_next->rc_prev = rp;
+               if (rp->rc_flag & RC_REPMBUF)
+                       m_freem(rp->rc_reply);
+               if (rp->rc_flag & RC_NAM)
+                       MFREE(rp->rc_nam, mb);
+               rp->rc_flag &= (RC_LOCKED | RC_WANTED);
        }
        }
-       if (rp->rc_flag & RC_REPMBUF)
-               m_freem(rp->rc_reply);
-       if (rp->rc_flag & RC_NAM)
-               MFREE(rp->rc_nam, mb);
-       rp->rc_flag &= (RC_LOCKED | RC_WANTED);
+       /* place at end of LRU list */
+       rp->rc_next = NULL;
+       rp->rc_prev = nfsrvlrutail;
+       *nfsrvlrutail = rp;
+       nfsrvlrutail = &rp->rc_next;
        rp->rc_state = RC_INPROG;
        rp->rc_xid = nd->nd_retxid;
        saddr = mtod(nam, struct sockaddr_in *);
        rp->rc_state = RC_INPROG;
        rp->rc_xid = nd->nd_retxid;
        saddr = mtod(nam, struct sockaddr_in *);
@@ -252,7 +240,12 @@ loop:
                break;
        };
        rp->rc_proc = nd->nd_procnum;
                break;
        };
        rp->rc_proc = nd->nd_procnum;
-       insque(rp, rh);
+       /* insert into hash chain */
+       if (rq = *rpp)
+               rq->rc_back = &rp->rc_forw;
+       rp->rc_next = rq;
+       rp->rc_back = rpp;
+       *rpp = rp;
        rp->rc_flag &= ~RC_LOCKED;
        if (rp->rc_flag & RC_WANTED) {
                rp->rc_flag &= ~RC_WANTED;
        rp->rc_flag &= ~RC_LOCKED;
        if (rp->rc_flag & RC_WANTED) {
                rp->rc_flag &= ~RC_WANTED;
@@ -272,13 +265,11 @@ nfsrv_updatecache(nam, nd, repvalid, repmbuf)
        struct mbuf *repmbuf;
 {
        register struct nfsrvcache *rp;
        struct mbuf *repmbuf;
 {
        register struct nfsrvcache *rp;
-       register union  rhead *rh;
 
        if (nd->nd_nqlflag != NQL_NOVAL)
                return;
 
        if (nd->nd_nqlflag != NQL_NOVAL)
                return;
-       rh = &rhead[NFSRCHASH(nd->nd_retxid)];
 loop:
 loop:
-       for (rp = rh->rh_chain[0]; rp != (struct nfsrvcache *)rh; rp = rp->rc_forw) {
+       for (rp = rheadhtbl[NFSRCHASH(nd->nd_retxid)]; rp; rp = rp->rc_forw) {
            if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
                netaddr_match(NETFAMILY(rp), &rp->rc_haddr, (union nethostaddr *)0, nam)) {
                        if ((rp->rc_flag & RC_LOCKED) != 0) {
            if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc &&
                netaddr_match(NETFAMILY(rp), &rp->rc_haddr, (union nethostaddr *)0, nam)) {
                        if ((rp->rc_flag & RC_LOCKED) != 0) {
@@ -325,29 +316,12 @@ loop:
 void
 nfsrv_cleancache()
 {
 void
 nfsrv_cleancache()
 {
-       register int i;
-       register struct nfsrvcache *rp = nfsrvcache;
-       register struct nfsrvcache *hp = &nfsrvcachehead;
-       register union  rhead *rh = rhead;
+       register struct nfsrvcache *rp, *nextrp;
 
 
-       for (i = NFSRCHSZ; --i >= 0; rh++) {
-               rh->rh_head[0] = rh;
-               rh->rh_head[1] = rh;
-       }
-       hp->rc_next = hp->rc_prev = hp;
-       for (i = NFSRVCACHESIZ; i-- > 0; ) {
-               if (rp->rc_flag & RC_REPMBUF)
-                       m_freem(rp->rc_reply);
-               if (rp->rc_flag & RC_NAM)
-                       m_freem(rp->rc_nam);
-               rp->rc_state = RC_UNUSED;
-               rp->rc_flag = 0;
-               rp->rc_forw = rp;
-               rp->rc_back = rp;
-               rp->rc_next = hp->rc_next;
-               hp->rc_next->rc_prev = rp;
-               rp->rc_prev = hp;
-               hp->rc_next = rp;
-               rp++;
+       for (rp = nfsrvlruhead; rp; rp = nextrp) {
+               nextrp = rp->rc_next;
+               free(rp, M_NFSD);
        }
        }
+       bzero((char *)rheadhtbl, (rheadhash + 1) * sizeof(void *));
+       numnfsrvcache = 0;
 }
 }
index e75236d..29b2f7a 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfs_subs.c  7.60 (Berkeley) %G%
+ *     @(#)nfs_subs.c  7.61 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -62,8 +62,6 @@ extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
 extern struct nfsreq nfsreqh;
 extern int nqnfs_piggy[NFS_NPROCS];
 extern struct nfsrtt nfsrtt;
 extern struct nfsreq nfsreqh;
 extern int nqnfs_piggy[NFS_NPROCS];
 extern struct nfsrtt nfsrtt;
-extern union nqsrvthead nqthead;
-extern union nqsrvthead nqfhead[NQLCHSZ];
 extern time_t nqnfsstarttime;
 extern u_long nqnfs_prog, nqnfs_vers;
 extern int nqsrv_clockskew;
 extern time_t nqnfsstarttime;
 extern u_long nqnfs_prog, nqnfs_vers;
 extern int nqsrv_clockskew;
@@ -601,11 +599,7 @@ nfs_init()
                nqnfs_vers = txdr_unsigned(NQNFS_VER1);
                nqthead.th_head[0] = &nqthead;
                nqthead.th_head[1] = &nqthead;
                nqnfs_vers = txdr_unsigned(NQNFS_VER1);
                nqthead.th_head[0] = &nqthead;
                nqthead.th_head[1] = &nqthead;
-               for (i = 0; i < NQLCHSZ; i++) {
-                       lhp = &nqfhead[i];
-                       lhp->th_head[0] = lhp;
-                       lhp->th_head[1] = lhp;
-               }
+               nqfhead = hashinit(NQLCHSZ, M_NQLEASE, &nqfheadhash);
        }
 
        /*
        }
 
        /*
@@ -640,7 +634,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
        register struct nfsv2_fattr *fp;
        extern int (**spec_nfsv2nodeop_p)();
        extern int (**spec_vnodeop_p)();
        register struct nfsv2_fattr *fp;
        extern int (**spec_nfsv2nodeop_p)();
        extern int (**spec_vnodeop_p)();
-       register struct nfsnode *np;
+       register struct nfsnode *np, *nq, **nhpp;
        register long t1;
        caddr_t dpos, cp2;
        int error = 0;
        register long t1;
        caddr_t dpos, cp2;
        int error = 0;
@@ -690,7 +684,9 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
                                /*
                                 * Discard unneeded vnode, but save its nfsnode.
                                 */
                                /*
                                 * Discard unneeded vnode, but save its nfsnode.
                                 */
-                               remque(np);
+                               if (nq = np->n_forw)
+                                       nq->n_back = np->n_back;
+                               *np->n_back = nq;
                                nvp->v_data = vp->v_data;
                                vp->v_data = NULL;
                                vp->v_op = spec_vnodeop_p;
                                nvp->v_data = vp->v_data;
                                vp->v_data = NULL;
                                vp->v_op = spec_vnodeop_p;
@@ -700,7 +696,12 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
                                 * Reinitialize aliased node.
                                 */
                                np->n_vnode = nvp;
                                 * Reinitialize aliased node.
                                 */
                                np->n_vnode = nvp;
-                               insque(np, nfs_hash(&np->n_fh));
+                               nhpp = (struct nfsnode **)nfs_hash(&np->n_fh);
+                               if (nq = *nhpp)
+                                       nq->n_back = &np->n_forw;
+                               np->n_forw = nq;
+                               np->n_back = nhpp;
+                               *nhpp = np;
                                *vpp = vp = nvp;
                        }
                }
                                *vpp = vp = nvp;
                        }
                }
index 6dc0788..3d986a8 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfsnode.h   7.26 (Berkeley) %G%
+ *     @(#)nfsnode.h   7.27 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -30,7 +30,8 @@ struct sillyrename {
  */
 
 struct nfsnode {
  */
 
 struct nfsnode {
-       struct  nfsnode *n_chain[2];    /* must be first */
+       struct  nfsnode *n_forw;        /* hash, forward */
+       struct  nfsnode **n_back;       /* hash, backward */
        nfsv2fh_t n_fh;                 /* NFS File Handle */
        long    n_flag;                 /* Flag for locking.. */
        struct  vnode *n_vnode;         /* vnode associated with this node */
        nfsv2fh_t n_fh;                 /* NFS File Handle */
        long    n_flag;                 /* Flag for locking.. */
        struct  vnode *n_vnode;         /* vnode associated with this node */
@@ -68,9 +69,6 @@ struct nfsnode {
 #define        n_tnext         n_un.un_nqnfs.un_tnext
 #define        n_tprev         n_un.un_nqnfs.un_tprev
 
 #define        n_tnext         n_un.un_nqnfs.un_tnext
 #define        n_tprev         n_un.un_nqnfs.un_tprev
 
-#define        n_forw          n_chain[0]
-#define        n_back          n_chain[1]
-
 #ifdef KERNEL
 /*
  * Convert between nfsnode pointers and vnode pointers
 #ifdef KERNEL
 /*
  * Convert between nfsnode pointers and vnode pointers
index 9a42bbc..598c75f 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nfsrvcache.h        7.4 (Berkeley) %G%
+ *     @(#)nfsrvcache.h        7.5 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
  */
 
 #define        NFSRVCACHESIZ   256
  */
 
 #define        NFSRVCACHESIZ   256
-#define        NFSRCHSZ        256
 
 struct nfsrvcache {
 
 struct nfsrvcache {
-       struct  nfsrvcache *rc_chain[2];        /* Hash chain links */
-       struct  nfsrvcache *rc_lchain[2];       /* Lru list */
+       struct  nfsrvcache *rc_forw;            /* Hash chain links */
+       struct  nfsrvcache **rc_back;           /* Hash chain links */
+       struct  nfsrvcache *rc_next;            /* Lru list */
+       struct  nfsrvcache **rc_prev;           /* Lru list */
        u_long  rc_xid;                         /* rpc id number */
        time_t  rc_timestamp;                   /* Time stamp */
        union {
        u_long  rc_xid;                         /* rpc id number */
        time_t  rc_timestamp;                   /* Time stamp */
        union {
@@ -32,10 +33,6 @@ struct nfsrvcache {
        u_char  rc_flag;                /* Flag bits */
 };
 
        u_char  rc_flag;                /* Flag bits */
 };
 
-#define        rc_forw         rc_chain[0]
-#define        rc_back         rc_chain[1]
-#define        rc_next         rc_lchain[0]
-#define        rc_prev         rc_lchain[1]
 #define        rc_reply        rc_un.ru_repmb
 #define        rc_status       rc_un.ru_repstat
 #define        rc_inetaddr     rc_haddr.had_inetaddr
 #define        rc_reply        rc_un.ru_repmb
 #define        rc_status       rc_un.ru_repstat
 #define        rc_inetaddr     rc_haddr.had_inetaddr
index 35096a2..ba65f50 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)nqnfs.h     7.3 (Berkeley) %G%
+ *     @(#)nqnfs.h     7.4 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -81,7 +81,7 @@ struct nqhost {
 struct nqlease {
        struct nqlease *lc_chain1[2];   /* Timer queue list (must be first) */
        struct nqlease *lc_fhnext;      /* Fhandle hash list */
 struct nqlease {
        struct nqlease *lc_chain1[2];   /* Timer queue list (must be first) */
        struct nqlease *lc_fhnext;      /* Fhandle hash list */
-       struct nqlease *lc_fhprev;
+       struct nqlease **lc_fhprev;
        time_t          lc_expiry;      /* Expiry time (sec) */
        struct nqhost   lc_host;        /* Host that got lease */
        struct nqm      *lc_morehosts;  /* Other hosts that share read lease */
        time_t          lc_expiry;      /* Expiry time (sec) */
        struct nqhost   lc_host;        /* Host that got lease */
        struct nqm      *lc_morehosts;  /* Other hosts that share read lease */
@@ -155,12 +155,14 @@ struct nqm {
                    NQL_WRITE : nqnfs_piggy[p]) : 0))
 
 /*
                    NQL_WRITE : nqnfs_piggy[p]) : 0))
 
 /*
- * List heads for timer queues.
+ * List head for timer queue.
  */
  */
-union nqsrvthead {
+extern union nqsrvthead {
        union   nqsrvthead *th_head[2];
        struct  nqlease *th_chain[2];
        union   nqsrvthead *th_head[2];
        struct  nqlease *th_chain[2];
-};
+} nqthead;
+extern struct nqlease **nqfhead;
+extern u_long nqfheadhash;
 
 /*
  * Nqnfs return status numbers.
 
 /*
  * Nqnfs return status numbers.