Windows: Do not double increment cm_data.currentCells
[openafs.git] / src / WINNT / afsd / cm_cell.c
index 855d0f9..2fd0237 100644 (file)
@@ -33,7 +33,7 @@ osi_rwlock_t cm_cellLock;
  *
  * At the present time the return value is ignored by the caller.
  */
-long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *hostnamep, unsigned short ipRank)
+long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *hostnamep, unsigned short adminRank)
 {
     cm_server_t *tsp;
     cm_serverRef_t *tsrp;
@@ -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;
@@ -59,16 +59,12 @@ long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *hostnamep, uns
     else
         tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp, NULL, probe ? 0 : CM_FLAG_NOPROBE);
 
-    if (ipRank)
-        tsp->ipRank = ipRank;
+    if (adminRank)
+        tsp->adminRank = adminRank;
 
     /* Insert the vlserver into a sorted list, sorted by server rank */
     tsrp = cm_NewServerRef(tsp, 0);
     cm_InsertServerList(&cellp->vlServersp, tsrp);
-    /* drop the allocation reference */
-    lock_ObtainWrite(&cm_serverLock);
-    tsrp->refCount--;
-    lock_ReleaseWrite(&cm_serverLock);
 
     return 0;
 }
@@ -88,14 +84,19 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
 
     lock_ObtainMutex(&cp->mx);
     mxheld = 1;
-    if ((cp->vlServersp == NULL
+
 #ifdef AFS_FREELANCE_CLIENT
-          && !(cp->flags & CM_CELLFLAG_FREELANCE)
+    if (cp->flags & CM_CELLFLAG_FREELANCE) {
+        lock_ReleaseMutex(&cp->mx);
+        return cp;
+    }
 #endif
-          ) || (time(0) > cp->timeout)
-        || (cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) &&
-         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID)))
-            )
+
+    if (cm_IsServerListEmpty(cp->vlServersp) ||
+        (time(0) > cp->timeout) ||
+        (cm_dnsEnabled &&
+         (cp->flags & CM_CELLFLAG_DNS) &&
+         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID))))
     {
         lock_ReleaseMutex(&cp->mx);
         mxheld = 0;
@@ -179,6 +180,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
     afs_uint32 hash;
     cm_cell_rock_t rock;
     size_t len;
+    afs_int32 cellID;
 
     if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH))
         return NULL;
@@ -268,15 +270,16 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
             if ( cm_data.currentCells >= cm_data.maxCells )
                 osi_panic("Exceeded Max Cells", __FILE__, __LINE__);
 
-            /* don't increment currentCells until we know that we
-             * are going to keep this entry
+            /*
+             * the cellID cannot be 0.
+             * If there is a name collision, one of the entries
+             * will end up on cm_data.freeCellsp for reuse.
              */
-            cp = &cm_data.cellBaseAddress[cm_data.currentCells];
+            cellID = InterlockedIncrement(&cm_data.currentCells);
+            cp = &cm_data.cellBaseAddress[cellID - 1];
             memset(cp, 0, sizeof(cm_cell_t));
             cp->magic = CM_CELL_MAGIC;
-
-            /* the cellID cannot be 0 */
-            cp->cellID = ++cm_data.currentCells;
+            cp->cellID = cellID;
 
             /* otherwise we found the cell, and so we're nearly done */
             lock_InitializeMutex(&cp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);