From d54859c6ac2e5186b18da027303860966504dbd9 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 28 Jun 2009 05:15:31 +0000 Subject: [PATCH] windows-multi-homed-callbacks-20090627 LICENSE MIT Properly handle callbacks from multi-homed file servers. Comparing cm_server_t pointers is insufficient. For a multi-homed server there will be multiple entries. The UUID for all of the equivalent entries will be the same. What matters is not that the pointers are the same but whether in the case of UUID labeled servers that the UUIDs match. Add cm_ServerEqual() to perform the comparison. --- src/WINNT/afsd/cm_callback.c | 10 +++------- src/WINNT/afsd/cm_server.c | 25 +++++++++++++++++++++++++ src/WINNT/afsd/cm_server.h | 2 ++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 63522b88e..17ab444bf 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -162,10 +162,6 @@ void cm_RevokeCallback(struct rx_call *callp, cm_cell_t * cellp, AFSFid *fidp) cm_scache_t *scp; long hash; - /* don't bother setting cell, since we won't be checking it (to aid - * in working with multi-homed servers: we don't know the cell if we - * don't recognize the IP address). - */ tfid.cell = cellp ? cellp->cellID : 0; tfid.volume = fidp->Volume; tfid.vnode = fidp->Vnode; @@ -1053,7 +1049,7 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid) discarded = 0; if (scp->cbExpires > 0 && scp->cbServerp != NULL) { /* we have a callback, now decide if we should clear it */ - if (scp->cbServerp == tsp) { + if (cm_ServerEqual(scp->cbServerp, tsp)) { osi_Log4(afsd_logp, "InitCallbackState3 Discarding SCache scp 0x%p vol %u vn %u uniq %u", scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique); cm_DiscardSCache(scp); @@ -1656,7 +1652,7 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp, /* record the callback; we'll clear it below if we really lose it */ if (cbrp) { if (scp) { - if (scp->cbServerp != cbrp->serverp) { + if (!cm_ServerEqual(scp->cbServerp, cbrp->serverp)) { serverp = scp->cbServerp; if (!freeFlag) cm_GetServer(cbrp->serverp); @@ -1903,7 +1899,7 @@ long cm_CBServersUp(cm_scache_t *scp, time_t * downTime) for (found = 0,tsrp = statep->serversp; tsrp; tsrp=tsrp->next) { if (tsrp->status == srv_deleted) continue; - if (tsrp->server == scp->cbServerp) + if (cm_ServerEqual(tsrp->server, scp->cbServerp)) found = 1; if (tsrp->server->downTime > *downTime) *downTime = tsrp->server->downTime; diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index 68fa4b4e1..f1f999829 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -1376,5 +1376,30 @@ int cm_DumpServers(FILE *outputFile, char *cookie, int lock) return (0); } +/* + * Determine if two servers are in fact the same. + * + * Returns 1 if they match, 0 if they do not + */ +int cm_ServerEqual(cm_server_t *srv1, cm_server_t *srv2) +{ + RPC_STATUS status; + + if (srv1 == NULL || srv2 == NULL) + return 0; + + if (srv1 == srv2) + return 1; + if (srv1->flags & CM_SERVERFLAG_UUID) { + if (!(srv2->flags & CM_SERVERFLAG_UUID)) + return 0; + + /* Both support UUID */ + if (UuidEqual((UUID *)&srv1->uuid, (UUID *)&srv2->uuid, &status)) + return 1; + } + + return 0; +} diff --git a/src/WINNT/afsd/cm_server.h b/src/WINNT/afsd/cm_server.h index 12f42077e..db023308c 100644 --- a/src/WINNT/afsd/cm_server.h +++ b/src/WINNT/afsd/cm_server.h @@ -136,6 +136,8 @@ extern void cm_RemoveVolumeFromServer(cm_server_t * serverp, afs_uint32 volID); extern int cm_DumpServers(FILE *outputFile, char *cookie, int lock); +extern int cm_ServerEqual(cm_server_t *srv1, cm_server_t *srv2); + /* Protected by cm_syscfgLock (rw) */ extern int cm_noIPAddr; /* number of client network interfaces */ extern int cm_IPAddr[CM_MAXINTERFACE_ADDR]; /* client's IP address in host order */ -- 2.39.5