static int
VLDB_Same(struct VenusFid *afid, struct vrequest *areq)
{
- struct vrequest treq;
+ struct vrequest *treq = NULL;
struct afs_conn *tconn;
int i, type = 0;
union {
AFS_STATCNT(CheckVLDB);
afs_FinalizeReq(areq);
- if ((i = afs_InitReq(&treq, afs_osi_credp)))
+ if ((i = afs_CreateReq(&treq, afs_osi_credp)))
return DUNNO;
v = afs_osi_Alloc(sizeof(*v));
osi_Assert(v != NULL);
VSleep(2); /* Better safe than sorry. */
tconn =
afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, tcell->cellNum,
- &treq, SHARED_LOCK, 0, &rxconn);
+ treq, SHARED_LOCK, 0, &rxconn);
if (tconn) {
if ( tconn->parent->srvr->server->flags & SNO_LHOSTS) {
type = 0;
}
} else
i = -1;
- } while (afs_Analyze(tconn, rxconn, i, NULL, &treq, -1, /* no op code for this */
+ } while (afs_Analyze(tconn, rxconn, i, NULL, treq, -1, /* no op code for this */
SHARED_LOCK, tcell));
afs_PutCell(tcell, READ_LOCK);
ICL_TYPE_INT32, i);
if (i) {
+ afs_DestroyReq(treq);
afs_osi_Free(v, sizeof(*v));
return DUNNO;
}
ReleaseWriteLock(&tvp->lock);
if (type == 2) {
- LockAndInstallUVolumeEntry(tvp, &v->utve, afid->Cell, tcell, &treq);
+ LockAndInstallUVolumeEntry(tvp, &v->utve, afid->Cell, tcell, treq);
} else if (type == 1) {
LockAndInstallNVolumeEntry(tvp, &v->ntve, afid->Cell);
} else {
ReleaseWriteLock(&tvp->lock);
afs_PutVolume(tvp, WRITE_LOCK);
} else { /* can't find volume */
- tvp = afs_GetVolume(afid, &treq, WRITE_LOCK);
+ tvp = afs_GetVolume(afid, treq, WRITE_LOCK);
if (tvp) {
afs_PutVolume(tvp, WRITE_LOCK);
+ afs_DestroyReq(treq);
afs_osi_Free(v, sizeof(*v));
return DIFFERENT;
} else {
+ afs_DestroyReq(treq);
afs_osi_Free(v, sizeof(*v));
return DUNNO;
}
}
+ afs_DestroyReq(treq);
afs_osi_Free(v, sizeof(*v));
return (changed ? DIFFERENT : SAME);
} /*VLDB_Same */
tvp = afs_FindVolume(afid, READ_LOCK);
if (tvp) {
for (i = 0; i < AFS_MAXHOSTS; i++) {
- if (tvp->serverHost[i]) {
+ if (areq->lasterror[i] && tvp->serverHost[i]) {
sa = tvp->serverHost[i]->addr;
if (sa) {
address = ntohl(sa->sa_ip);
* actions are necessary.
*
* \param[in] aconn Ptr to the relevant connection on which the call was made.
+ * \param[in] rxconn Ptr to the rx_connection.
* \param[in] acode The return code experienced by the RPC.
* \param[in] fid The FID of the file involved in the action. This argument
* may be null if none was involved.
afs_PutVolume(tvp, READ_LOCK);
}
- /* If network troubles, mark server as having bogued out again. */
- /* VRESTARTING is < 0 because of backward compatibility issues
- * with 3.4 file servers and older cache managers */
#ifdef AFS_64BIT_CLIENT
if (acode == -455)
acode = 455;
#endif /* AFS_64BIT_CLIENT */
- if ((acode < 0) && (acode != VRESTARTING)) {
- if (acode == RX_MSGSIZE || acode == RX_CALL_BUSY) {
+ if (acode == RX_MSGSIZE) {
+ shouldRetry = 1;
+ goto out;
+ }
+ if (acode == RX_CALL_TIMEOUT || acode == VNOSERVICE) {
+ serversleft = afs_BlackListOnce(areq, afid, tsp);
+ if (afid)
+ tvp = afs_FindVolume(afid, READ_LOCK);
+ if ((serversleft == 0) && tvp &&
+ ((tvp->states & VRO) || (tvp->states & VBackup))) {
+ shouldRetry = 0;
+ } else {
shouldRetry = 1;
- goto out;
}
- if (acode == RX_CALL_TIMEOUT || acode == RX_CALL_IDLE) {
- serversleft = afs_BlackListOnce(areq, afid, tsp);
- if (afid)
- tvp = afs_FindVolume(afid, READ_LOCK);
- if ((serversleft == 0) && tvp &&
- ((tvp->states & VRO) || (tvp->states & VBackup))) {
- shouldRetry = 0;
- } else {
- shouldRetry = 1;
- }
- if (!afid || !tvp || (tvp->states & VRO))
- areq->idleError++;
- else if (afs_ClearStatus(afid, op, tvp) == 0)
- shouldRetry = 0;
+ if (!afid || !tvp || (tvp->states & VRO))
+ areq->idleError++;
+ else if (afs_ClearStatus(afid, op, tvp) == 0)
+ shouldRetry = 0;
- if (tvp)
- afs_PutVolume(tvp, READ_LOCK);
- /* By doing this, we avoid ever marking a server down
- * in an idle timeout case. That's because the server is
- * still responding and may only be letting a single vnode
- * time out. We otherwise risk having the server continually
- * be marked down, then up, then down again...
- */
- goto out;
- }
- afs_ServerDown(sa, acode);
+ if (tvp)
+ afs_PutVolume(tvp, READ_LOCK);
+ /* By doing this, we avoid ever marking a server down
+ * in an idle timeout case. That's because the server is
+ * still responding and may only be letting a single vnode
+ * time out. We otherwise risk having the server continually
+ * be marked down, then up, then down again...
+ */
+ goto out;
+ }
+ /* If network troubles, mark server as having bogued out again. */
+ /* VRESTARTING is < 0 because of backward compatibility issues
+ * with 3.4 file servers and older cache managers */
+ if ((acode < 0) && (acode != VRESTARTING)) {
+ afs_ServerDown(sa, acode, rxconn);
ForceNewConnections(sa); /* multi homed clients lock:afs_xsrvAddr? */
if (aerrP)
(aerrP->err_Server)++;
}
/* check for ubik errors; treat them like crashed servers */
else if (acode >= ERROR_TABLE_BASE_U && acode < ERROR_TABLE_BASE_U + 255) {
- afs_ServerDown(sa, acode);
+ afs_ServerDown(sa, acode, rxconn);
if (aerrP)
(aerrP->err_Server)++;
shouldRetry = 1; /* retryable (maybe one is working) */
}
/* Check for bad volume data base / missing volume. */
else if (acode == VSALVAGE || acode == VOFFLINE || acode == VNOVOL
- || acode == VNOSERVICE || acode == VMOVED) {
+ || acode == VMOVED) {
struct cell *tcell;
int same;
* retry in case there is another server. However, if we find
* no connection (aconn == 0) we set the networkError flag.
*/
- afs_ServerDown(sa, acode);
+ afs_ServerDown(sa, acode, rxconn);
if (aerrP)
(aerrP->err_Server)++;
VSleep(1); /* Just a hack for desperate times. */