windows-buf-consistency-20080217

LICENSE MIT

All calls to buf_Get() must be protected by a read lock on the
cm_scache_t bufCreateLock

When a MergeStatus results in the invalidation of buffers, do
not remove buffers from the hash tables that have active references.
This commit is contained in:
Jeffrey Altman 2008-02-17 05:26:51 +00:00
parent 935c49a2a6
commit 33bed62961
3 changed files with 37 additions and 20 deletions

View File

@ -694,7 +694,10 @@ cm_BkgPrefetch(cm_scache_t *scp, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, af
lock_ReleaseMutex(&scp->mx);
mxheld = 0;
}
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &offset, &bp);
lock_ReleaseRead(&scp->bufCreateLock);
if (code)
break;
@ -1087,7 +1090,9 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp,
if (LargeIntegerGreaterThanOrEqualTo(pageBase, fileSize))
break;
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &pageBase, &tbp);
lock_ReleaseRead(&scp->bufCreateLock);
if (code) {
//lock_ReleaseMutex(&cm_bufGetMutex);
lock_ObtainMutex(&scp->mx);

View File

@ -1657,31 +1657,41 @@ void cm_MergeStatus(cm_scache_t *dscp,
for (bp = cm_data.buf_fileHashTablepp[i]; bp; bp=nextBp)
{
nextBp = bp->fileHashp;
/*
* if the buffer belongs to this stat cache entry
* and the buffer mutex can be obtained, check the
* reference count and if it is zero, remove the buffer
* from the hash tables. If there are references,
* the buffer might be updated to the current version
* so leave it in place.
*/
if (cm_FidCmp(&scp->fid, &bp->fid) == 0 &&
lock_TryMutex(&bp->mx)) {
if (bp->refCount == 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;
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;
}
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;
}
*lbpp = bp->hashp; /* hash out */
bp->hashp = NULL;
bp->flags &= ~CM_BUF_INHASH;
lock_ReleaseMutex(&bp->mx);
}
}
lock_ReleaseWrite(&buf_globalLock);
}
scp->dataVersion = dataVersion;

View File

@ -1698,7 +1698,9 @@ long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp)
/* read the link data */
lock_ReleaseMutex(&linkScp->mx);
thyper.LowPart = thyper.HighPart = 0;
lock_ObtainRead(&linkScp->bufCreateLock);
code = buf_Get(linkScp, &thyper, &bufp);
lock_ReleaseRead(&linkScp->bufCreateLock);
lock_ObtainMutex(&linkScp->mx);
if (code)
return code;