From: Jeffrey Altman Date: Mon, 10 Dec 2007 20:43:58 +0000 (+0000) Subject: windows-remove-out-of-date-buffers-from-hash-tables-20071210 X-Git-Tag: BP-openafs-windows-kdfs-ifs~300 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=649194188e4af21370faa1bf1217a887adae2572;p=packages%2Fo%2Fopenafs.git 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. --- diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 8a73b7ecb..daceea81d 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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; } diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index 01aef071d..1c2347937 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -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 diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 512bc0320..fd3529552 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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) {