For each StoreData operation the dataVersion on the object is incremented.
To prevent all of the cached buffers from being considered out of date,
if the dataVersion has been incremented by exactly one, then update the
dataVersion of the buffers that match the FID and the previous dataVersion
(cherry picked from commit
4e8bc6d5016f8e6d46a21331009c414d94e90d10)
if (LargeIntegerGreaterThanOrEqualTo(t, scp->length))
scp->mask &= ~CM_SCACHEMASK_LENGTH;
- cm_MergeStatus(scp, &outStatus, &volSync, userp, 0);
+ cm_MergeStatus(scp, &outStatus, &volSync, userp, CM_MERGEFLAG_STOREDATA);
} else {
if (code == CM_ERROR_SPACE)
scp->flags |= CM_SCACHEFLAG_OUTOFSPACE;
if (LargeIntegerGreaterThanOrEqualTo(t, scp->length))
scp->mask &= ~CM_SCACHEMASK_LENGTH;
- cm_MergeStatus(scp, &outStatus, &volSync, userp, 0);
+ cm_MergeStatus(scp, &outStatus, &volSync, userp, CM_MERGEFLAG_STOREDATA);
}
return code;
if (!(scp->flags & CM_SCACHEFLAG_RO))
return;
}
+
scp->serverModTime = statusp->ServerModTime;
if (!(scp->mask & CM_SCACHEMASK_CLIENTMODTIME)) {
scp->serverLength.HighPart = statusp->Length_hi;
scp->linkCount = statusp->LinkCount;
- scp->dataVersion = statusp->DataVersion;
scp->owner = statusp->Owner;
scp->group = statusp->Group;
scp->unixModeBits = statusp->UnixModeBits & 07777;
if (userp != NULL) {
cm_AddACLCache(scp, userp, statusp->CallerAccess);
}
+
+ if ((flags & CM_MERGEFLAG_STOREDATA) &&
+ statusp->DataVersion - scp->dataVersion == 1) {
+ afs_uint32 i;
+ cm_buf_t *bp;
+
+ for (i = 0; i < cm_data.buf_hashSize; i++)
+ {
+ for(bp = cm_data.buf_hashTablepp[i]; bp; bp=bp->hashp) {
+ if (cm_FidCmp(&scp->fid, &bp->fid) == 0 &&
+ bp->dataVersion == scp->dataVersion)
+ bp->dataVersion = statusp->DataVersion;
+ }
+ }
+
+ }
+ scp->dataVersion = statusp->DataVersion;
}
/* note that our stat cache info is incorrect, so force us eventually
* used to see if we're merging
* in old info.
*/
+#define CM_MERGEFLAG_STOREDATA 2 /* Merge due to storedata 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
cm_SyncOpDone(dscp, NULL, sflags);
if (code == 0)
cm_MergeStatus(dscp, &newDirStatus, &volSync, userp, 0);
- 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
- * have an inconsistent view of the world.
- */
- dscp->cbServerp = NULL;
- }
+ 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
+ * have an inconsistent view of the world.
+ */
+ dscp->cbServerp = NULL;
+ }
lock_ReleaseMutex(&dscp->mx);
return code;
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_STORESTATUS);
if (code == 0)
cm_MergeStatus(scp, &afsOutStatus, &volSync, userp,
- CM_MERGEFLAG_FORCE);
+ CM_MERGEFLAG_FORCE|CM_MERGEFLAG_STOREDATA);
/* if we're changing the mode bits, discard the ACL cache,
* since we changed the mode bits.