server-list-refcount-20040804
authorJeffrey Altman <jaltman@mit.edu>
Wed, 4 Aug 2004 16:52:56 +0000 (16:52 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 4 Aug 2004 16:52:56 +0000 (16:52 +0000)
cm_GetVolServers must return a pointer to the pointer to the server list
so the volume can be updated when the list is freed

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

index bc7090f..d51e4e1 100644 (file)
@@ -97,8 +97,10 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
         else {
             dns_expired = 1;
             /* must empty cp->vlServersp */
+            lock_ObtainWrite(&cp->mx);
             cm_FreeServerList(&cp->vlServersp);
             cp->vlServersp = NULL;
+            lock_ReleaseWrite(&cp->mx);
         }
 
         code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
index fdb285e..90542fd 100644 (file)
@@ -97,15 +97,15 @@ void cm_InitReq(cm_req_t *reqp)
  
 }
 
-long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
-       struct cm_req *reqp, cm_serverRef_t **serverspp)
+static long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
+       struct cm_req *reqp, cm_serverRef_t ***serversppp)
 {
        long code;
     cm_volume_t *volp = NULL;
     cm_cell_t *cellp = NULL;
 
     if (!fidp) {
-               *serverspp = NULL;
+               *serversppp = NULL;
                return 0;
        }
 
@@ -115,7 +115,7 @@ long cm_GetServerList(struct cm_fid *fidp, struct cm_user *userp,
     code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp);
     if (code) return code;
     
-    *serverspp = cm_GetVolServers(volp, fidp->volume);
+    *serversppp = cm_GetVolServers(volp, fidp->volume);
 
     cm_PutVolume(volp);
        return 0;
@@ -145,6 +145,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
        cm_callbackRequest_t *cbrp, long errorCode)
 {
        cm_server_t *serverp;
+    cm_serverRef_t **serverspp = 0;
        cm_serverRef_t *tsrp;
        cm_ucell_t *ucellp;
     int retry = 0;
@@ -199,7 +200,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                 * flag and reset the busy state as well.
                 */
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serversp);
+            cm_GetServerList(fidp, userp, reqp, &serverspp);
+            serversp = *serverspp;
             free_svr_list = 1;
         }
         if (serversp) {
@@ -210,8 +212,10 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                     tsrp->status = not_busy;
             }
             lock_ReleaseWrite(&cm_serverLock);
-            if (free_svr_list)
+            if (free_svr_list) {
                 cm_FreeServerList(&serversp);
+                *serverspp = serversp;
+            }
             retry = 1;
         }
 
@@ -223,7 +227,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
     if (errorCode == CM_ERROR_ALLBUSY && timeLeft > 7) {
         thrd_Sleep(5000);
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serversp);
+            cm_GetServerList(fidp, userp, reqp, &serverspp);
+            serversp = *serverspp;
             free_svr_list = 1;
         }
                lock_ObtainWrite(&cm_serverLock);
@@ -232,15 +237,18 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                                tsrp->status = not_busy;
                }
         lock_ReleaseWrite(&cm_serverLock);
-        if (free_svr_list)
+        if (free_svr_list) {
             cm_FreeServerList(&serversp);
+            *serverspp = serversp;
+        }
                retry = 1;
        }
 
        /* special codes:  VBUSY and VRESTARTING */
        if (errorCode == VBUSY || errorCode == VRESTARTING) {
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serversp);
+            cm_GetServerList(fidp, userp, reqp, &serverspp);
+            serversp = *serverspp;
             free_svr_list = 1;
         }
                lock_ObtainWrite(&cm_serverLock);
@@ -252,8 +260,10 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
                        }
                }
         lock_ReleaseWrite(&cm_serverLock);
-        if (free_svr_list)
+        if (free_svr_list) {
             cm_FreeServerList(&serversp);
+            *serverspp = serversp;
+        }
                retry = 1;
        }
 
@@ -286,15 +296,18 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
 
                /* Mark server offline for this volume */
         if (!serversp) {
-            cm_GetServerList(fidp, userp, reqp, &serversp);
+            cm_GetServerList(fidp, userp, reqp, &serverspp);
+            serversp = *serverspp;
             free_svr_list = 1;
         }
                for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
                        if (tsrp->server == serverp)
                                tsrp->status = offline;
                }
-        if (free_svr_list)
+        if (free_svr_list) {
             cm_FreeServerList(&serversp);
+            *serverspp = serversp;
+        }
         if ( timeLeft > 2 )
                retry = 1;
        }
@@ -559,15 +572,15 @@ long cm_Conn(struct cm_fid *fidp, struct cm_user *userp, cm_req_t *reqp,
 {
        long code;
 
-       cm_serverRef_t *serversp;
+       cm_serverRef_t **serverspp;
 
-       code = cm_GetServerList(fidp, userp, reqp, &serversp);
+       code = cm_GetServerList(fidp, userp, reqp, &serverspp);
        if (code) {
                *connpp = NULL;
                return code;
        }
 
-       code = cm_ConnByMServers(serversp, userp, reqp, connpp);
-    cm_FreeServerList(&serversp);
+       code = cm_ConnByMServers(*serverspp, userp, reqp, connpp);
+    cm_FreeServerList(serverspp);
     return code;
 }
index 234e775..538a60c 100644 (file)
@@ -696,7 +696,7 @@ long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_scache_t *scp;
     cm_cell_t *cellp;
     cm_volume_t *tvp;
-       cm_serverRef_t *tsrp, *current;
+       cm_serverRef_t **tsrpp, *current;
     cm_server_t *tsp;
     unsigned long volume;
     char *cp;
@@ -720,15 +720,15 @@ long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp = ioctlp->outDatap;
         
        lock_ObtainMutex(&tvp->mx);
-       tsrp = cm_GetVolServers(tvp, volume);
+       tsrpp = cm_GetVolServers(tvp, volume);
        lock_ObtainRead(&cm_serverLock);
-       for (current = tsrp; current; current = current->next) {
+       for (current = *tsrpp; current; current = current->next) {
                tsp = current->server;
                memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
                cp += sizeof(long);
        }
        lock_ReleaseRead(&cm_serverLock);
-    cm_FreeServerList(&tsrp);
+    cm_FreeServerList(tsrpp);
     lock_ReleaseMutex(&tvp->mx);
 
        /* still room for terminating NULL, add it on */
index aa1ebd4..2e35b36 100644 (file)
@@ -303,27 +303,27 @@ void cm_ForceUpdateVolume(cm_fid_t *fidp, cm_user_t *userp, cm_req_t *reqp)
 }
 
 /* find the appropriate servers from a volume */
-cm_serverRef_t *cm_GetVolServers(cm_volume_t *volp, unsigned long volume)
+cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, unsigned long volume)
 {
-       cm_serverRef_t *serversp;
+       cm_serverRef_t **serverspp;
     cm_serverRef_t *current;;
 
     lock_ObtainWrite(&cm_serverLock);
 
        if (volume == volp->rwID)
-        serversp = volp->rwServersp;
+        serverspp = &volp->rwServersp;
        else if (volume == volp->roID)
-        serversp = volp->roServersp;
+        serverspp = &volp->roServersp;
        else if (volume == volp->bkID)
-        serversp = volp->bkServersp;
+        serverspp = &volp->bkServersp;
        else osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__);
         
-    for (current = serversp; current; current = current->next)
+    for (current = *serverspp; current; current = current->next)
         current->refCount++;
 
     lock_ReleaseWrite(&cm_serverLock);
 
-    return serversp;
+    return serverspp;
 }
 
 void cm_PutVolume(cm_volume_t *volp)
index d3f92e4..89547d7 100644 (file)
 
 typedef struct cm_volume {
        struct cm_cell *cellp;          /* never changes */
-        char *namep;                   /* by cm_volumeLock */
+    char *namep;                       /* by cm_volumeLock */
        unsigned long rwID;             /* by cm_volumeLock */
        unsigned long roID;             /* by cm_volumeLock */
        unsigned long bkID;             /* by cm_volumeLock */
-        struct cm_volume *nextp;       /* by cm_volumeLock */
+    struct cm_volume *nextp;   /* by cm_volumeLock */
        struct cm_fid *dotdotFidp;      /* parent of volume root */
-        osi_mutex_t mx;
-        long flags;                    /* by mx */
-        int refCount;                  /* by cm_volumeLock */
-        cm_serverRef_t *rwServersp;    /* by mx */
-        cm_serverRef_t *roServersp;    /* by mx */
-        cm_serverRef_t *bkServersp;    /* by mx */
+    osi_mutex_t mx;
+    long flags;                        /* by mx */
+    int refCount;                      /* by cm_volumeLock */
+    cm_serverRef_t *rwServersp;        /* by mx */
+    cm_serverRef_t *roServersp;        /* by mx */
+    cm_serverRef_t *bkServersp;        /* by mx */
 } cm_volume_t;
 
 #define CM_VOLUMEFLAG_RESET    1       /* reload this info on next use */
@@ -43,7 +43,7 @@ extern long cm_GetVolumeByID(struct cm_cell *cellp, long volumeID,
 extern void cm_ForceUpdateVolume(struct cm_fid *fidp, cm_user_t *userp,
        cm_req_t *reqp);
 
-extern cm_serverRef_t *cm_GetVolServers(cm_volume_t *volp, unsigned long volume);
+extern cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, unsigned long volume);
 
 extern void cm_ChangeRankVolume(cm_server_t *tsp);