From: Jeffrey Altman Date: Mon, 20 Feb 2006 15:27:06 +0000 (+0000) Subject: STABLE14-viced-client-cps-race-fix-20060220 X-Git-Tag: openafs-stable-1_4_1-rc9~32 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=8fc8483ae7aed185e4555f891952c8d62fb27479;p=packages%2Fo%2Fopenafs.git STABLE14-viced-client-cps-race-fix-20060220 remove a race condition between h_TossStuff_r and SRXAFS_FlushCPS by changing h_ID2Client to return the client with a refcount and then release the refCount with PutClient. when the CPS list is non-NULL and the viceid is ANONYMOUSID be sure to set the prlist_val to NULL if the prlist_len is being set to 0 since all of the tests are performed on prlist_val (cherry picked from commit 4808977d7d0e49e5d260a26113fd97cb48d5f844) --- diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 28cfe9fde..7a4443690 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -6163,7 +6163,7 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids, for (i = 0; i < nids; i++, vd++) { if (!*vd) continue; - client = h_ID2Client(*vd); /* returns client write locked, or NULL */ + client = h_ID2Client(*vd); /* returns write locked and refCounted, or NULL */ if (!client) continue; @@ -6179,6 +6179,7 @@ SRXAFS_FlushCPS(struct rx_call * acall, struct ViceIds * vids, client->CPS.prlist_len = 0; } ReleaseWriteLock(&client->lock); + PutClient(&client); } addr = addrs->IPAddrs_val; diff --git a/src/viced/host.c b/src/viced/host.c index 0dd0311e2..682297861 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -719,10 +719,9 @@ h_TossStuff_r(register struct host *host) } /* We can't protect this without dropping the H_LOCK */ client->CPS.prlist_len = 0; - if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) { + if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) free(client->CPS.prlist_val); - client->CPS.prlist_val = NULL; - } + client->CPS.prlist_val = NULL; if (client->tcon) { rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0); } @@ -1533,7 +1532,7 @@ MapName_r(char *aname, char *acell, afs_int32 * aval) /*MapName*/ -/* NOTE: this returns the client with a Write lock */ +/* NOTE: this returns the client with a Write lock and a refCount */ struct client * h_ID2Client(afs_int32 vid) { @@ -1549,9 +1548,6 @@ h_ID2Client(afs_int32 vid) client->refCount++; H_UNLOCK; ObtainWriteLock(&client->lock); - H_LOCK; - client->refCount--; - H_UNLOCK; return client; } } @@ -1721,11 +1717,10 @@ h_FindClient_r(struct rx_connection *tcon) client->prfail = fail; if (!(client->CPS.prlist_val) || (viceid != client->ViceId)) { - if (client->CPS.prlist_val && (client->ViceId != ANONYMOUSID)) { + client->CPS.prlist_len = 0; + if (client->CPS.prlist_val && (client->ViceId != ANONYMOUSID)) free(client->CPS.prlist_val); - } client->CPS.prlist_val = NULL; - client->CPS.prlist_len = 0; client->ViceId = viceid; client->expTime = expTime; @@ -1784,10 +1779,9 @@ h_FindClient_r(struct rx_connection *tcon) afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr), ntohs(rxr_PortOf(tcon)), oldClient, oldClient->sid)); - if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) { + if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) free(client->CPS.prlist_val); - client->CPS.prlist_val = NULL; - } + client->CPS.prlist_val = NULL; client->CPS.prlist_len = 0; if (client->tcon) { rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);