mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 15:30:14 +00:00
afs: Check dv against localhero aincr
For operations that modify directories, we call afs_LocalHero to determine if we can perform the directory modification in our local cache, and avoid fetching the dir blob from the fileserver. Currently, afs_LocalHero assumes that the DV received from the fileserver is correct, and will update the cache DV as long as we have a valid callback on the file. If for any reason the client cache falls out of sync with what's on the fileserver, this can cause the client to incorrectly believe its cache is up to date. Since, the cached data will be marked with the newest DV, even if the DV on the server has jumped to be larger than we expected. While the client cache should never fall out of sync with the fileserver, in the past this has been possible due to other bugs (fileserver idle dead processing and client VNOSERVICE handling). Assuming that the given DV is correct is also just unnecesarily fragile, since we can always check if it is correct, so just check it, and add some comments helping explain what's going on here. Note that regular file writes effectively already check this. Note that this change makes use of the 'aincr' argument to afs_LocalHero, which was previously unused. aincr appears to have been used for a purpose similar to this before OpenAFS 1.0, but was removed, possibly accidentally. It is possible this change negatively affects, or even breaks (unlikely), functionality with the AFS<->DFS translator. Although nothing of the sort has been seen, it is difficult to know one way or the other, due to the lack of available DFS translators. Change-Id: I0e5395bac695257f66ba0cd58695a59ebdf56431 Reviewed-on: http://gerrit.openafs.org/8864 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@your-file-system.com>
This commit is contained in:
parent
19f424ecc2
commit
004e9f2563
@ -521,13 +521,25 @@ afs_LocalHero(struct vcache *avc, struct dcache *adc,
|
||||
|
||||
AFS_STATCNT(afs_LocalHero);
|
||||
hset64(avers, astat->dataVersionHigh, astat->DataVersion);
|
||||
/* this *is* the version number, no matter what */
|
||||
/* avers *is* the version number now, no matter what */
|
||||
|
||||
if (adc) {
|
||||
/* does what's in the dcache *now* match what's in the vcache *now*,
|
||||
* and do we have a valid callback? if not, our local copy is not "ok" */
|
||||
ok = (hsame(avc->f.m.DataVersion, adc->f.versionNo) && avc->callback
|
||||
&& (avc->f.states & CStatd) && avc->cbExpires >= osi_Time());
|
||||
} else {
|
||||
ok = 0;
|
||||
}
|
||||
if (ok) {
|
||||
/* check that the DV on the server is what we expect it to be */
|
||||
afs_hyper_t newDV;
|
||||
hset(newDV, adc->f.versionNo);
|
||||
hadd32(newDV, aincr);
|
||||
if (!hsame(avers, newDV)) {
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
#if defined(AFS_SGI_ENV)
|
||||
osi_Assert(avc->v.v_type == VDIR);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user