code = RXAFS_FetchStatus(connp->callp, &tfid,
&afsStatus, &callback, &volSync);
- } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync,
+ } while (cm_Analyze(connp, userp, reqp, &sfid, &volSync, NULL,
&cbr, code));
code = cm_MapRPCError(code, reqp);
osi_Log0(afsd_logp, "CALL FetchStatus DONE");
tsp->cellp = cellp;
}
else
- tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp);
+ tsp = cm_NewServer(addrp, CM_SERVER_VLDB, cellp);
/* Insert the vlserver into a sorted list, sorted by server rank */
tsrp = cm_NewServerRef(tsp);
cm_InsertServerList(&cellp->vlServersp, tsrp);
-
+ /* drop the allocation reference */
+ lock_ObtainWrite(&cm_serverLock);
+ tsrp->refCount--;
+ lock_ReleaseWrite(&cm_serverLock);
return 0;
}
struct cm_req *reqp, cm_serverRef_t **serverspp)
{
long code;
- cm_volume_t *volp = NULL;
- cm_serverRef_t *serversp = NULL;
- cm_cell_t *cellp = NULL;
+ cm_volume_t *volp = NULL;
+ cm_cell_t *cellp = NULL;
- if (!fidp) {
+ if (!fidp) {
*serverspp = NULL;
return 0;
}
cellp = cm_FindCellByID(fidp->cell);
- if (!cellp) return CM_ERROR_NOSUCHCELL;
+ if (!cellp) return CM_ERROR_NOSUCHCELL;
- code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp);
- if (code) return code;
-
- if (fidp->volume == volp->rwID)
- serversp = volp->rwServersp;
- else if (fidp->volume == volp->roID)
- serversp = volp->roServersp;
- else if (fidp->volume == volp->bkID)
- serversp = volp->bkServersp;
- else
- serversp = NULL;
-
- cm_PutVolume(volp);
- *serverspp = serversp;
+ code = cm_GetVolumeByID(cellp, fidp->volume, userp, reqp, &volp);
+ if (code) return code;
+
+ *serverspp = cm_GetVolServers(volp, fidp->volume);
+
+ cm_PutVolume(volp);
return 0;
}
*/
int
cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
- struct cm_fid *fidp,
- AFSVolSync *volSyncp, cm_callbackRequest_t *cbrp, long errorCode)
+ struct cm_fid *fidp,
+ AFSVolSync *volSyncp,
+ cm_serverRef_t * serversp,
+ cm_callbackRequest_t *cbrp, long errorCode)
{
cm_server_t *serverp;
- cm_serverRef_t *serversp, *tsrp;
+ cm_serverRef_t *tsrp;
cm_ucell_t *ucellp;
- int retry = 0;
+ int retry = 0;
+ int free_svr_list = 0;
int dead_session;
osi_Log2(afsd_logp, "cm_Analyze connp 0x%x, code %d",
serverp = connp->serverp;
/* Update callback pointer */
- if (cbrp && errorCode == 0) cbrp->serverp = connp->serverp;
+ if (cbrp && errorCode == 0)
+ cbrp->serverp = connp->serverp;
/* If not allowed to retry, don't */
if (reqp->flags & CM_REQ_NORETRY)
* the servers are marked as DOWN. So clear the DOWN
* flag and reset the busy state as well.
*/
- cm_GetServerList(fidp, userp, reqp, &serversp);
+ if (!serversp) {
+ cm_GetServerList(fidp, userp, reqp, &serversp);
+ free_svr_list = 1;
+ }
if (serversp) {
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsrp->status = not_busy;
}
lock_ReleaseWrite(&cm_serverLock);
-
+ if (free_svr_list)
+ cm_FreeServerList(&serversp);
retry = 1;
}
/* if all servers are busy, mark them non-busy and start over */
if (errorCode == CM_ERROR_ALLBUSY) {
- cm_GetServerList(fidp, userp, reqp, &serversp);
+ if (!serversp) {
+ cm_GetServerList(fidp, userp, reqp, &serversp);
+ free_svr_list = 1;
+ }
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (tsrp->status == busy)
tsrp->status = not_busy;
}
lock_ReleaseWrite(&cm_serverLock);
+ if (free_svr_list)
+ cm_FreeServerList(&serversp);
thrd_Sleep(5000);
retry = 1;
}
/* special codes: VBUSY and VRESTARTING */
if (errorCode == VBUSY || errorCode == VRESTARTING) {
- cm_GetServerList(fidp, userp, reqp, &serversp);
+ if (!serversp) {
+ cm_GetServerList(fidp, userp, reqp, &serversp);
+ free_svr_list = 1;
+ }
lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (tsrp->server == serverp
}
}
lock_ReleaseWrite(&cm_serverLock);
+ if (free_svr_list)
+ cm_FreeServerList(&serversp);
retry = 1;
}
}
/* Mark server offline for this volume */
- cm_GetServerList(fidp, userp, reqp, &serversp);
-
+ if (!serversp) {
+ cm_GetServerList(fidp, userp, reqp, &serversp);
+ free_svr_list = 1;
+ }
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (tsrp->server == serverp)
tsrp->status = offline;
}
+ if (free_svr_list)
+ cm_FreeServerList(&serversp);
retry = 1;
}
else if (errorCode >= -64 && errorCode < 0) {
/* mark server as down */
lock_ObtainMutex(&serverp->mx);
- serverp->flags |= CM_SERVERFLAG_DOWN;
+ serverp->flags |= CM_SERVERFLAG_DOWN;
lock_ReleaseMutex(&serverp->mx);
- retry = 1;
- }
+ retry = 1;
+ }
if (errorCode == RXKADEXPIRED && !dead_session) {
lock_ObtainMutex(&userp->mx);
{
long code;
cm_serverRef_t *tsrp;
- cm_server_t *tsp;
- long firstError = 0;
+ cm_server_t *tsp;
+ long firstError = 0;
int someBusy = 0, someOffline = 0, allBusy = 1, allDown = 1;
long timeUsed, timeLeft, hardTimeLeft;
#ifdef DJGPP
- struct timeval now;
+ struct timeval now;
#endif /* DJGPP */
- *connpp = NULL;
+ *connpp = NULL;
#ifndef DJGPP
timeUsed = (GetCurrentTime() - reqp->startTime) / 1000;
#else
- gettimeofday(&now, NULL);
- timeUsed = sub_time(now, reqp->startTime) / 1000;
+ gettimeofday(&now, NULL);
+ timeUsed = sub_time(now, reqp->startTime) / 1000;
#endif
/* leave 5 seconds margin of safety */
hardTimeLeft = HardDeadtimeout - timeUsed - 5;
lock_ObtainWrite(&cm_serverLock);
-
- for(tsrp = serversp; tsrp; tsrp=tsrp->next) {
+ for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
tsp->refCount++;
lock_ReleaseWrite(&cm_serverLock);
}
code = cm_ConnByMServers(serversp, userp, reqp, connpp);
- return code;
+ cm_FreeServerList(&serversp);
+ return code;
}
extern int cm_Analyze(cm_conn_t *connp, struct cm_user *up, struct cm_req *reqp,
struct cm_fid *fidp,
struct AFSVolSync *volInfop,
+ struct cm_serverRef_t * serversp,
struct cm_callbackRequest *cbrp, long code);
extern long cm_ConnByMServers(struct cm_serverRef *, struct cm_user *,
code = rx_EndCall(callp, code);
osi_Log0(afsd_logp, "CALL StoreData DONE");
- } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, code));
+ } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
/* now, clean up our state */
if (code == 0)
code = EndRXAFS_StoreData(callp, &outStatus, &volSync);
code = rx_EndCall(callp, code);
- } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, code));
+ } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
/* now, clean up our state */
osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY");
osi_Log0(afsd_logp, "CALL FetchData DONE");
- } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, code));
+ } while (cm_Analyze(connp, up, reqp, &scp->fid, &volSync, NULL, NULL, code));
fetchingcompleted:
code = cm_MapRPCError(code, reqp);
if (code) continue;
code = RXAFS_FetchACL(connp->callp, &fid, &acl, &fileStatus, &volSync);
- } while (cm_Analyze(connp, userp, &req, &scp->fid,
- &volSync, NULL, code));
+ } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, &req);
cm_ReleaseSCache(scp);
if (code) continue;
code = RXAFS_StoreACL(connp->callp, &fid, &acl, &fileStatus, &volSync);
- } while (cm_Analyze(connp, userp, &req, &scp->fid,
- &volSync, NULL, code));
+ } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, &req);
/* invalidate cache info, since we just trashed the ACL cache */
code = RXAFS_SetVolumeStatus(tcp->callp, scp->fid.volume,
&storeStat, volName, offLineMsg, motd);
- } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, code));
+ } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code));
code = cm_MapRPCError(code, &req);
/* return on failure */
code = RXAFS_GetVolumeStatus(tcp->callp, scp->fid.volume,
&volStat, &Name, &OfflineMsg, &MOTD);
- } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, code));
+ } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code));
code = cm_MapRPCError(code, &req);
cm_ReleaseSCache(scp);
long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
{
long code;
- cm_scache_t *scp;
- cm_cell_t *cellp;
- cm_volume_t *tvp;
- cm_serverRef_t *tsrp;
- cm_server_t *tsp;
- unsigned long volume;
- char *cp;
- cm_req_t req;
+ cm_scache_t *scp;
+ cm_cell_t *cellp;
+ cm_volume_t *tvp;
+ cm_serverRef_t *tsrp, *current;
+ cm_server_t *tsp;
+ unsigned long volume;
+ char *cp;
+ cm_req_t req;
cm_InitReq(&req);
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
- if (code) return code;
+ code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
+ if (code) return code;
volume = scp->fid.volume;
cellp = cm_FindCellByID(scp->fid.cell);
- osi_assert(cellp);
+ osi_assert(cellp);
- cm_ReleaseSCache(scp);
+ cm_ReleaseSCache(scp);
code = cm_GetVolumeByID(cellp, volume, userp, &req, &tvp);
- if (code) return code;
+ if (code) return code;
- cp = ioctlp->outDatap;
+ cp = ioctlp->outDatap;
lock_ObtainMutex(&tvp->mx);
tsrp = cm_GetVolServers(tvp, volume);
lock_ObtainRead(&cm_serverLock);
- while(tsrp) {
- tsp = tsrp->server;
+ for (current = tsrp; current; current = current->next) {
+ tsp = current->server;
memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
cp += sizeof(long);
- tsrp = tsrp->next;
}
lock_ReleaseRead(&cm_serverLock);
- lock_ReleaseMutex(&tvp->mx);
+ cm_FreeServerList(&tsrp);
+ lock_ReleaseMutex(&tvp->mx);
/* still room for terminating NULL, add it on */
volume = 0; /* reuse vbl */
long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
{
long whichCell;
- long magic = 0;
+ long magic = 0;
cm_cell_t *tcellp;
cm_serverRef_t *serverRefp;
- cm_server_t *serverp;
+ cm_server_t *serverp;
long i;
- char *cp;
- char *tp;
- char *basep;
+ char *cp;
+ char *tp;
+ char *basep;
cm_SkipIoctlPath(ioctlp);
memcpy((char *)&magic, tp, sizeof(long));
}
- lock_ObtainRead(&cm_cellLock);
+ lock_ObtainRead(&cm_cellLock);
for(tcellp = cm_allCellsp; tcellp; tcellp = tcellp->nextp) {
if (whichCell == 0) break;
whichCell--;
max = 13;
}
memset(cp, 0, max * sizeof(long));
- basep = cp;
+ basep = cp;
lock_ObtainRead(&cm_serverLock); /* for going down server list */
+ /* jaltman - do the reference counts to serverRefp contents need to be increased? */
serverRefp = tcellp->vlServersp;
for(i=0; i<max; i++) {
if (!serverRefp) break;
serverp = serverRefp->server;
memcpy(cp, &serverp->addr.sin_addr.s_addr, sizeof(long));
cp += sizeof(long);
- serverRefp = serverRefp->next;
+ serverRefp = serverRefp->next;
}
lock_ReleaseRead(&cm_serverLock);
cp = basep + max * sizeof(afs_int32);
{
char afspath[MAX_PATH];
char *submountreqp;
- int iteration;
int nextAutoSubmount;
HKEY hkSubmounts;
DWORD dwType, dwSize;
if (submountreqp && *submountreqp) {
char submountPathNormalized[MAX_PATH];
char submountPath[MAX_PATH];
- int submountPathLen;
dwSize = sizeof(submountPath);
status = RegQueryValueEx( hkSubmounts, submountreqp, 0,
lock_ReleaseWrite(&cm_serverLock);
}
+void cm_PutServerNoLock(cm_server_t *serverp)
+{
+ osi_assert(serverp->refCount-- > 0);
+}
+
void cm_SetServerPrefs(cm_server_t * serverp)
{
unsigned long serverAddr; /* in host byte order */
{
cm_serverRef_t *tsrp;
- lock_ObtainWrite(&cm_serverLock);
+ lock_ObtainWrite(&cm_serverLock);
serverp->refCount++;
- lock_ReleaseWrite(&cm_serverLock);
+ lock_ReleaseWrite(&cm_serverLock);
tsrp = malloc(sizeof(*tsrp));
tsrp->server = serverp;
tsrp->status = not_busy;
tsrp->next = NULL;
+ tsrp->refCount = 1;
return tsrp;
}
cm_serverRef_t *tsrp;
lock_ObtainWrite(&cm_serverLock);
-
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
if (first)
first = 0;
/*
** Insert a server into the server list keeping the list sorted in
** asending order of ipRank.
+**
+** The refCount of the cm_serverRef_t is increased
*/
void cm_InsertServerList(cm_serverRef_t** list, cm_serverRef_t* element)
{
unsigned short ipRank = element->server->ipRank;
lock_ObtainWrite(&cm_serverLock);
+ element->refCount++; /* increase refCount */
- /* insertion into empty list or at the beginning of the list */
+ /* insertion into empty list or at the beginning of the list */
if ( !current || (current->server->ipRank > ipRank) )
{
element->next = *list;
/* re-insert deleted element into the list with modified rank*/
cm_InsertServerList(list, element);
+
+ /* reduce refCount which was increased by cm_InsertServerList */
+ lock_ObtainWrite(&cm_serverLock);
+ element->refCount--;
+ lock_ReleaseWrite(&cm_serverLock);
return 0;
}
/*
while (current)
{
next = current->next;
- cm_FreeServer(current->server);
- free(current);
+ if (--current->refCount == 0) {
+ cm_FreeServer(current->server);
+ free(current);
+ }
current = next;
}
*/
typedef struct cm_server {
struct cm_server *allNextp; /* locked by cm_serverLock */
- struct sockaddr_in addr; /* by mx */
- int type; /* by mx */
+ struct sockaddr_in addr; /* by mx */
+ int type; /* by mx */
struct cm_conn *connsp; /* locked by cm_connLock */
- long flags; /* by mx */
- struct cm_cell *cellp; /* cell containing this server */
+ long flags; /* by mx */
+ struct cm_cell *cellp; /* cell containing this server */
int refCount; /* locked by cm_serverLock */
- osi_mutex_t mx;
+ osi_mutex_t mx;
unsigned short ipRank; /* server priority */
} cm_server_t;
enum repstate {not_busy, busy, offline};
typedef struct cm_serverRef {
- struct cm_serverRef *next;
- struct cm_server *server;
- enum repstate status;
+ struct cm_serverRef *next; /* locked by cm_serverLock */
+ struct cm_server *server; /* locked by cm_serverLock */
+ enum repstate status; /* locked by cm_serverLock */
+ int refCount; /* locked by cm_serverLock */
} cm_serverRef_t;
/* types */
extern void cm_PutServer(cm_server_t *);
+extern void cm_PutServerNoLock(cm_server_t *);
+
extern cm_server_t *cm_FindServer(struct sockaddr_in *addrp, int type);
extern osi_rwlock_t cm_serverLock;
code = RXAFS_RemoveFile(connp->callp, &afsFid, namep,
&newDirStatus, &volSync);
- } while (cm_Analyze(connp, userp, reqp,
- &dscp->fid, &volSync, NULL, code));
+ } while (cm_Analyze(connp, userp, reqp, &dscp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
lock_ObtainMutex(&dscp->mx);
&statStruct, &callbackStruct, &volSync);
} while (cm_Analyze(connp, userp, reqp, &dscp->fid,
- &volSync, &cbReq, code));
+ &volSync, NULL, &cbReq, code));
code = cm_MapRPCError(code, reqp);
osi_Log0(afsd_logp, "CALL BulkStatus DONE");
&afsInStatus, &afsOutStatus, &volSync);
} while (cm_Analyze(connp, userp, reqp,
- &scp->fid, &volSync, NULL, code));
+ &scp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
osi_Log1(afsd_logp, "CALL StoreStatus DONE, code %d", code);
&updatedDirStatus, &newFileCallback,
&volSync);
} while (cm_Analyze(connp, userp, reqp,
- &dscp->fid, &volSync, &cbReq, code));
+ &dscp->fid, &volSync, NULL, &cbReq, code));
code = cm_MapRPCError(code, reqp);
lock_ObtainMutex(&dscp->mx);
&updatedDirStatus, &newDirCallback,
&volSync);
} while (cm_Analyze(connp, userp, reqp,
- &dscp->fid, &volSync, &cbReq, code));
+ &dscp->fid, &volSync, NULL, &cbReq, code));
code = cm_MapRPCError(code, reqp);
lock_ObtainMutex(&dscp->mx);
&inStatus, &newAFSFid, &newLinkStatus,
&updatedDirStatus, &volSync);
} while (cm_Analyze(connp, userp, reqp,
- &dscp->fid, &volSync, NULL, code));
+ &dscp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
lock_ObtainMutex(&dscp->mx);
code = RXAFS_RemoveDir(connp->callp, &dirAFSFid, namep,
&updatedDirStatus, &volSync);
} while (cm_Analyze(connp, userp, reqp,
- &dscp->fid, &volSync, NULL, code));
+ &dscp->fid, &volSync, NULL, NULL, code));
code = cm_MapRPCErrorRmdir(code, reqp);
lock_ObtainMutex(&dscp->mx);
&updatedOldDirStatus, &updatedNewDirStatus,
&volSync);
} while (cm_Analyze(connp, userp, reqp, &oldDscp->fid,
- &volSync, NULL, code));
+ &volSync, NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
/* update the individual stat cache entries for the directories */
code = RXAFS_SetLock(connp->callp, &tfid, Which,
&volSync);
} while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync,
- NULL, code));
+ NULL, NULL, code));
lock_ObtainMutex(&scp->mx);
code = cm_MapRPCError(code, reqp);
}
break;
code = RXAFS_ReleaseLock(connp->callp, &tfid, &volSync);
} while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync,
- NULL, code));
+ NULL, NULL, code));
code = cm_MapRPCError(code, reqp);
lock_ObtainMutex(&scp->mx);
}
code = RXAFS_ExtendLock(connp->callp, &tfid,
&volSync);
} while (cm_Analyze(connp, fileLock->userp, &req,
- &fileLock->fid, &volSync, NULL,
+ &fileLock->fid, &volSync, NULL, NULL,
code));
code = cm_MapRPCError(code, &req);
lock_ObtainWrite(&cm_scacheLock);
&volSync);
} while (cm_Analyze(connp, oldFileLock->userp, &req,
&oldFileLock->fid, &volSync,
- NULL, code));
+ NULL, NULL, code));
code = cm_MapRPCError(code, &req);
}
long code;
/* clear out old bindings */
- while (tsrp = volp->rwServersp) {
- volp->rwServersp = tsrp->next;
- cm_PutServer(tsrp->server);
- free(tsrp);
- }
- while (tsrp = volp->roServersp) {
- volp->roServersp = tsrp->next;
- cm_PutServer(tsrp->server);
- free(tsrp);
- }
- while (tsrp = volp->bkServersp) {
- volp->bkServersp = tsrp->next;
- cm_PutServer(tsrp->server);
- free(tsrp);
- }
+ cm_FreeServerList(&volp->rwServersp);
+ cm_FreeServerList(&volp->roServersp);
+ cm_FreeServerList(&volp->bkServersp);
/* now we have volume structure locked and held; make RPC to fill it */
do {
osi_Log1(afsd_logp, "CALL VL_GetEntryByNameO name %s",
volp->namep);
code = VL_GetEntryByNameO(connp->callp, volp->namep, &vldbEntry);
- } while (cm_Analyze(connp, userp, reqp, NULL, NULL, NULL, code));
+ } while (cm_Analyze(connp, userp, reqp, NULL, NULL, cellp->vlServersp, NULL, code));
code = cm_MapVLRPCError(code, reqp);
if (code == 0) {
if ((tflags & VLSF_RWVOL)
&& (vldbEntry.flags & VLF_RWEXISTS)) {
tsrp = cm_NewServerRef(tsp);
- tsrp->next = volp->rwServersp;
- volp->rwServersp = tsrp;
+ cm_InsertServerList(&volp->rwServersp, tsrp);
+ lock_ObtainWrite(&cm_serverLock);
+ tsrp->refCount--; /* drop allocation reference */
+ lock_ReleaseWrite(&cm_serverLock);
}
if ((tflags & VLSF_ROVOL)
&& (vldbEntry.flags & VLF_ROEXISTS)) {
tsrp = cm_NewServerRef(tsp);
cm_InsertServerList(&volp->roServersp, tsrp);
+ lock_ObtainWrite(&cm_serverLock);
+ tsrp->refCount--; /* drop allocation reference */
+ lock_ReleaseWrite(&cm_serverLock);
ROcount++;
}
/* We don't use VLSF_BACKVOL !?! */
if ((tflags & VLSF_RWVOL)
&& (vldbEntry.flags & VLF_BACKEXISTS)) {
tsrp = cm_NewServerRef(tsp);
- tsrp->next = volp->bkServersp;
- volp->bkServersp = tsrp;
+ cm_InsertServerList(&volp->bkServersp, tsrp);
+ lock_ObtainWrite(&cm_serverLock);
+ tsrp->refCount--; /* drop allocation reference */
+ lock_ReleaseWrite(&cm_serverLock);
}
/* Drop the reference obtained by cm_FindServer() */
cm_PutServer(tsp);
cm_serverRef_t *cm_GetVolServers(cm_volume_t *volp, unsigned long volume)
{
cm_serverRef_t *serversp;
+ cm_serverRef_t *current;;
+
+ lock_ObtainWrite(&cm_serverLock);
if (volume == volp->rwID)
- serversp = volp->rwServersp;
+ serversp = volp->rwServersp;
else if (volume == volp->roID)
- serversp = volp->roServersp;
+ serversp = volp->roServersp;
else if (volume == volp->bkID)
- serversp = volp->bkServersp;
+ serversp = volp->bkServersp;
else osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__);
- return serversp;
+ for (current = serversp; current; current = current->next)
+ current->refCount++;
+
+ lock_ReleaseWrite(&cm_serverLock);
+
+ return serversp;
}
void cm_PutVolume(cm_volume_t *volp)