int
InitCallBack(int nblks)
{
- H_LOCK tfirst = CBtime(FT_ApproxTime());
+ H_LOCK;
+ tfirst = CBtime(FT_ApproxTime());
/* N.B. The "-1", below, is because
* FE[0] and CB[0] are not used--and not allocated */
FE = ((struct FileEntry *)(calloc(nblks, sizeof(struct FileEntry)))) - 1;
FreeCB(&CB[cbstuff.nCBs]); /* This is correct */
cbstuff.nblks = nblks;
cbstuff.nbreakers = 0;
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
afs_int32
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;
- H_UNLOCK code |= RXAFSCB_CallBack(ahost->callback_rxcon, &tf, &tc);
- H_LOCK}
+ cb_conn = ahost->callback_rxcon;
+ rx_GetConnection(cb_conn);
+ H_UNLOCK;
+ code |= RXAFSCB_CallBack(cb_conn, &tf, &tc);
+ rx_PutConnection(cb_conn);
+ cb_conn = NULL;
+ H_LOCK;
+ }
return code;
}
int locked)
{
int retVal;
- H_LOCK if (!locked) {
+ H_LOCK;
+ if (!locked) {
h_Lock_r(host);
}
retVal = AddCallBack1_r(host, fid, thead, type, 1);
if (!locked) {
h_Unlock_r(host);
}
- H_UNLOCK return retVal;
+ H_UNLOCK;
+ return retVal;
}
static int
{
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
if (j) { /* who knows what multi would do with 0 conns? */
cbstuff.nbreakers++;
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_CallBack(afidp, &tc);
if (multi_error) {
afs_uint32 idx;
ntohs(hp->port)));
}
- H_LOCK h_Lock_r(hp);
+ H_LOCK;
+ 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}
+ h_Unlock_r(hp);
+ H_UNLOCK;
+ }
}
}
}
multi_End;
- H_LOCK cbstuff.nbreakers--;
+ H_LOCK;
+ cbstuff.nbreakers--;
}
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];
afs_inet_ntoa_r(xhost->host, hoststr), ntohs(xhost->port),
fid->Volume, fid->Vnode, fid->Unique));
- H_LOCK cbstuff.BreakCallBacks++;
+ H_LOCK;
+ cbstuff.BreakCallBacks++;
fe = FindFE(fid);
if (!fe) {
goto done;
}
done:
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/* Delete (do not break) single call back for fid */
cbstuff.DeleteCallBacks++;
- H_LOCK h_Lock_r(host);
+ H_LOCK;
+ h_Lock_r(host);
fe = FindFE(fid);
if (!fe) {
h_Unlock_r(host);
- H_UNLOCK ViceLog(8,
- ("DCB: No call backs for fid (%u, %u, %u)\n",
- fid->Volume, fid->Vnode, fid->Unique));
+ H_UNLOCK;
+ ViceLog(8,
+ ("DCB: No call backs for fid (%u, %u, %u)\n", fid->Volume,
+ fid->Vnode, fid->Unique));
return 0;
}
pcb = FindCBPtr(fe, host);
afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
fid->Volume, fid->Vnode, fid->Unique));
h_Unlock_r(host);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
HDel(itocb(*pcb));
TDel(itocb(*pcb));
CDelPtr(fe, pcb, 1);
h_Unlock_r(host);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/*
register afs_uint32 cbi;
register int n;
- H_LOCK cbstuff.DeleteFiles++;
+ H_LOCK;
+ cbstuff.DeleteFiles++;
fe = FindFE(fid);
if (!fe) {
- H_UNLOCK ViceLog(8,
- ("DF: No fid (%u,%u,%u) to delete\n", fid->Volume,
- fid->Vnode, fid->Unique));
+ H_UNLOCK;
+ ViceLog(8,
+ ("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++) {
FreeCB(cb);
}
FDel(fe);
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
/* Delete (do not break) all call backs for host. The host should be
BreakDelayedCallBacks(struct host *host)
{
int retVal;
- H_LOCK retVal = BreakDelayedCallBacks_r(host);
- H_UNLOCK return retVal;
+ H_LOCK;
+ retVal = BreakDelayedCallBacks_r(host);
+ H_UNLOCK;
+ return retVal;
}
int
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} else {
- H_UNLOCK code = RXAFSCB_InitCallBackState(host->callback_rxcon);
- H_LOCK}
+ H_UNLOCK;
+ code =
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
+ } else {
+ H_UNLOCK;
+ 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) {
struct VCBParams *parms)
{
int retval;
- H_LOCK retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
- H_UNLOCK return retval;
+ H_LOCK;
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
+ H_UNLOCK;
+ return retval;
}
/*
struct VCBParams *parms)
{
int retval;
- H_LOCK retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
- H_UNLOCK return retval;
+ H_LOCK;
+ retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
+ H_UNLOCK;
+ return retval;
}
/*
struct VCBParams henumParms;
afs_uint32 tthead = 0; /* zero is illegal value */
- H_LOCK fid.Volume = volume, fid.Vnode = fid.Unique = 0;
+ H_LOCK;
+ fid.Volume = volume, fid.Vnode = fid.Unique = 0;
for (hash = 0; hash < VHASH; hash++) {
for (feip = &HashTable[hash]; (fe = itofe(*feip));) {
if (fe->volid == volume) {
if (!tthead) {
/* didn't find any callbacks, so return right away. */
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
henumParms.ncbas = 0;
henumParms.fid = &fid;
henumParms.thead = tthead;
- H_UNLOCK h_Enumerate(MultiBreakVolumeCallBack, (char *)&henumParms);
- H_LOCK if (henumParms.ncbas) { /* do left-overs */
+ H_UNLOCK;
+ h_Enumerate(MultiBreakVolumeCallBack, (char *)&henumParms);
+ H_LOCK;
+ if (henumParms.ncbas) { /* do left-overs */
struct AFSCBFids tf;
tf.AFSCBFids_len = 1;
tf.AFSCBFids_val = &fid;
henumParms.ncbas = 0;
}
- H_UNLOCK return 0;
+ H_UNLOCK;
+ return 0;
}
#ifdef AFS_PTHREAD_ENV
int found = 0;
ViceLog(25, ("Setting later on volume %u\n", volume));
- H_LOCK for (hash = 0; hash < VHASH; hash++) {
+ H_LOCK;
+ for (hash = 0; hash < VHASH; hash++) {
for (feip = &HashTable[hash]; fe = itofe(*feip);) {
if (fe->volid == volume) {
register struct CallBack *cbnext;
cb->status = CB_DELAYED;
cbnext = itocb(cb->cnext);
}
- FSYNC_LOCK fe->status |= FE_LATER;
- FSYNC_UNLOCK found++;
+ FSYNC_LOCK;
+ fe->status |= FE_LATER;
+ FSYNC_UNLOCK;
+ found++;
}
feip = &fe->fnext;
}
}
- H_UNLOCK if (!found) {
+ H_UNLOCK;
+ if (!found) {
/* didn't find any callbacks, so return right away. */
return 0;
}
#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
- /* Pick the first volume we see to clean up */
- fid.Volume = fid.Vnode = fid.Unique = 0;
+ H_LOCK;
+ FSYNC_LOCK;
+ /* Pick the first volume we see to clean up */
+ fid.Volume = fid.Vnode = fid.Unique = 0;
for (hash = 0; hash < VHASH; hash++) {
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 return 0;
+ H_UNLOCK;
+ return 0;
}
/* loop over FEs from myfe and free/break */
- FSYNC_UNLOCK tthead = 0;
+ tthead = 0;
for (fe = myfe; fe;) {
register struct CallBack *cbnext;
for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
henumParms.ncbas = 0;
henumParms.fid = &fid;
henumParms.thead = tthead;
- H_UNLOCK h_Enumerate(MultiBreakVolumeLaterCallBack,
- (char *)&henumParms);
- H_LOCK if (henumParms.ncbas) { /* do left-overs */
+ H_UNLOCK;
+ h_Enumerate(MultiBreakVolumeLaterCallBack, (char *)&henumParms);
+ H_LOCK;
+ if (henumParms.ncbas) { /* do left-overs */
struct AFSCBFids tf;
tf.AFSCBFids_len = 1;
tf.AFSCBFids_val = &fid;
henumParms.ncbas = 0;
}
}
- FSYNC_LOCK H_UNLOCK
- /* Arrange to be called again */
- return 1;
+ H_UNLOCK;
+
+ /* Arrange to be called again */
+ return 1;
}
/*
int
CleanupTimedOutCallBacks(void)
{
- H_LOCK CleanupTimedOutCallBacks_r();
-H_UNLOCK}
+ H_LOCK;
+ CleanupTimedOutCallBacks_r();
+ H_UNLOCK;
+ return 0;
+}
int
CleanupTimedOutCallBacks_r(void)
}
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} else {
- H_UNLOCK code = RXAFSCB_InitCallBackState(hp->callback_rxcon);
- H_LOCK}
+ H_UNLOCK;
+ code =
+ RXAFSCB_InitCallBackState3(cb_conn, &FS_HostUUID);
+ } else {
+ H_UNLOCK;
+ 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 */
MultiBreakCallBackAlternateAddress(struct host *host, struct AFSCBFids *afidp)
{
int retVal;
- H_LOCK retVal = MultiBreakCallBackAlternateAddress_r(host, afidp);
- H_UNLOCK return retVal;
+ H_LOCK;
+ retVal = MultiBreakCallBackAlternateAddress_r(host, afidp);
+ H_UNLOCK;
+ return retVal;
}
int
ViceLog(125,
("Starting multibreakcall back on all addr for host %s\n",
afs_inet_ntoa_r(host->host, hoststr)));
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_CallBack(afidp, &tc);
if (!multi_error) {
/* first success */
- H_LOCK if (host->callback_rxcon)
- rx_DestroyConnection(host->callback_rxcon);
+ H_LOCK;
+ if (host->callback_rxcon)
+ rx_DestroyConnection(host->callback_rxcon);
host->callback_rxcon = conns[multi_i];
host->host = addr[multi_i];
connSuccess = conns[multi_i];
ViceLog(125,
("multibreakcall success with addr %s\n",
afs_inet_ntoa_r(addr[multi_i], hoststr)));
- H_UNLOCK multi_Abort;
+ H_UNLOCK;
+ multi_Abort;
}
}
multi_End_Ignore;
- H_LOCK
- /* Destroy all connections except the one on which we succeeded */
- for (i = 0; i < j; i++)
+ H_LOCK;
+ /* Destroy all connections except the one on which we succeeded */
+ for (i = 0; i < j; i++)
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);
ViceLog(125,
("Starting multiprobe on all addr for host %s\n",
afs_inet_ntoa_r(host->host, hoststr)));
- H_UNLOCK multi_Rx(conns, j) {
+ H_UNLOCK;
+ multi_Rx(conns, j) {
multi_RXAFSCB_ProbeUuid(&host->interface->uuid);
if (!multi_error) {
/* first success */
- H_LOCK if (host->callback_rxcon)
- rx_DestroyConnection(host->callback_rxcon);
+ H_LOCK;
+ if (host->callback_rxcon)
+ rx_DestroyConnection(host->callback_rxcon);
host->callback_rxcon = conns[multi_i];
host->host = addr[multi_i];
connSuccess = conns[multi_i];
ViceLog(125,
("multiprobe success with addr %s\n",
afs_inet_ntoa_r(addr[multi_i], hoststr)));
- H_UNLOCK multi_Abort;
+ H_UNLOCK;
+ multi_Abort;
}
}
multi_End_Ignore;
- H_LOCK
- /* Destroy all connections except the one on which we succeeded */
- for (i = 0; i < j; i++)
+ H_LOCK;
+ /* Destroy all connections except the one on which we succeeded */
+ for (i = 0; i < j; i++)
if (conns[i] != connSuccess)
rx_DestroyConnection(conns[i]);