windows-remove-out-of-date-buffers-from-hash-tables-20071210
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 10 Dec 2007 20:43:58 +0000 (20:43 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 10 Dec 2007 20:43:58 +0000 (20:43 +0000)
LICENSE MIT

When a cm_MergeStatus operation determines that the current data buffers
are out of date, remove them from the buffer hash tables in order to speed
the lookup of valid data buffers.

src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_scache.h
src/WINNT/afsd/cm_vnodeops.c

index 8a73b7e..daceea8 100644 (file)
@@ -1635,15 +1635,54 @@ void cm_MergeStatus(cm_scache_t *dscp,
     }
 
     if ((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion == 1) {
-       cm_buf_t *bp;
-
-       for (bp = cm_data.buf_fileHashTablepp[BUF_FILEHASH(&scp->fid)]; bp; bp=bp->fileHashp)
+        buf_ForceDataVersion(scp, scp->dataVersion, dataVersion);
+    } else if (scp->dataVersion != 0 && 
+        (!(flags & CM_MERGEFLAG_DIROP) && dataVersion != scp->dataVersion ||
+         (flags & CM_MERGEFLAG_DIROP) && dataVersion - scp->dataVersion > 1)) {
+        /* 
+         * We now know that all of the data buffers that we have associated
+         * with this scp are invalid.  Subsequent operations will go faster
+         * if the buffers are removed from the hash tables.
+         *
+         * We do not remove directory buffers if the dataVersion delta is 1 because
+         * those version numbers will be updated as part of the directory operation.
+         */
+        int i, j;
+        cm_buf_t **lbpp;
+        cm_buf_t *tbp;
+        cm_buf_t *bp, *prevBp, *nextBp;
+
+        lock_ObtainWrite(&buf_globalLock);
+        i = BUF_FILEHASH(&scp->fid);
+               for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp=nextBp)
        {
-           if (cm_FidCmp(&scp->fid, &bp->fid) == 0 && 
-               bp->dataVersion == scp->dataVersion)
-               bp->dataVersion = dataVersion;
+            nextBp = bp->fileHashp;
+
+            if (cm_FidCmp(&scp->fid, &bp->fid) == 0) {
+                prevBp = bp->fileHashBackp;
+                bp->fileHashBackp = bp->fileHashp = NULL;
+                if (prevBp)
+                    prevBp->fileHashp = nextBp;
+                else
+                    cm_data.buf_fileHashTablepp[i] = nextBp;
+                if (nextBp)
+                    nextBp->fileHashBackp = prevBp;
+
+                j = BUF_HASH(&bp->fid, &bp->offset);
+                lbpp = &(cm_data.buf_scacheHashTablepp[j]);
+                for(tbp = *lbpp; tbp; lbpp = &tbp->hashp, tbp = *lbpp) {
+                    if (tbp == bp) 
+                        break;
+                }
+
+                *lbpp = bp->hashp;     /* hash out */
+                bp->hashp = NULL;
+
+                bp->flags &= ~CM_BUF_INHASH;
+            }
        }
 
+        lock_ReleaseWrite(&buf_globalLock);
     }
     scp->dataVersion = dataVersion;
 }
index 01aef07..1c23479 100644 (file)
@@ -303,6 +303,7 @@ typedef struct cm_scache {
                                                 * in old info.
                                                  */
 #define CM_MERGEFLAG_STOREDATA         2       /* Merge due to storedata op */
+#define CM_MERGEFLAG_DIROP              4       /* Merge due to directory op */ 
 
 /* hash define.  Must not include the cell, since the callback revocation code
  * doesn't necessarily know the cell in the case of a multihomed server
index 512bc03..fd35295 100644 (file)
@@ -1644,7 +1644,7 @@ long cm_Unlink(cm_scache_t *dscp, char *namep, cm_user_t *userp, cm_req_t *reqp)
     cm_dnlcRemove(dscp, namep);
     cm_SyncOpDone(dscp, NULL, sflags);
     if (code == 0) {
-        cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     } else if (code == CM_ERROR_NOSUCHFILE) {
        /* windows would not have allowed the request to delete the file 
         * if it did not believe the file existed.  therefore, we must 
@@ -2714,7 +2714,7 @@ long cm_Create(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp,
     lock_ObtainMutex(&dscp->mx);
     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
     if (code == 0) {
-        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     }
     lock_ReleaseMutex(&dscp->mx);
 
@@ -2864,7 +2864,7 @@ long cm_MakeDir(cm_scache_t *dscp, char *namep, long flags, cm_attr_t *attrp,
     lock_ObtainMutex(&dscp->mx);
     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
     if (code == 0) {
-        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     }
     lock_ReleaseMutex(&dscp->mx);
 
@@ -2974,7 +2974,7 @@ long cm_Link(cm_scache_t *dscp, char *namep, cm_scache_t *sscp, long flags,
     lock_ObtainMutex(&dscp->mx);
     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
     if (code == 0) {
-        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     }
     lock_ReleaseMutex(&dscp->mx);
 
@@ -3056,7 +3056,7 @@ long cm_SymLink(cm_scache_t *dscp, char *namep, char *contentsp, long flags,
     lock_ObtainMutex(&dscp->mx);
     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
     if (code == 0) {
-        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     }
     lock_ReleaseMutex(&dscp->mx);
 
@@ -3160,7 +3160,7 @@ long cm_RemoveDir(cm_scache_t *dscp, char *namep, cm_user_t *userp,
     cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
     if (code == 0) {
         cm_dnlcRemove(dscp, namep); 
-        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, 0);
+        cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, CM_MERGEFLAG_DIROP);
     }
     lock_ReleaseMutex(&dscp->mx);
 
@@ -3355,7 +3355,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp,
 
     if (code == 0)
         cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync,
-                        userp, 0);
+                        userp, CM_MERGEFLAG_DIROP);
     lock_ReleaseMutex(&oldDscp->mx);
 
     if (code == 0) {
@@ -3398,7 +3398,7 @@ long cm_Rename(cm_scache_t *oldDscp, char *oldNamep, cm_scache_t *newDscp,
         cm_SyncOpDone(newDscp, NULL, CM_SCACHESYNC_STOREDATA);
         if (code == 0)
             cm_MergeStatus(NULL, newDscp, &updatedNewDirStatus, &volSync,
-                            userp, 0);
+                            userp, CM_MERGEFLAG_DIROP);
         lock_ReleaseMutex(&newDscp->mx);
 
         if (code == 0) {