/* 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;
}
return tsvp;
}
+/*
+ * cm_NewServerRef() returns with the allocated cm_serverRef_t
+ * with a refCount of 1.
+ */
cm_serverRef_t *cm_NewServerRef(cm_server_t *serverp, afs_uint32 volID)
{
cm_serverRef_t *tsrp;
return tsrp;
}
+void cm_GetServerRef(cm_serverRef_t *tsrp, int locked)
+{
+ afs_int32 refCount;
+
+ if (!locked)
+ lock_ObtainRead(&cm_serverLock);
+ refCount = InterlockedIncrement(&tsrp->refCount);
+ if (!locked)
+ lock_ReleaseRead(&cm_serverLock);
+}
+
+afs_int32 cm_PutServerRef(cm_serverRef_t *tsrp, int locked)
+{
+ afs_int32 refCount;
+
+ if (!locked)
+ lock_ObtainRead(&cm_serverLock);
+ refCount = InterlockedDecrement(&tsrp->refCount);
+ osi_assertx(refCount >= 0, "cm_serverRef_t refCount underflow");
+
+ if (!locked)
+ lock_ReleaseRead(&cm_serverLock);
+
+ return refCount;
+}
+
+
+
LONG_PTR cm_ChecksumServerList(cm_serverRef_t *serversp)
{
LONG_PTR sum = 0;
** Insert a server into the server list keeping the list sorted in
** ascending order of ipRank.
**
-** The refCount of the cm_serverRef_t is increased
+** The refCount of the cm_serverRef_t is not altered.
*/
void cm_InsertServerList(cm_serverRef_t** list, cm_serverRef_t* element)
{
current=*list;
ipRank = element->server->ipRank;
- element->refCount++; /* increase refCount */
-
/* insertion into empty list or at the beginning of the list */
if ( !current || (current->server->ipRank > ipRank) )
{
}
element->next = current->next;
current->next = element;
+
lock_ReleaseWrite(&cm_serverLock);
}
/*
if ( (*current)->server == server)
{
element = (*current);
- *current = (*current)->next; /* delete it */
+ *current = element->next; /* delete it */
break;
}
current = & ( (*current)->next);
/* 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;
}
/*
cm_serverRef_t **current;
cm_serverRef_t **nextp;
cm_serverRef_t * next;
+ afs_int32 refCount;
lock_ObtainWrite(&cm_serverLock);
current = list;
while (*current)
{
nextp = &(*current)->next;
- if (--((*current)->refCount) == 0) {
+ refCount = cm_PutServerRef(*current, TRUE);
+ if (refCount == 0) {
next = *nextp;
if ((*current)->volID)
extern cm_serverRef_t *cm_NewServerRef(struct cm_server *serverp, afs_uint32 volID);
+extern void cm_GetServerRef(cm_serverRef_t *tsrp, int locked);
+
+extern afs_int32 cm_PutServerRef(cm_serverRef_t *tsrp, int locked);
+
extern LONG_PTR cm_ChecksumServerList(cm_serverRef_t *serversp);
extern void cm_GetServer(cm_server_t *);
tempAddr = htonl(serverNumber[i]);
tsockAddr.sin_addr.s_addr = tempAddr;
tsp = cm_FindServer(&tsockAddr, CM_SERVER_FILE);
+#ifdef MULTIHOMED
if (tsp && (method == 2) && (tsp->flags & CM_SERVERFLAG_UUID)) {
/*
* Check to see if the uuid of the server we know at this address
osi_LogSaveString(afsd_logp, hoststr));
}
}
+#endif
if (!tsp) {
/*
* cm_NewServer will probe the file server which in turn will
if ((tflags & VLSF_RWVOL) && (flags & VLF_RWEXISTS)) {
tsrp = cm_NewServerRef(tsp, rwID);
cm_InsertServerList(&volp->vol[RWVOL].serversp, tsrp);
-
- lock_ObtainWrite(&cm_serverLock);
- tsrp->refCount--; /* drop allocation reference */
- lock_ReleaseWrite(&cm_serverLock);
-
if (!(tsp->flags & CM_SERVERFLAG_DOWN))
rwServers_alldown = 0;
}
if ((tflags & VLSF_ROVOL) && (flags & VLF_ROEXISTS)) {
tsrp = cm_NewServerRef(tsp, roID);
cm_InsertServerList(&volp->vol[ROVOL].serversp, tsrp);
- lock_ObtainWrite(&cm_serverLock);
- tsrp->refCount--; /* drop allocation reference */
- lock_ReleaseWrite(&cm_serverLock);
ROcount++;
if (!(tsp->flags & CM_SERVERFLAG_DOWN))
if ((tflags & VLSF_RWVOL) && (flags & VLF_BACKEXISTS)) {
tsrp = cm_NewServerRef(tsp, bkID);
cm_InsertServerList(&volp->vol[BACKVOL].serversp, tsrp);
- lock_ObtainWrite(&cm_serverLock);
- tsrp->refCount--; /* drop allocation reference */
- lock_ReleaseWrite(&cm_serverLock);
if (!(tsp->flags & CM_SERVERFLAG_DOWN))
bkServers_alldown = 0;
* They will be freed by cm_FreeServerList when they get to zero
*/
for (current = *serverspp; current; current = current->next)
- current->refCount++;
+ cm_GetServerRef(current, TRUE);
lock_ReleaseWrite(&cm_serverLock);
*volumeUpdatedp = 1;
}
+ lock_ObtainRead(&cm_serverLock);
if (statep->serversp) {
alldown = 1;
alldeleted = 1;
if (serversp->status == srv_busy || serversp->status == srv_offline)
serversp->status = srv_not_busy;
}
+ lock_ReleaseRead(&cm_serverLock);
if (alldeleted && !(*volumeUpdatedp)) {
cm_InitReq(&req);
statep->state = vl_alldown;
}
} else if (statep->state != vl_alldown) {
+ lock_ReleaseRead(&cm_serverLock);
cm_VolumeStatusNotification(volp, statep->ID, statep->state, vl_alldown);
statep->state = vl_alldown;
}