]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-remove-out-of-date-buffers-from-hash-tables-20071210
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 10 Dec 2007 20:45:16 +0000 (20:45 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 10 Dec 2007 20:45:16 +0000 (20:45 +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.

(cherry picked from commit 649194188e4af21370faa1bf1217a887adae2572)

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

index 8fca3278f5c7e1511525654d017e198a9e7c80e7..6f24d636c47950c38ab19b5117570adf0e4b8d86 100644 (file)
@@ -1637,15 +1637,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 8bc373912b0faa43cc709e47ad52a2b151450517..f95ca065b52bf6b4c69dcd0e59cea017a32b8b02 100644 (file)
@@ -307,6 +307,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 814aa96a13b9d0ebbf47e2277c8b9ef45ca9d61a..da578118aa088aa69a94530d2519d3ded2f10fa2 100644 (file)
@@ -1646,7 +1646,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 
@@ -2716,7 +2716,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);
 
@@ -2866,7 +2866,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);
 
@@ -2976,7 +2976,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);
 
@@ -3058,7 +3058,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);
 
@@ -3162,7 +3162,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);
 
@@ -3357,7 +3357,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) {
@@ -3400,7 +3400,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) {