From 871f79b8a0082f71a8f52cafc64e4093d9b0517d Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 10 Dec 2007 20:45:16 +0000 Subject: [PATCH] DEVEL15-windows-remove-out-of-date-buffers-from-hash-tables-20071210 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 | 51 +++++++++++++++++++++++++++++++----- src/WINNT/afsd/cm_scache.h | 1 + src/WINNT/afsd/cm_vnodeops.c | 16 +++++------ 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 8fca3278f..6f24d636c 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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; } diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index 8bc373912..f95ca065b 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -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 diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 814aa96a1..da578118a 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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) { -- 2.39.5