From 306f75eb4cfe174da3ad7524320316109d75bd76 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 4 Aug 2004 16:52:56 +0000 Subject: [PATCH] server-list-refcount-20040804 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 | 2 ++ src/WINNT/afsd/cm_conn.c | 45 ++++++++++++++++++++++++-------------- src/WINNT/afsd/cm_ioctl.c | 8 +++---- src/WINNT/afsd/cm_volume.c | 14 ++++++------ src/WINNT/afsd/cm_volume.h | 18 +++++++-------- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index bc7090f65..d51e4e1da 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -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); diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index fdb285eb4..90542fdbd 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -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; } diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index 234e7755f..538a60c91 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -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 */ diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index aa1ebd43c..2e35b362c 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -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) diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index d3f92e499..89547d7f9 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -12,18 +12,18 @@ 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); -- 2.39.5