struct AFSCBs tc;
int code;
int j;
+ struct rx_connection *cb_conn = NULL;
#ifdef ADAPT_MTU
rx_SetConnDeadTime(ahost->callback_rxcon, 4);
tc.AFSCBs_len = i;
tc.AFSCBs_val = tcbs;
+ cb_conn = ahost->callback_rxcon;
+ rx_GetConnection(cb_conn);
H_UNLOCK;
- code |= RXAFSCB_CallBack(ahost->callback_rxcon, &tf, &tc);
+ code |= RXAFSCB_CallBack(cb_conn, &tf, &tc);
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
H_LOCK;
}
{
int i, j;
struct rx_connection *conns[MAX_CB_HOSTS];
- int opt_TO; /* secs, but internal adaptive parms are in ms */
static struct AFSCBs tc = { 0, 0 };
assert(ncbas <= MAX_CB_HOSTS);
if (!thishost || (thishost->hostFlags & HOSTDELETED)) {
continue;
}
+ rx_GetConnection(thishost->callback_rxcon);
conns[j++] = thishost->callback_rxcon;
#ifdef ADAPT_MTU
}
H_LOCK;
- h_Lock_r(hp);
+ h_Lock_r(hp);
hp->hostFlags |= VENUSDOWN;
/**
* We always go into AddCallBack1_r with the host locked
*/
AddCallBack1_r(hp, afidp->AFSCBFids_val, itot(idx),
CB_DELAYED, 1);
- h_Unlock_r(hp);
+ h_Unlock_r(hp);
H_UNLOCK;
}
}
for (i = 0; i < ncbas; i++) {
struct host *hp;
hp = cba[i].hp;
- if (hp && xhost != hp)
+ if (hp && xhost != hp) {
h_Release_r(hp);
+ }
+ }
+
+ /* H_UNLOCK around this so h_FreeConnection does not deadlock.
+ h_FreeConnection should *never* be called on a callback connection,
+ but on 10/27/04 a deadlock occurred where it was, when we know why,
+ this should be reverted. -- shadow */
+ H_UNLOCK;
+ for (i = 0; i < j; i++) {
+ rx_PutConnection(conns[i]);
}
+ H_LOCK;
return;
}
struct CallBack *cb, *nextcb;
struct cbstruct cba[MAX_CB_HOSTS];
int ncbas;
- struct rx_connection *conns[MAX_CB_HOSTS];
struct AFSCBFids tf;
int hostindex;
char hoststr[16];
h_Unlock_r(host);
H_UNLOCK;
ViceLog(8,
- ("DCB: No call backs for fid (%u, %u, %u)\n",
- fid->Volume, fid->Vnode, fid->Unique));
+ ("DCB: No call backs for fid (%u, %u, %u)\n", fid->Volume,
+ fid->Vnode, fid->Unique));
return 0;
}
pcb = FindCBPtr(fe, host);
if (!fe) {
H_UNLOCK;
ViceLog(8,
- ("DF: No fid (%u,%u,%u) to delete\n", fid->Volume,
- fid->Vnode, fid->Unique));
+ ("DF: No fid (%u,%u,%u) to delete\n", fid->Volume, fid->Vnode,
+ fid->Unique));
return 0;
}
for (n = 0, cbi = fe->firstcb; cbi; n++) {
u_byte thead[AFSCBMAX]; /* This should match thead in struct Callback */
int cbi, first, nfids;
struct CallBack *cb;
- struct interfaceAddr interf;
int code;
char hoststr[16];
+ struct rx_connection *cb_conn;
cbstuff.nbreakers++;
if (!(host->hostFlags & RESETDONE) && !(host->hostFlags & HOSTDELETED)) {
host->hostFlags &= ~ALTADDR; /* alterrnate addresses are invalid */
+ cb_conn = host->callback_rxcon;
+ rx_GetConnection(cb_conn);
if (host->interface) {
H_UNLOCK;
code =
- RXAFSCB_InitCallBackState3(host->callback_rxcon,
- &FS_HostUUID);
- H_LOCK;
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
} else {
H_UNLOCK;
- code = RXAFSCB_InitCallBackState(host->callback_rxcon);
- H_LOCK;
+ code = RXAFSCB_InitCallBackState(cb_conn);
}
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
host->hostFlags |= ALTADDR; /* alternate addresses are valid */
if (code) {
if (ShowProblems) {
#ifdef AFS_PTHREAD_ENV
assert(pthread_cond_broadcast(&fsync_cond) == 0);
#else
- LWP_NoYieldSignal(&fsync_wait);
+ LWP_NoYieldSignal(fsync_wait);
#endif
return 0;
}
/* Unchain first */
ViceLog(25, ("Looking for FileEntries to unchain\n"));
H_LOCK;
+ FSYNC_LOCK;
/* Pick the first volume we see to clean up */
fid.Volume = fid.Vnode = fid.Unique = 0;
for (feip = &HashTable[hash]; fe = itofe(*feip);) {
if (fe && (fe->status & FE_LATER)
&& (fid.Volume == 0 || fid.Volume == fe->volid)) {
+ /* Ugly, but used to avoid left side casting */
+ struct object *tmpfe;
ViceLog(125,
("Unchaining for %u:%u:%u\n", fe->vnode, fe->unique,
fe->volid));
fid.Volume = fe->volid;
*feip = fe->fnext;
/* Works since volid is deeper than the largest pointer */
- ((struct object *)fe)->next = (struct object *)myfe;
+ tmpfe = (struct object *)fe;
+ tmpfe->next = (struct object *)myfe;
myfe = fe;
} else
feip = &fe->fnext;
}
}
+ FSYNC_UNLOCK;
if (!myfe) {
H_UNLOCK;
}
/* loop over FEs from myfe and free/break */
- FSYNC_UNLOCK;
tthead = 0;
for (fe = myfe; fe;) {
register struct CallBack *cbnext;
henumParms.ncbas = 0;
}
}
- FSYNC_LOCK;
- H_UNLOCK;;
+ H_UNLOCK;
/* Arrange to be called again */
return 1;
H_LOCK;
CleanupTimedOutCallBacks_r();
H_UNLOCK;
+ return 0;
}
int
}
static struct host *lih_host;
+static int lih_host_held = 0;
static int
lih_r(register struct host *host, register int held,
register struct host *hostp)
{
+ lih_host_held = 0;
if (host->cblist
&& ((hostp && host != hostp) || (!held && !h_OtherHolds_r(host)))
&& (!lih_host || host->ActiveCall < lih_host->ActiveCall)) {
lih_host = host;
}
+ if (!held) {
+ held = 1;
+ lih_host_held = 1;
+ }
return held;
}
hp = lih_host;
if (hp) {
cbstuff.GSS4++;
- if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ ))
+ if (!ClearHostCallbacks_r(hp, 0 /* not locked or held */ )) {
+ if (lih_host_held)
+ h_Release_r(hp);
return 0;
+ }
+ if (lih_host_held)
+ h_Release_r(hp);
hp2 = hp->next;
} else {
hp2 = hostList;
static int
ClearHostCallbacks_r(struct host *hp, int locked)
{
- struct interfaceAddr interf;
int code;
int held = 0;
char hoststr[16];
+ struct rx_connection *cb_conn = NULL;
ViceLog(5,
("GSS: Delete longest inactive host %s\n",
} else {
/* host is up, try a call */
hp->hostFlags &= ~ALTADDR; /* alternate addresses are invalid */
+ cb_conn = hp->callback_rxcon;
+ rx_GetConnection(hp->callback_rxcon);
if (hp->interface) {
H_UNLOCK;
code =
- RXAFSCB_InitCallBackState3(hp->callback_rxcon, &FS_HostUUID);
- H_LOCK;
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
} else {
H_UNLOCK;
- code = RXAFSCB_InitCallBackState(hp->callback_rxcon);
- H_LOCK;
+ code = RXAFSCB_InitCallBackState(cb_conn);
}
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
hp->hostFlags |= ALTADDR; /* alternate addresses are valid */
if (code) {
/* failed, mark host down and need reset */