From: Jeffrey Altman Date: Fri, 3 May 2013 15:23:31 +0000 (-0400) Subject: Windows: Introduce CM_CONN_FLAG_NEW X-Git-Tag: openafs-stable-1_8_0pre1~1186 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=0e2d4c0fcb45389d20dad93ae29b1c84364b59bf Windows: Introduce CM_CONN_FLAG_NEW The new CM_CONN_FLAG_NEW flag is set on the cm_conn object whenever a new rx_connection has been created. The flag is cleared in cm_Analyze if the call succeeded or if the error is one that is generated as a result of communicating with the peer. If no communication with the peer has taken place the connection is considered "new". For errors that would result in forcing a new connection, check whether the existing connection is already "new". This avoids an extra RX_CALL_DEAD timeout period in the case where a "new" connection was already in use. Change-Id: If23a5f4b98e7599e4b4e62b474661e9d91aba81b Reviewed-on: http://gerrit.openafs.org/9847 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 3cd7297..cfe0d36 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -394,7 +394,11 @@ cm_Analyze(cm_conn_t *connp, } } - if (errorCode == CM_ERROR_TIMEDOUT) { + if (errorCode == 0) { + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + } + else if (errorCode == CM_ERROR_TIMEDOUT) { osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_TIMEDOUT"); if ( timeLeft > 5 ) { thrd_Sleep(3000); @@ -415,6 +419,9 @@ cm_Analyze(cm_conn_t *connp, thrd_Sleep(1000); retry = 1; } + + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); } /* if there is nosuchvolume, then we have a situation in which a @@ -585,6 +592,9 @@ cm_Analyze(cm_conn_t *connp, /* special codes: VBUSY and VRESTARTING */ else if (errorCode == VBUSY || errorCode == VRESTARTING) { + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (fidp) { code = cm_FindVolumeByID(cellp, fidp->volume, userp, reqp, CM_GETVOL_FLAG_NO_LRU_UPDATE, @@ -650,6 +660,9 @@ cm_Analyze(cm_conn_t *connp, else if (errorCode == VNOVOL || errorCode == VMOVED || errorCode == VOFFLINE || errorCode == VSALVAGE || errorCode == VIO) { + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + /* In case of timeout */ reqp->volumeError = errorCode; @@ -823,6 +836,9 @@ cm_Analyze(cm_conn_t *connp, if ( timeLeft > 2 ) retry = 1; } else if ( errorCode == VNOVNODE ) { + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if ( fidp ) { osi_Log4(afsd_logp, "cm_Analyze passed VNOVNODE cell %u vol %u vn %u uniq %u.", fidp->cell, fidp->volume, fidp->vnode, fidp->unique); @@ -947,6 +963,9 @@ cm_Analyze(cm_conn_t *connp, * is currently busy on the server. Unconditionally * retry the request so an alternate call channel can be used. */ + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (serverp) sprintf(addr, "%d.%d.%d.%d", ((serverp->addr.sin_addr.s_addr & 0xff)), @@ -970,6 +989,9 @@ cm_Analyze(cm_conn_t *connp, * The RPC was not serviced so it can be retried and any * existing status information is still valid. */ + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (fidp) { if (serverp) sprintf(addr, "%d.%d.%d.%d", @@ -1010,6 +1032,9 @@ cm_Analyze(cm_conn_t *connp, * client should fail over to another server. If this is a * request against a single source, the client may retry once. */ + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (serverp) sprintf(addr, "%d.%d.%d.%d", ((serverp->addr.sin_addr.s_addr & 0xff)), @@ -1078,7 +1103,8 @@ cm_Analyze(cm_conn_t *connp, (reqp->flags & CM_REQ_NEW_CONN_FORCED ? "yes" : "no")); if (serverp) { - if ((reqp->flags & CM_REQ_NEW_CONN_FORCED)) { + if ((connp->flags & CM_CONN_FLAG_NEW) || + (reqp->flags & CM_REQ_NEW_CONN_FORCED)) { lock_ObtainMutex(&serverp->mx); if (!(serverp->flags & CM_SERVERFLAG_DOWN)) { _InterlockedOr(&serverp->flags, CM_SERVERFLAG_DOWN); @@ -1128,7 +1154,8 @@ cm_Analyze(cm_conn_t *connp, (reqp->flags & CM_REQ_NEW_CONN_FORCED ? "yes" : "no")); if (serverp) { - if (reqp->flags & CM_REQ_NEW_CONN_FORCED) { + if ((connp->flags & CM_CONN_FLAG_NEW) || + (reqp->flags & CM_REQ_NEW_CONN_FORCED)) { reqp->errorServp = serverp; reqp->tokenError = errorCode; } else { @@ -1182,6 +1209,9 @@ cm_Analyze(cm_conn_t *connp, osi_Log2(afsd_logp, "cm_Analyze: rxkad error code 0x%x (%s)", errorCode, s); + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (serverp) { reqp->errorServp = serverp; reqp->tokenError = errorCode; @@ -1195,6 +1225,9 @@ cm_Analyze(cm_conn_t *connp, * to answer our query. Therefore, we will retry the request * and force the use of another server. */ + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (serverp) { reqp->errorServp = serverp; reqp->tokenError = errorCode; @@ -1207,6 +1240,9 @@ cm_Analyze(cm_conn_t *connp, if ( timeLeft > 2 ) retry = 1; } else { + if (connp) + _InterlockedAnd(&connp->flags, ~CM_CONN_FLAG_NEW); + if (errorCode) { char * s = "unknown error"; switch ( errorCode ) { @@ -1340,6 +1376,7 @@ cm_Analyze(cm_conn_t *connp, cm_PutConn(connp); /* + * clear the volume updated flag if we succeed. * this way the flag will not prevent a subsequent volume * from being updated if necessary. @@ -1593,6 +1630,7 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp, rxs_Release(secObjp); /* Decrement the initial refCount */ _InterlockedAnd(&tcp->flags, ~CM_CONN_FLAG_FORCE_NEW); + _InterlockedOr(&tcp->flags, CM_CONN_FLAG_NEW); } long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, afs_uint32 replicated, cm_conn_t **connpp) diff --git a/src/WINNT/afsd/cm_conn.h b/src/WINNT/afsd/cm_conn.h index d326fe9..b340495 100644 --- a/src/WINNT/afsd/cm_conn.h +++ b/src/WINNT/afsd/cm_conn.h @@ -46,11 +46,12 @@ typedef struct cm_conn { afs_int32 refCount; /* Interlocked */ int ucgen; /* ucellp's generation number */ afs_uint32 flags; /* locked by mx */ - int cryptlevel; /* encrytion status */ + int cryptlevel; /* encryption status */ } cm_conn_t; #define CM_CONN_FLAG_FORCE_NEW 1 #define CM_CONN_FLAG_REPLICATION 2 +#define CM_CONN_FLAG_NEW 4 /* * structure used for tracking RPC progress