static void
FreeCE(register struct client *entry)
{
+ entry->VenusEpoch = 0;
+ entry->sid = 0;
entry->next = CEFree;
CEFree = entry;
CEs--;
if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val)
free(client->CPS.prlist_val);
client->CPS.prlist_val = NULL;
- if (client->tcon) {
- rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
- rx_PutConnection(client->tcon);
- }
CurrentConnections--;
*cp = client->next;
ReleaseWriteLock(&client->lock);
Console--;
if ((rxconn = host->callback_rxcon)) {
host->callback_rxcon = (struct rx_connection *)0;
- /*
- * If rx_DestroyConnection calls h_FreeConnection we will
- * deadlock on the host_glock_mutex. Work around the problem
- * by unhooking the client from the connection before
- * destroying the connection.
- */
- client = rx_GetSpecific(rxconn, rxcon_client_key);
- if (client && client->tcon == rxconn) {
- rx_PutConnection(client->tcon);
- client->tcon = NULL;
- }
- rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
rx_DestroyConnection(rxconn);
}
if (host->hcps.prlist_val)
} /*h_TossStuff_r */
-/* Called by rx when a server connection disappears */
-int
-h_FreeConnection(struct rx_connection *tcon)
-{
- register struct client *client;
-
- client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (client) {
- H_LOCK;
- if (client->tcon == tcon) {
- rx_PutConnection(client->tcon);
- client->tcon = (struct rx_connection *)0;
- }
- H_UNLOCK;
- }
- return 0;
-} /*h_FreeConnection */
-
/* h_Enumerate: Calls (*proc)(host, held, param) for at least each host in the
* system at the start of the enumeration (perhaps more). Hosts may be deleted
* destroying the connection.
*/
client = rx_GetSpecific(rxconn, rxcon_client_key);
- if (client) {
- if (client->tcon != rxconn)
- ViceLog(0,("CB: client %x tcon %x didn't match rxconn %x\n", client, client->tcon, rxconn));
- else {
- rx_PutConnection(client->tcon);
- client->tcon = NULL;
- }
- }
rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
rx_DestroyConnection(rxconn);
}
int created = 0;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (client) {
+ if (client && client->sid == rxr_CidOf(tcon)
+ && client->VenusEpoch == rxr_GetEpoch(tcon)) {
client->refCount++;
h_Hold_r(client->host);
if (!client->deleted && client->prfail != 2) {
for (client = host->FirstClient; client; client = client->next) {
if (!client->deleted && (client->sid == rxr_CidOf(tcon))
&& (client->VenusEpoch == rxr_GetEpoch(tcon))) {
- if (client->tcon && (client->tcon != tcon)) {
- ViceLog(0,
- ("*** Vid=%d, sid=%x, tcon=%x, Tcon=%x ***\n",
- client->ViceId, client->sid, client->tcon,
- tcon));
- oldClient =
- (struct client *)rx_GetSpecific(client->tcon,
- rxcon_client_key);
- if (oldClient) {
- if (oldClient == client) {
- rx_SetSpecific(client->tcon, rxcon_client_key,
- NULL);
- } else
- ViceLog(0,
- ("Client-conn mismatch: CL1=%x, CN=%x, CL2=%x\n",
- client, client->tcon, oldClient));
- }
- rx_PutConnection(client->tcon);
- client->tcon = (struct rx_connection *)0;
- }
client->refCount++;
H_UNLOCK;
ObtainWriteLock(&client->lock);
* the RPC from the other client structure's rock.
*/
oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (oldClient && oldClient->tcon == tcon) {
+ if (oldClient && oldClient->sid == rxr_CidOf(tcon)
+ && oldClient->VenusEpoch == rxr_GetEpoch(tcon)) {
char hoststr[16];
if (!oldClient->deleted) {
/* if we didn't create it, it's not ours to put back */
free(client->CPS.prlist_val);
client->CPS.prlist_val = NULL;
client->CPS.prlist_len = 0;
- if (client->tcon) {
- rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
- }
}
/* We should perhaps check for 0 here */
client->refCount--;
oldClient->refCount++;
client = oldClient;
} else {
- rx_PutConnection(oldClient->tcon);
- oldClient->tcon = (struct rx_connection *)0;
ViceLog(0, ("FindClient: deleted client %x(%x) already had conn %x (host %s:%d), stolen by client %x(%x)\n",
oldClient, oldClient->sid, tcon,
afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
h_Unlock_r(host);
CurrentConnections++; /* increment number of connections */
}
- rx_GetConnection(tcon);
- client->tcon = tcon;
rx_SetSpecific(tcon, rxcon_client_key, client);
ReleaseWriteLock(&client->lock);
H_LOCK;
*cp = NULL;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
- if (client == NULL || client->tcon == NULL) {
+ if (client == NULL) {
ViceLog(0,
("GetClient: no client in conn %x (host %x:%d), VBUSYING\n",
tcon, rxr_HostOf(tcon),ntohs(rxr_PortOf(tcon))));
H_UNLOCK;
return VBUSY;
}
- if (rxr_CidOf(client->tcon) != client->sid) {
+ if (rxr_CidOf(tcon) != client->sid || rxr_GetEpoch(tcon) != client->VenusEpoch) {
ViceLog(0,
("GetClient: tcon %x tcon sid %d client sid %d\n",
- client->tcon, rxr_CidOf(client->tcon), client->sid));
+ tcon, rxr_CidOf(tcon), client->sid));
H_UNLOCK;
return VBUSY;
}
- if (!(client && client->tcon && rxr_CidOf(client->tcon) == client->sid)) {
- if (!client)
- ViceLog(0, ("GetClient: no client in conn %x\n", tcon));
- else
- ViceLog(0,
- ("GetClient: tcon %x tcon sid %d client sid %d\n",
- client->tcon, client->tcon ? rxr_CidOf(client->tcon)
- : -1, client->sid));
- assert(0);
- }
if (client && client->LastCall > client->expTime && client->expTime) {
char hoststr[16];
ViceLog(1,
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
for (client = host->FirstClient; client; client = client->next) {
if (!client->deleted) {
- if (client->tcon) {
(void)afs_snprintf(tmpStr, sizeof tmpStr,
" user id=%d, name=%s, sl=%s till %s",
client->ViceId, h_UserName(client),
sizeof(tbuffer))
: "No Limit\n");
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
- } else {
- (void)afs_snprintf(tmpStr, sizeof tmpStr,
- " user=%s, no current server connection\n",
- h_UserName(client));
- (void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
- }
(void)afs_snprintf(tmpStr, sizeof tmpStr, " CPS-%d is [",
client->CPS.prlist_len);
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);