}
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;
}
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
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);
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);
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);
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);
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);
if (code == 0)
cm_MergeStatus(NULL, oldDscp, &updatedOldDirStatus, &volSync,
- userp, 0);
+ userp, CM_MERGEFLAG_DIROP);
lock_ReleaseMutex(&oldDscp->mx);
if (code == 0) {
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) {