Windows: prevent cm_server races
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 14 Aug 2011 04:14:10 +0000 (00:14 -0400)
committerDerrick Brashear <shadow@dementix.org>
Sun, 14 Aug 2011 18:34:07 +0000 (11:34 -0700)
Use interlocked operations to modified the flags field.

Close a race in cm_NewServer() which can result in multiple
cm_server objecs being created for the same addr/port/type
tuple.

Change-Id: Ia26e21e1f007875ce316d2ae45a1fbf6fed835f9
Reviewed-on: http://gerrit.openafs.org/5266
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h
src/WINNT/afsd/cm_volume.c

index f709f3a..edb4c34 100644 (file)
@@ -304,12 +304,12 @@ static void afsd_InitServerPreferences(void)
             saddr.sin_family = AF_INET;
             dwRank += (rand() & 0x000f);
 
-            tsp = cm_FindServer(&saddr, CM_SERVER_VLDB);
+            tsp = cm_FindServer(&saddr, CM_SERVER_VLDB, FALSE);
             if ( tsp )         /* an existing server - ref count increased */
             {
                 lock_ObtainMutex(&tsp->mx);
                 tsp->ipRank = (USHORT)dwRank;
-                tsp->flags |= CM_SERVERFLAG_PREF_SET;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
                tsp->adminRank = tsp->ipRank;
                 lock_ReleaseMutex(&tsp->mx);
 
@@ -322,7 +322,7 @@ static void afsd_InitServerPreferences(void)
                 tsp = cm_NewServer(&saddr, CM_SERVER_VLDB, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
                 lock_ObtainMutex(&tsp->mx);
                 tsp->ipRank = (USHORT)dwRank;
-                tsp->flags |= CM_SERVERFLAG_PREF_SET;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
                tsp->adminRank = tsp->ipRank;
                 lock_ReleaseMutex(&tsp->mx);
             }
@@ -380,12 +380,12 @@ static void afsd_InitServerPreferences(void)
             saddr.sin_family = AF_INET;
             dwRank += (rand() & 0x000f);
 
-            tsp = cm_FindServer(&saddr, CM_SERVER_FILE);
+            tsp = cm_FindServer(&saddr, CM_SERVER_FILE, FALSE);
             if ( tsp )         /* an existing server - ref count increased */
             {
                 lock_ObtainMutex(&tsp->mx);
                 tsp->ipRank = (USHORT)dwRank;
-               tsp->flags |= CM_SERVERFLAG_PREF_SET;
+               _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
                tsp->adminRank = tsp->ipRank;
                 lock_ReleaseMutex(&tsp->mx);
 
@@ -401,7 +401,7 @@ static void afsd_InitServerPreferences(void)
                 tsp = cm_NewServer(&saddr, CM_SERVER_FILE, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
                 lock_ObtainMutex(&tsp->mx);
                 tsp->ipRank = (USHORT)dwRank;
-                tsp->flags |= CM_SERVERFLAG_PREF_SET;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
                tsp->adminRank = tsp->ipRank;
                 lock_ReleaseMutex(&tsp->mx);
             }
index 27d12ee..405d3e5 100644 (file)
@@ -369,7 +369,7 @@ SRXAFSCB_CallBack(struct rx_call *callp, AFSCBFids *fidsArrayp, AFSCBs *cbsArray
         host = rx_HostOf(peerp);
         port = rx_PortOf(peerp);
 
-        tsp = cm_FindServerByIP(host, port, CM_SERVER_FILE);
+        tsp = cm_FindServerByIP(host, port, CM_SERVER_FILE, FALSE);
         if (tsp) {
             cellp = tsp->cellp;
             cm_PutServer(tsp);
@@ -963,7 +963,6 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
 {
     char *p = NULL;
 
-    struct sockaddr_in taddr;
     cm_server_t *tsp = NULL;
     cm_scache_t *scp = NULL;
     cm_cell_t* cellp = NULL;
@@ -987,10 +986,10 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
                 RpcStringFree(&p);
             }
 
-            tsp = cm_FindServerByUuid(serverUuid, CM_SERVER_FILE);
+            tsp = cm_FindServerByUuid(serverUuid, CM_SERVER_FILE, FALSE);
         }
         if (!tsp)
-            tsp = cm_FindServerByIP(host, port, CM_SERVER_FILE);
+            tsp = cm_FindServerByIP(host, port, CM_SERVER_FILE, FALSE);
         if (tsp) {
             cellp = tsp->cellp;
             cm_PutServer(tsp);
@@ -1010,11 +1009,7 @@ SRXAFSCB_InitCallBackState3(struct rx_call *callp, afsUUID* serverUuid)
     }
 
     if (connp && peerp) {
-       taddr.sin_family = AF_INET;
-       taddr.sin_addr.s_addr = rx_HostOf(rx_PeerOf(rx_ConnectionOf(callp)));
-       taddr.sin_port = rx_PortOf(rx_PeerOf(rx_ConnectionOf(callp)));
-
-       tsp = cm_FindServer(&taddr, CM_SERVER_FILE);
+       tsp = cm_FindServerByIP(host, port, CM_SERVER_FILE, FALSE);
 
        osi_Log1(afsd_logp, "InitCallbackState3 server %x", tsp);
 
@@ -2041,7 +2036,7 @@ cm_GiveUpAllCallbacks(cm_server_t *tsp, afs_int32 markDown)
 
             lock_ObtainMutex(&tsp->mx);
             if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
-                tsp->flags |= CM_SERVERFLAG_DOWN;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
                 tsp->downTime = time(NULL);
             }
             /* Now update the volume status */
@@ -2160,7 +2155,7 @@ cm_GiveUpAllCallbacksAllServersMulti(afs_int32 markDown)
 
             lock_ObtainMutex(&tsp->mx);
             if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
-                tsp->flags |= CM_SERVERFLAG_DOWN;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
                 tsp->downTime = time(NULL);
             }
             /* Now update the volume status */
index b6aa482..4c8711b 100644 (file)
@@ -45,7 +45,7 @@ long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *hostnamep, uns
     probe = !(cellrockp->flags & CM_FLAG_NOPROBE);
 
     /* if this server was previously created by fs setserverprefs */
-    if ( tsp = cm_FindServer(addrp, CM_SERVER_VLDB))
+    if ( tsp = cm_FindServer(addrp, CM_SERVER_VLDB, FALSE))
     {
         if ( !tsp->cellp )
             tsp->cellp = cellp;
index 141adb6..49e5fc6 100644 (file)
@@ -792,7 +792,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
             if (errorCode == RX_CALL_DEAD &&
                 (reqp->flags & CM_REQ_NEW_CONN_FORCED)) {
                 if (!(serverp->flags & CM_SERVERFLAG_DOWN)) {
-                    serverp->flags |= CM_SERVERFLAG_DOWN;
+                    _InterlockedOr(&serverp->flags, CM_SERVERFLAG_DOWN);
                     serverp->downTime = time(NULL);
                 }
             } else {
index f896c3b..1be9356 100644 (file)
@@ -1876,12 +1876,12 @@ cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
         }
         tmp.sin_family = AF_INET;
 
-        tsp = cm_FindServer(&tmp, type);
+        tsp = cm_FindServer(&tmp, type, FALSE);
         if ( tsp )             /* an existing server - ref count increased */
         {
             lock_ObtainMutex(&tsp->mx);
             tsp->ipRank = rank;
-            tsp->flags |= CM_SERVERFLAG_PREF_SET;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
            tsp->adminRank = tsp->ipRank;
             lock_ReleaseMutex(&tsp->mx);
 
@@ -1905,7 +1905,7 @@ cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
             tsp = cm_NewServer(&tmp, type, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
             lock_ObtainMutex(&tsp->mx);
             tsp->ipRank = rank;
-            tsp->flags |= CM_SERVERFLAG_PREF_SET;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PREF_SET);
            tsp->adminRank = tsp->ipRank;
             lock_ReleaseMutex(&tsp->mx);
             tsp->ipRank = rank;
index b7a4081..a294824 100644 (file)
@@ -131,13 +131,13 @@ cm_PingServer(cm_server_t *tsp)
        lock_ObtainMutex(&tsp->mx);
        tsp->waitCount--;
        if (tsp->waitCount == 0)
-           tsp->flags &= ~CM_SERVERFLAG_PINGING;
+           _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
        else
            osi_Wakeup((LONG_PTR)tsp);
        lock_ReleaseMutex(&tsp->mx);
        return;
     }
-    tsp->flags |= CM_SERVERFLAG_PINGING;
+    _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PINGING);
     wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
     afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
     lock_ReleaseMutex(&tsp->mx);
@@ -174,7 +174,7 @@ cm_PingServer(cm_server_t *tsp)
     lock_ObtainMutex(&tsp->mx);
     if (code >= 0 || code == RXGEN_OPCODE) {
        /* mark server as up */
-       tsp->flags &= ~CM_SERVERFLAG_DOWN;
+       _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
         tsp->downTime = 0;
 
        /* we currently handle 32-bits of capabilities */
@@ -218,7 +218,7 @@ cm_PingServer(cm_server_t *tsp)
     } else {
        /* mark server as down */
         if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
-            tsp->flags |= CM_SERVERFLAG_DOWN;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
             tsp->downTime = time(NULL);
         }
        if (code != VRESTARTING) {
@@ -257,7 +257,7 @@ cm_PingServer(cm_server_t *tsp)
     }
 
     if (tsp->waitCount == 0)
-       tsp->flags &= ~CM_SERVERFLAG_PINGING;
+       _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
     else
        osi_Wakeup((LONG_PTR)tsp);
     lock_ReleaseMutex(&tsp->mx);
@@ -413,7 +413,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
                 continue;
             }
 
-            tsp->flags |= CM_SERVERFLAG_PINGING;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PINGING);
             lock_ReleaseMutex(&tsp->mx);
 
             serversp[nconns] = tsp;
@@ -457,7 +457,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
 
             if (results[i] >= 0 || results[i] == RXGEN_OPCODE)  {
                 /* mark server as up */
-                tsp->flags &= ~CM_SERVERFLAG_DOWN;
+                _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
                 tsp->downTime = 0;
 
                 /* we currently handle 32-bits of capabilities */
@@ -502,7 +502,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
             } else {
                 /* mark server as down */
                 if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
-                    tsp->flags |= CM_SERVERFLAG_DOWN;
+                    _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
                     tsp->downTime = time(NULL);
                 }
                 if (code != VRESTARTING) {
@@ -542,7 +542,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
             }
 
             if (tsp->waitCount == 0)
-                tsp->flags &= ~CM_SERVERFLAG_PINGING;
+                _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
             else
                 osi_Wakeup((LONG_PTR)tsp);
 
@@ -577,7 +577,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
                 continue;
             }
 
-            tsp->flags |= CM_SERVERFLAG_PINGING;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PINGING);
             lock_ReleaseMutex(&tsp->mx);
 
             serversp[nconns] = tsp;
@@ -622,7 +622,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
 
             if (results[i] >= 0)  {
                 /* mark server as up */
-                tsp->flags &= ~CM_SERVERFLAG_DOWN;
+                _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
                 tsp->downTime = 0;
                 tsp->capabilities = 0;
 
@@ -634,7 +634,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
             } else {
                 /* mark server as down */
                 if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
-                    tsp->flags |= CM_SERVERFLAG_DOWN;
+                    _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
                     tsp->downTime = time(NULL);
                 }
                 if (code != VRESTARTING) {
@@ -650,7 +650,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
             }
 
             if (tsp->waitCount == 0)
-                tsp->flags &= ~CM_SERVERFLAG_PINGING;
+                _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
             else
                 osi_Wakeup((LONG_PTR)tsp);
 
@@ -748,9 +748,9 @@ void cm_SetServerNo64Bit(cm_server_t * serverp, int no64bit)
 {
     lock_ObtainMutex(&serverp->mx);
     if (no64bit)
-        serverp->flags |= CM_SERVERFLAG_NO64BIT;
+        _InterlockedOr(&serverp->flags, CM_SERVERFLAG_NO64BIT);
     else
-        serverp->flags &= ~CM_SERVERFLAG_NO64BIT;
+        _InterlockedAnd(&serverp->flags, ~CM_SERVERFLAG_NO64BIT);
     lock_ReleaseMutex(&serverp->mx);
 }
 
@@ -758,9 +758,9 @@ void cm_SetServerNoInlineBulk(cm_server_t * serverp, int no)
 {
     lock_ObtainMutex(&serverp->mx);
     if (no)
-        serverp->flags |= CM_SERVERFLAG_NOINLINEBULK;
+        _InterlockedOr(&serverp->flags, CM_SERVERFLAG_NOINLINEBULK);
     else
-        serverp->flags &= ~CM_SERVERFLAG_NOINLINEBULK;
+        _InterlockedAnd(&serverp->flags, ~CM_SERVERFLAG_NOINLINEBULK);
     lock_ReleaseMutex(&serverp->mx);
 }
 
@@ -834,6 +834,20 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
 
     osi_assertx(socketp->sin_family == AF_INET, "unexpected socket family");
 
+    lock_ObtainWrite(&cm_serverLock);  /* get server lock */
+    tsp = cm_FindServer(socketp, type, TRUE);
+    if (tsp) {
+        /* we might have found a server created by set server prefs */
+        if (uuidp && !afs_uuid_is_nil(uuidp) &&
+            !(tsp->flags & CM_SERVERFLAG_UUID))
+        {
+            tsp->uuid = *uuidp;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_UUID);
+        }
+        lock_ReleaseWrite(&cm_serverLock);
+        return tsp;
+    }
+
     tsp = malloc(sizeof(*tsp));
     if (tsp) {
         memset(tsp, 0, sizeof(*tsp));
@@ -841,7 +855,7 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
         tsp->cellp = cellp;
         if (uuidp && !afs_uuid_is_nil(uuidp)) {
             tsp->uuid = *uuidp;
-            tsp->flags |= CM_SERVERFLAG_UUID;
+            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_UUID);
         }
         tsp->refCount = 1;
         lock_InitializeMutex(&tsp->mx, "cm_server_t mutex", LOCK_HIERARCHY_SERVER);
@@ -849,7 +863,6 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
 
         cm_SetServerPrefs(tsp);
 
-        lock_ObtainWrite(&cm_serverLock);      /* get server lock */
         tsp->allNextp = cm_allServersp;
         cm_allServersp = tsp;
 
@@ -861,23 +874,25 @@ cm_server_t *cm_NewServer(struct sockaddr_in *socketp, int type, cm_cell_t *cell
             cm_numFileServers++;
             break;
         }
+    }
+    lock_ReleaseWrite(&cm_serverLock);         /* release server lock */
 
-        lock_ReleaseWrite(&cm_serverLock);     /* release server lock */
-
-        if ( !(flags & CM_FLAG_NOPROBE) ) {
-            tsp->flags |= CM_SERVERFLAG_DOWN;  /* assume down; ping will mark up if available */
-            cm_PingServer(tsp);                        /* Obtain Capabilities and check up/down state */
-        }
+    if (!(flags & CM_FLAG_NOPROBE) && tsp) {
+        _InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);       /* assume down; ping will mark up if available */
+        cm_PingServer(tsp);                                    /* Obtain Capabilities and check up/down state */
     }
+
     return tsp;
 }
 
 cm_server_t *
-cm_FindServerByIP(afs_uint32 ipaddr, unsigned short port, int type)
+cm_FindServerByIP(afs_uint32 ipaddr, unsigned short port, int type, int locked)
 {
     cm_server_t *tsp;
 
-    lock_ObtainRead(&cm_serverLock);
+    if (!locked)
+        lock_ObtainRead(&cm_serverLock);
+
     for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
         if (tsp->type == type &&
             tsp->addr.sin_addr.S_un.S_addr == ipaddr &&
@@ -889,17 +904,20 @@ cm_FindServerByIP(afs_uint32 ipaddr, unsigned short port, int type)
     if (tsp)
         cm_GetServerNoLock(tsp);
 
-    lock_ReleaseRead(&cm_serverLock);
+    if (!locked)
+        lock_ReleaseRead(&cm_serverLock);
 
     return tsp;
 }
 
 cm_server_t *
-cm_FindServerByUuid(afsUUID *serverUuid, int type)
+cm_FindServerByUuid(afsUUID *serverUuid, int type, int locked)
 {
     cm_server_t *tsp;
 
-    lock_ObtainRead(&cm_serverLock);
+    if (locked)
+        lock_ObtainRead(&cm_serverLock);
+
     for (tsp = cm_allServersp; tsp; tsp = tsp->allNextp) {
         if (tsp->type == type && !afs_uuid_equal(&tsp->uuid, serverUuid))
             break;
@@ -909,35 +927,18 @@ cm_FindServerByUuid(afsUUID *serverUuid, int type)
     if (tsp)
         cm_GetServerNoLock(tsp);
 
-    lock_ReleaseRead(&cm_serverLock);
+    if (!locked)
+        lock_ReleaseRead(&cm_serverLock);
 
     return tsp;
 }
 
 /* find a server based on its properties */
-cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type)
+cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type, int locked)
 {
-    cm_server_t *tsp;
-
     osi_assertx(addrp->sin_family == AF_INET, "unexpected socket value");
 
-    lock_ObtainRead(&cm_serverLock);
-    for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
-        if (tsp->type == type &&
-            tsp->addr.sin_addr.s_addr == addrp->sin_addr.s_addr &&
-            (tsp->addr.sin_port == addrp->sin_port || tsp->addr.sin_port == 0))
-            break;
-    }
-
-    /* bump ref count if we found the server */
-    if (tsp)
-        cm_GetServerNoLock(tsp);
-
-    /* drop big table lock */
-    lock_ReleaseRead(&cm_serverLock);
-
-    /* return what we found */
-    return tsp;
+    return cm_FindServerByIP(addrp->sin_addr.s_addr, addrp->sin_port, type, locked);
 }
 
 cm_server_vols_t *cm_NewServerVols(void) {
index 2aa03d8..8e39721 100644 (file)
@@ -99,7 +99,7 @@ extern void cm_PutServer(cm_server_t *);
 
 extern void cm_PutServerNoLock(cm_server_t *);
 
-extern cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type);
+extern cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type, int locked);
 
 extern osi_rwlock_t cm_serverLock;
 
@@ -135,9 +135,9 @@ extern void cm_SetServerNo64Bit(cm_server_t * serverp, int no64bit);
 
 extern void cm_SetServerNoInlineBulk(cm_server_t * serverp, int no);
 
-extern cm_server_t * cm_FindServerByIP(afs_uint32 addr, unsigned short port, int type);
+extern cm_server_t * cm_FindServerByIP(afs_uint32 addr, unsigned short port, int type, int locked);
 
-extern cm_server_t * cm_FindServerByUuid(afsUUID* uuid, int type);
+extern cm_server_t * cm_FindServerByUuid(afsUUID* uuid, int type, int locked);
 
 extern void cm_SetLanAdapterChangeDetected(void);
 
index 1c1e32a..d37a70b 100644 (file)
@@ -523,7 +523,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
             tsockAddr.sin_family = AF_INET;
             tempAddr = htonl(serverNumber[i]);
             tsockAddr.sin_addr.s_addr = tempAddr;
-            tsp = cm_FindServer(&tsockAddr, CM_SERVER_FILE);
+            tsp = cm_FindServer(&tsockAddr, CM_SERVER_FILE, FALSE);
 #ifdef MULTIHOMED
             if (tsp && (method == 2) && (tsp->flags & CM_SERVERFLAG_UUID)) {
                 /*
@@ -569,7 +569,7 @@ long cm_UpdateVolumeLocation(struct cm_cell *cellp, cm_user_t *userp, cm_req_t *
             if ( (method == 2) && !(tsp->flags & CM_SERVERFLAG_UUID) &&
                  !afs_uuid_is_nil(&serverUUID[i])) {
                 tsp->uuid = serverUUID[i];
-                tsp->flags |= CM_SERVERFLAG_UUID;
+                _InterlockedOr(&tsp->flags, CM_SERVERFLAG_UUID);
             }
 
             /* and add it to the list(s). */