if (code)
return code;
- *serversppp = cm_GetVolServers(volp, fidp->volume);
+ *serversppp = cm_GetVolServers(volp, fidp->volume, userp, reqp);
lock_ObtainRead(&cm_volumeLock);
cm_PutVolume(volp);
lock_ReleaseRead(&cm_volumeLock);
- return 0;
+ return (*serversppp ? 0 : CM_ERROR_NOSUCHVOLUME);
}
/*
reqp->tokenError = errorCode;
retry = 1;
}
+ } else if (errorCode >= ERROR_TABLE_BASE_U && errorCode < ERROR_TABLE_BASE_U + 256) {
+ /*
+ * We received a ubik error. its possible that the server we are
+ * communicating with has a corrupted database or is partitioned
+ * from the rest of the servers and another server might be able
+ * to answer our query. Therefore, we will retry the request
+ * and force the use of another server.
+ */
+ if (serverp) {
+ reqp->tokenIdleErrorServp = serverp;
+ reqp->tokenError = errorCode;
+ retry = 1;
+ }
} else if (errorCode == VICECONNBAD || errorCode == VICETOKENDEAD) {
cm_ForceNewConnections(serverp);
if ( timeLeft > 2 )
*connpp = NULL;
- serverspp = cm_GetVolServers(volp, volid);
+ serverspp = cm_GetVolServers(volp, volid, userp, reqp);
code = cm_ConnByMServers(*serverspp, userp, reqp, connpp);
cm_FreeServerList(serverspp, 0);
afs_int32
cm_IoctlWhereIs(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- afs_int32 code;
+ afs_int32 code = 0;
cm_cell_t *cellp;
cm_volume_t *tvp;
cm_serverRef_t **tsrpp, *current;
cp = ioctlp->outDatap;
- tsrpp = cm_GetVolServers(tvp, volume);
- lock_ObtainRead(&cm_serverLock);
- for (current = *tsrpp; current; current = current->next) {
- tsp = current->server;
- memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
- cp += sizeof(long);
+ tsrpp = cm_GetVolServers(tvp, volume, userp, reqp);
+ if (tsrpp == NULL) {
+ code = CM_ERROR_NOSUCHVOLUME;
+ } else {
+ lock_ObtainRead(&cm_serverLock);
+ 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(tsrpp, 0);
}
- lock_ReleaseRead(&cm_serverLock);
- cm_FreeServerList(tsrpp, 0);
-
/* still room for terminating NULL, add it on */
volume = 0; /* reuse vbl */
memcpy(cp, (char *)&volume, sizeof(long));
ioctlp->outDatap = cp;
cm_PutVolume(tvp);
}
- return 0;
+ return code;
}
/*
cm_DumpSCache(hLogFile, cookie, 1);
cm_DumpBufHashTable(hLogFile, cookie, 1);
smb_DumpVCP(hLogFile, cookie, 1);
+ rx_DumpCalls(hLogFile, cookie);
+ rx_DumpPackets(hLogFile, cookie);
CloseHandle(hLogFile);
}
/* find the appropriate servers from a volume */
-cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, afs_uint32 volume)
+cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, afs_uint32 volume, cm_user_t *userp, cm_req_t *reqp)
{
cm_serverRef_t **serverspp;
cm_serverRef_t *current;
+ int firstTry = 1;
+ start:
lock_ObtainWrite(&cm_serverLock);
if (volume == volp->vol[RWVOL].ID)
serverspp = &volp->vol[ROVOL].serversp;
else if (volume == volp->vol[BACKVOL].ID)
serverspp = &volp->vol[BACKVOL].serversp;
- else
- osi_panic("bad volume ID in cm_GetVolServers", __FILE__, __LINE__);
-
+ else {
+ lock_ReleaseWrite(&cm_serverLock);
+ if (firstTry) {
+ afs_int32 code;
+ firstTry = 0;
+ lock_ObtainWrite(&volp->rw);
+ volp->flags |= CM_VOLUMEFLAG_RESET;
+ code = cm_UpdateVolumeLocation(volp->cellp, userp, reqp, volp);
+ lock_ReleaseWrite(&volp->rw);
+ if (code == 0)
+ goto start;
+ }
+ return NULL;
+ }
+
/*
* Increment the refCount on deleted items as well.
* They will be freed by cm_FreeServerList when they get to zero
extern long cm_ForceUpdateVolume(struct cm_fid *fidp, cm_user_t *userp,
cm_req_t *reqp);
-extern cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, afs_uint32 volume);
+extern cm_serverRef_t **cm_GetVolServers(cm_volume_t *volp, afs_uint32 volume,
+ cm_user_t *userp, cm_req_t *reqp);
extern void cm_ChangeRankVolume(cm_server_t *tsp);