mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 13:38:01 +00:00
afs: discard cached state when we are unsure of validity
in the event we got a network error, we don't know if the server completed (or will complete) our operation. we can assume nothing. a more complicated version of this could attempt to verify that the state is what we expect it to be, but in extended callbacks universe this is potentially easier to solve anyway. for now, return the error to the caller, and mark the vcache unstat'd. (cherry picked from commit c2fc7e0f66621fc97f5b4dc389d379260638315c) Change-Id: Ic38cf16e47664e6f36ad614735b42d3f4e5a6ce2 Reviewed-on: http://gerrit.openafs.org/6520 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Derrick Brashear <shadow@dementix.org>
This commit is contained in:
parent
6479bb29d4
commit
3d4c44b61d
@ -273,6 +273,61 @@ afs_BlackListOnce(struct vrequest *areq, struct VenusFid *afid,
|
||||
return serversleft;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* afs_ClearStatus
|
||||
*
|
||||
* Description:
|
||||
* Analyze the outcome of an RPC operation, taking whatever support
|
||||
* actions are necessary.
|
||||
*
|
||||
* Arguments:
|
||||
* afid : The FID of the file involved in the action. This argument
|
||||
* may be null if none was involved.
|
||||
* op : which RPC we are analyzing.
|
||||
* avp : A pointer to the struct volume, if we already have one.
|
||||
*
|
||||
* Returns:
|
||||
* Non-zero value if the related RPC operation can be retried,
|
||||
* zero otherwise.
|
||||
*
|
||||
* Environment:
|
||||
* This routine is called when we got a network error,
|
||||
* and discards state if the operation was a data-mutating
|
||||
* operation.
|
||||
*------------------------------------------------------------------------*/
|
||||
static int
|
||||
afs_ClearStatus(struct VenusFid *afid, int op, struct volume *avp)
|
||||
{
|
||||
struct volume *tvp = NULL;
|
||||
|
||||
/* if it's not a write op, we have nothing to veto and shouldn't clear. */
|
||||
if (!AFS_STATS_FS_RPCIDXES_ISWRITE(op)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (avp)
|
||||
tvp = avp;
|
||||
else if (afid)
|
||||
tvp = afs_FindVolume(afid, READ_LOCK);
|
||||
|
||||
/* don't assume just discarding will fix if no cached volume */
|
||||
if (tvp) {
|
||||
struct vcache *tvc;
|
||||
ObtainReadLock(&afs_xvcache);
|
||||
if ((tvc = afs_FindVCache(afid, 0, 0))) {
|
||||
ReleaseReadLock(&afs_xvcache);
|
||||
tvc->f.states &= ~(CStatd | CUnique);
|
||||
afs_PutVCache(tvc);
|
||||
} else {
|
||||
ReleaseReadLock(&afs_xvcache);
|
||||
}
|
||||
}
|
||||
if (!avp)
|
||||
afs_PutVolume(tvp, READ_LOCK);
|
||||
|
||||
/* not retriable: we may have raced ourselves */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* EXPORTED afs_Analyze
|
||||
@ -465,8 +520,12 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
|
||||
else {
|
||||
if (acode == RX_MSGSIZE)
|
||||
shouldRetry = 1;
|
||||
else
|
||||
else {
|
||||
areq->networkError = 1;
|
||||
/* do not promote to shouldRetry if not already */
|
||||
if (afs_ClearStatus(afid, op, NULL) == 0)
|
||||
shouldRetry = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldRetry;
|
||||
@ -516,14 +575,17 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn,
|
||||
serversleft = afs_BlackListOnce(areq, afid, tsp);
|
||||
if (afid)
|
||||
tvp = afs_FindVolume(afid, READ_LOCK);
|
||||
if (!afid || !tvp || (tvp->states & VRO))
|
||||
areq->idleError++;
|
||||
if ((serversleft == 0) && tvp &&
|
||||
((tvp->states & VRO) || (tvp->states & VBackup))) {
|
||||
shouldRetry = 0;
|
||||
} else {
|
||||
shouldRetry = 1;
|
||||
}
|
||||
if (!afid || !tvp || (tvp->states & VRO))
|
||||
areq->idleError++;
|
||||
else if (afs_ClearStatus(afid, op, tvp) == 0)
|
||||
shouldRetry = 0;
|
||||
|
||||
if (tvp)
|
||||
afs_PutVolume(tvp, READ_LOCK);
|
||||
/* By doing this, we avoid ever marking a server down
|
||||
|
@ -867,6 +867,8 @@ struct afs_stats_CMPerf {
|
||||
|
||||
#define AFS_STATS_NUM_FS_RPC_OPS 29
|
||||
|
||||
#define AFS_STATS_FS_RPCIDXES_ISWRITE(X) (((X > AFS_STATS_FS_RPCIDX_FETCHSTATUS) && (X < AFS_STATS_FS_RPCIDX_GETSTATISTICS)) || (X == AFS_STATS_FS_RPCIDX_SETVOLUMESTATUS))
|
||||
|
||||
#define AFS_STATS_FS_XFERIDX_FETCHDATA 0
|
||||
#define AFS_STATS_FS_XFERIDX_STOREDATA 1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user