DEVEL15-windows-updatecell-20070619
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 19 Jun 2007 17:15:59 +0000 (17:15 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 19 Jun 2007 17:15:59 +0000 (17:15 +0000)
No longer permit cm_GetCell() or cm_FindCellByID() to return NULL simply
because cm_UpdateCell() failed.  The cm_cell_t object still exists and
is valid even if the vlServersp list is empty.

Modify the lock management in cm_GetCell_Gen() to ensure we drop all the
locks.

In cm_Analyze() update the volume status when one of the servers reports
VBUSY or VRESTARTING.

(cherry picked from commit 01c3c334d53da95318f54b4085da9b37c79c90b9)

src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_cell.h
src/WINNT/afsd/cm_conn.c

index 4bd2df6..025036a 100644 (file)
@@ -115,16 +115,17 @@ cm_cell_t *cm_UpdateCell(cm_cell_t * cp)
 }
 
 /* load up a cell structure from the cell database, afsdcell.ini */
-cm_cell_t *cm_GetCell(char *namep, long flags)
+cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags)
 {
     return cm_GetCell_Gen(namep, NULL, flags);
 }
 
-cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
+cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
 {
     cm_cell_t *cp, *cp2;
     long code;
     char fullname[200]="";
+    int  hasWriteLock = 0;
 
     if (!strcmp(namep,SMB_IOCTL_FILENAME_NOSLASH))
         return NULL;
@@ -139,9 +140,10 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
     lock_ReleaseRead(&cm_cellLock);    
 
     if (cp) {
-        cp = cm_UpdateCell(cp);
+        cm_UpdateCell(cp);
     } else if (flags & CM_FLAG_CREATE) {
         lock_ObtainWrite(&cm_cellLock);
+        hasWriteLock = 1;
 
         /* when we dropped the lock the cell could have been added
          * to the list so check again while holding the write lock 
@@ -153,10 +155,8 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
             }
         }   
 
-        if (cp) {
-            lock_ReleaseWrite(&cm_cellLock);
+        if (cp)
             goto done;
-        }
 
         if ( cm_data.currentCells >= cm_data.maxCells )
             osi_panic("Exceeded Max Cells", __FILE__, __LINE__);
@@ -213,7 +213,6 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
         if (cp2) {
             cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);
             cp = cp2;
-            lock_ReleaseWrite(&cm_cellLock);
             goto done;
         }
 
@@ -234,10 +233,12 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
            
         /* the cellID cannot be 0 */
         cp->cellID = ++cm_data.currentCells;
-        lock_ReleaseWrite(&cm_cellLock);
     }
 
   done:
+    if (hasWriteLock)
+        lock_ReleaseWrite(&cm_cellLock);
+    
     /* fullname is not valid if cp == NULL */
     if (cp && newnamep)
         strcpy(newnamep, fullname);
@@ -257,7 +258,7 @@ cm_cell_t *cm_FindCellByID(afs_int32 cellID)
     lock_ReleaseRead(&cm_cellLock);    
 
     if (cp)
-        cp = cm_UpdateCell(cp);
+        cm_UpdateCell(cp);
 
     return cp;
 }
index 64eb03e..0652e2a 100644 (file)
@@ -40,13 +40,13 @@ extern long cm_ShutdownCell(void);
 
 extern long cm_ValidateCell(void);
 
-extern cm_cell_t *cm_GetCell(char *namep, long flags);
+extern cm_cell_t *cm_GetCell(char *namep, afs_uint32 flags);
 
-extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags);
+extern cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags);
 
 extern cm_cell_t *cm_FindCellByID(afs_int32 cellID);
 
-extern void cm_ChangeRankCellVLServer(cm_server_t       *tsp);
+extern void cm_ChangeRankCellVLServer(cm_server_t *tsp);
 
 extern osi_rwlock_t cm_cellLock;
 
index 1b675b1..32e62ab 100644 (file)
@@ -164,6 +164,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     cm_serverRef_t *tsrp;
     cm_cell_t  *cellp = NULL;
     cm_ucell_t *ucellp;
+    cm_volume_t * volp = NULL;
+    cm_vol_state_t *statep = NULL;
     int retry = 0;
     int free_svr_list = 0;
     int dead_session;
@@ -300,8 +302,6 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
          */
        osi_Log0(afsd_logp, "cm_Analyze passed CM_ERROR_ALLBUSY.");
         if (timeLeft > 7) {
-            cm_volume_t * volp = NULL;
-            cm_vol_state_t *statep;
 
             thrd_Sleep(5000);
 
@@ -372,12 +372,30 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
         lock_ObtainWrite(&cm_serverLock);
         for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
             if (tsrp->server == serverp && tsrp->status == srv_not_busy) {
-                /* REDIRECT */
                 tsrp->status = srv_busy;
+                if (fidp) { /* File Server query */
+                    code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, 
+                                             CM_GETVOL_FLAG_NO_LRU_UPDATE, 
+                                             &volp);
+                    if (code == 0) {
+                        if (fidp->volume == volp->rw.ID)
+                            statep = &volp->rw;
+                        else if (fidp->volume == volp->ro.ID)
+                            statep = &volp->ro;
+                        else if (fidp->volume == volp->bk.ID)
+                            statep = &volp->bk;
+                    }
+            
+                    cm_PutVolume(volp);
+                }
                 break;
             }
         }
         lock_ReleaseWrite(&cm_serverLock);
+        
+        if (statep)
+            cm_UpdateVolumeStatus(volp, statep->ID);
+        
         if (free_svr_list) {
             cm_FreeServerList(&serversp, 0);
             *serverspp = serversp;