afs: add a file-level comment to afs_osidnlc.c
[openafs.git] / src / afs / afs_osidnlc.c
index 218af5e..ab451dd 100644 (file)
@@ -1,17 +1,22 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
+/*-
+ * OSI Directory Name Lookup Cache
+ *
+ * Keep a local cache of lookup results to avoid needing to examine the disk
+ * cache, for frequently accessed names.
+ */
+
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include "afs/sysincludes.h"   /*Standard vendor system headers */
 #include "afsincludes.h"       /*AFS-based standard headers */
@@ -25,8 +30,8 @@ RCSID
  *    look into interactions of dnlc and readdir.
  *    cache larger names, perhaps by using a better,longer key (SHA) and discarding
  *    the actual name itself.
- *    precompute a key and stuff for @sys, and combine the HandleAtName function with
- *    this, since we're looking at the name anyway.  
+ *    precompute a key and stuff for \sys, and combine the HandleAtName function with
+ *    this, since we're looking at the name anyway.
  */
 
 struct afs_lock afs_xdnlc;
@@ -34,7 +39,7 @@ extern struct afs_lock afs_xvcache;
 
 dnlcstats_t dnlcstats;
 
-#define NCSIZE 300
+#define NCSIZE 4096
 #define NHSIZE 256             /* must be power of 2. == NHASHENT in dir package */
 struct nc *ncfreelist = NULL;
 static struct nc nameCache[NCSIZE];
@@ -83,6 +88,9 @@ GetMeAnEntry(void)
            break;
     }
 
+    if (nameptr >= NHSIZE)
+       nameptr = 0;
+
     TRACE(ScavengeEntryT, nameptr);
     tnc = nameHash[nameptr];
     if (!tnc)                  /* May want to consider changing this to return 0 */
@@ -145,7 +153,7 @@ osi_dnlc_enter(struct vcache *adp, char *aname, struct vcache *avc,
     ObtainWriteLock(&afs_xdnlc, 222);
 
     /* Only cache entries from the latest version of the directory */
-    if (!(adp->states & CStatd) || !hsame(*avno, adp->m.DataVersion)) {
+    if (!(adp->f.states & CStatd) || !hsame(*avno, adp->f.m.DataVersion)) {
        ReleaseWriteLock(&afs_xdnlc);
        return 0;
     }
@@ -192,22 +200,20 @@ struct vcache *
 osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype)
 {
     struct vcache *tvc;
-    int LRUme;
     unsigned int key, skey;
     char *ts = aname;
-    struct nc *tnc, *tnc1 = 0;
+    struct nc *tnc;
     int safety;
 #ifdef AFS_DARWIN80_ENV
     vnode_t tvp;
 #endif
 
     if (!afs_usednlc)
-       return 0;
+      return 0;
 
     dnlcHash(ts, key);         /* leaves ts pointing at the NULL */
-    if (ts - aname >= AFSNCNAMESIZE) {
-       return 0;
-    }
+    if (ts - aname >= AFSNCNAMESIZE)
+      return 0;
     skey = key & (NHSIZE - 1);
 
     TRACE(osi_dnlc_lookupT, skey);
@@ -221,7 +227,6 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype)
        if ( /* (tnc->key == key)  && */ (tnc->dirp == adp)
            && (!strcmp((char *)tnc->name, aname))) {
            tvc = tnc->vp;
-           tnc1 = tnc;
            break;
        } else if (tnc->next == nameHash[skey]) {       /* end of list */
            break;
@@ -235,23 +240,24 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype)
        }
     }
 
-    LRUme = 0;                 /* (tnc != nameHash[skey]); */
     ReleaseReadLock(&afs_xdnlc);
 
     if (!tvc) {
        ReleaseReadLock(&afs_xvcache);
        dnlcstats.misses++;
     } else {
-       if (tvc->states & CVInit) {
+       if ((tvc->f.states & CVInit)
+#ifdef  AFS_DARWIN80_ENV
+           ||(tvc->f.states & CDeadVnode)
+#endif
+           )
+       {
            ReleaseReadLock(&afs_xvcache);
            dnlcstats.misses++;
            osi_dnlc_remove(adp, aname, tvc);
            return 0;
        }
-#ifdef AFS_OSF_ENV
-       VN_HOLD((vnode_t *) tvc);
-#else
-#ifdef AFS_DARWIN80_ENV
+#if defined(AFS_DARWIN80_ENV)
        tvp = AFSTOV(tvc);
        if (vnode_get(tvp)) {
            ReleaseReadLock(&afs_xvcache);
@@ -271,41 +277,8 @@ osi_dnlc_lookup(struct vcache *adp, char *aname, int locktype)
 #else
        osi_vnhold(tvc, 0);
 #endif
-#endif
        ReleaseReadLock(&afs_xvcache);
 
-#ifdef notdef
-       /* 
-        * XX If LRUme ever is non-zero change the if statement around because
-        * aix's cc with optimizer on won't necessarily check things in order XX
-        */
-       if (LRUme && (0 == NBObtainWriteLock(&afs_xdnlc))) {
-           /* don't block to do this */
-           /* tnc might have been moved during race condition, */
-           /* but it's always in a legit hash chain when a lock is granted, 
-            * or else it's on the freelist so prev == NULL, 
-            * so at worst this is redundant */
-           /* Now that we've got it held, and a lock on the dnlc, we 
-            * should check to be sure that there was no race, and 
-            * bail out if there was. */
-           if (tnc->prev) {
-               /* special case for only two elements on list - relative ordering
-                * doesn't change */
-               if (tnc->prev != tnc->next) {
-                   /* remove from old location */
-                   tnc->prev->next = tnc->next;
-                   tnc->next->prev = tnc->prev;
-                   /* insert into new location */
-                   tnc->next = nameHash[skey];
-                   tnc->prev = tnc->next->prev;
-                   tnc->next->prev = tnc;
-                   tnc->prev->next = tnc;
-               }
-               nameHash[skey] = tnc;
-           }
-           ReleaseWriteLock(&afs_xdnlc);
-       }
-#endif
     }
 
     return tvc;
@@ -382,10 +355,15 @@ osi_dnlc_remove(struct vcache *adp, char *aname, struct vcache *avc)
     return 0;
 }
 
-/* remove anything pertaining to this directory.  I can invalidate
+/*!
+ * Remove anything pertaining to this directory.  I can invalidate
  * things without the lock, since I am just looking through the array,
  * but to move things off the lists or into the freelist, I need the
- * write lock */
+ * write lock
+ *
+ * \param adp vcache entry for the directory to be purged.
+ * \return 0
+ */
 int
 osi_dnlc_purgedp(struct vcache *adp)
 {
@@ -393,7 +371,7 @@ osi_dnlc_purgedp(struct vcache *adp)
     int writelocked;
 
 #ifdef AFS_DARWIN_ENV
-    if (!(adp->states & (CVInit | CVFlushed
+    if (!(adp->f.states & (CVInit | CVFlushed
 #ifdef AFS_DARWIN80_ENV
                         | CDeadVnode
 #endif
@@ -424,7 +402,12 @@ osi_dnlc_purgedp(struct vcache *adp)
     return 0;
 }
 
-/* remove anything pertaining to this file */
+/*!
+ * Remove anything pertaining to this file
+ *
+ * \param File vcache entry.
+ * \return 0
+ */
 int
 osi_dnlc_purgevp(struct vcache *avc)
 {
@@ -432,7 +415,7 @@ osi_dnlc_purgevp(struct vcache *avc)
     int writelocked;
 
 #ifdef AFS_DARWIN_ENV
-    if (!(avc->states & (CVInit | CVFlushed
+    if (!(avc->f.states & (CVInit | CVFlushed
 #ifdef AFS_DARWIN80_ENV
                         | CDeadVnode
 #endif
@@ -448,7 +431,7 @@ osi_dnlc_purgevp(struct vcache *avc)
     writelocked = (0 == NBObtainWriteLock(&afs_xdnlc, 3));
 
     for (i = 0; i < NCSIZE; i++) {
-       if ((nameCache[i].vp == avc)) {
+       if (nameCache[i].vp == avc) {
            nameCache[i].dirp = nameCache[i].vp = NULL;
            /* can't simply break; because of hard links -- might be two */
            /* different entries with same vnode */
@@ -478,8 +461,8 @@ osi_dnlc_purge(void)
            nameCache[i].dirp = nameCache[i].vp = NULL;
     } else {                   /* did get the lock */
        ncfreelist = NULL;
-       memset((char *)nameCache, 0, sizeof(struct nc) * NCSIZE);
-       memset((char *)nameHash, 0, sizeof(struct nc *) * NHSIZE);
+       memset(nameCache, 0, sizeof(struct nc) * NCSIZE);
+       memset(nameHash, 0, sizeof(struct nc *) * NHSIZE);
        for (i = 0; i < NCSIZE; i++) {
            nameCache[i].next = ncfreelist;
            ncfreelist = &nameCache[i];
@@ -507,13 +490,13 @@ osi_dnlc_init(void)
     int i;
 
     Lock_Init(&afs_xdnlc);
-    memset((char *)&dnlcstats, 0, sizeof(dnlcstats));
-    memset((char *)dnlctracetable, 0, sizeof(dnlctracetable));
+    memset(&dnlcstats, 0, sizeof(dnlcstats));
+    memset(dnlctracetable, 0, sizeof(dnlctracetable));
     dnlct = 0;
     ObtainWriteLock(&afs_xdnlc, 223);
     ncfreelist = NULL;
-    memset((char *)nameCache, 0, sizeof(struct nc) * NCSIZE);
-    memset((char *)nameHash, 0, sizeof(struct nc *) * NHSIZE);
+    memset(nameCache, 0, sizeof(struct nc) * NCSIZE);
+    memset(nameHash, 0, sizeof(struct nc *) * NHSIZE);
     for (i = 0; i < NCSIZE; i++) {
        nameCache[i].next = ncfreelist;
        ncfreelist = &nameCache[i];