Windows: cm_GetCell_gen Fixup cm_server cellp on race
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 23 Jan 2014 03:17:56 +0000 (22:17 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Sat, 8 Feb 2014 15:25:33 +0000 (07:25 -0800)
If a race occurs during the instantiation of a new cm_cell_t object,
the created servers will point at the wrong cm_cell_t object after
the race is detected.  Before cm_GetCell_gen completes the cm_server_t
objects must be fixed to point to the correct cm_cell_t.

Change-Id: I8341c2cfd2a8ac7be31699d11f78b4b9ced257af
Reviewed-on: http://gerrit.openafs.org/10777
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsd/cm_cell.c

index 990584b..b552a3b 100644 (file)
@@ -342,6 +342,8 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
         }
 
         if (cp2) {
+           cm_server_t *tsp;
+
             if (!hasMutex) {
                 lock_ObtainMutex(&cp->mx);
                 hasMutex = 1;
@@ -352,7 +354,24 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
             cm_RemoveCellFromNameHashTable(cp);
             lock_ReleaseMutex(&cp->mx);
             hasMutex = 0;
-            cm_FreeCell(cp);
+
+           /* Replace cells references in servers */
+           lock_ObtainRead(&cm_serverLock);
+           for (tsp = cm_serversAllFirstp;
+                 tsp;
+                 tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
+               if (tsp->cellp == cp) {
+                   osi_Log4(afsd_logp, "cm_GetCell_gen race: replacing cell (%u) %s with cell (%u) %s",
+                             cp->cellID,
+                             osi_LogSaveString(afsd_logp,cp->name),
+                             cp2->cellID,
+                             osi_LogSaveString(afsd_logp,cp2->name));
+                   tsp->cellp = cp2;
+               }
+           }
+           lock_ReleaseRead(&cm_serverLock);
+
+           cm_FreeCell(cp);
             cp = cp2;
             goto done;
         }