ntohs(thishost->port)));
cb->status = CB_DELAYED;
} else {
- h_Hold_r(thishost);
- cba[ncbas].hp = thishost;
- cba[ncbas].thead = cb->thead;
- ncbas++;
+ if (!(thishost->hostFlags & HOSTDELETED)) {
+ h_Hold_r(thishost);
+ cba[ncbas].hp = thishost;
+ cba[ncbas].thead = cb->thead;
+ ncbas++;
+ }
TDel(cb);
HDel(cb);
CDel(cb, 1); /* Usually first; so this delete
register struct CallBack *cbnext;
for (cb = itocb(fe->firstcb); cb; cb = cbnext) {
host = h_itoh(cb->hhead);
- h_Hold_r(host);
- cbnext = itocb(cb->cnext);
- if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
- tthead = cb->thead;
+
+ if (!(host->hostFlags & HOSTDELETED)) {
+ h_Hold_r(host);
+ if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
+ tthead = cb->thead;
+ }
}
+ cbnext = itocb(cb->cnext);
TDel(cb);
HDel(cb);
FreeCB(cb);
cbnext = itocb(cb->cnext);
host = h_itoh(cb->hhead);
if (cb->status == CB_DELAYED) {
- h_Hold_r(host);
- if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
- tthead = cb->thead;
+ if (!(host->hostFlags & HOSTDELETED)) {
+ h_Hold_r(host);
+ if (!tthead || (TNorm(tthead) < TNorm(cb->thead))) {
+ tthead = cb->thead;
+ }
}
TDel(cb);
HDel(cb);
("GSS: Delete longest inactive host %p (%s:%d)\n",
hp, afs_inet_ntoa_r(hp->host, hoststr), ntohs(hp->port)));
+ if ((hp->hostFlags & HOSTDELETED)) {
+ /* hp could go away after reacquiring H_LOCK in h_NBLock_r, so we can't
+ * really use it; its callbacks will get cleared anyway when
+ * h_TossStuff_r gets its hands on it */
+ return 1;
+ }
+
h_Hold_r(hp);
/** Try a non-blocking lock. If the lock is already held return
register struct host *host, **list;
register int *flags;
register int i, count;
+ int totalCount;
H_LOCK;
if (hostCount == 0) {
ViceLog(0, ("Failed malloc in h_Enumerate (flags)\n"));
assert(0);
}
- for (count = 0, host = hostList; host && count < hostCount; host = host->next, count++) {
- list[count] = host;
- h_Hold_r(host);
+ for (totalCount = count = 0, host = hostList;
+ host && totalCount < hostCount;
+ host = host->next, totalCount++) {
+
+ if (!(host->hostFlags & HOSTDELETED)) {
+ list[count] = host;
+ h_Hold_r(host);
+ count++;
+ }
}
- if (count != hostCount) {
- ViceLog(0, ("h_Enumerate found %d of %d hosts\n", count, hostCount));
+ if (totalCount != hostCount) {
+ ViceLog(0, ("h_Enumerate found %d of %d hosts\n", totalCount, hostCount));
} else if (host != NULL) {
ViceLog(0, ("h_Enumerate found more than %d hosts\n", hostCount));
ShutDownAndCore(PANIC);
return;
}
+ host = enumstart;
+ enumstart = NULL;
+
+ /* find the first non-deleted host, so we know where to actually start
+ * enumerating */
+ for (count = 0; host && count < hostCount; count++) {
+ if (!(host->hostFlags & HOSTDELETED)) {
+ enumstart = host;
+ break;
+ }
+ host = host->next;
+ }
+ if (!enumstart) {
+ /* we didn't find a non-deleted host... */
+
+ if (host && count >= hostCount) {
+ /* ...because we found a loop */
+ ViceLog(0, ("h_Enumerate_r found more than %d hosts\n", hostCount));
+ ShutDownAndCore(PANIC);
+ }
+
+ /* ...because the hostList is full of deleted hosts */
+ return;
+ }
+
h_Hold_r(enumstart);
/* remember hostCount, lest it change over the potential H_LOCK drop in
for (count = 0, host = enumstart; host && count < origHostCount; host = next, flags = nflags, count++) {
next = host->next;
+
+ /* find the next non-deleted host */
+ while (next && (next->hostFlags & HOSTDELETED)) {
+ next = next->next;
+ /* inc count for the skipped-over host */
+ if (++count > origHostCount) {
+ ViceLog(0, ("h_Enumerate_r found more than %d hosts\n", origHostCount));
+ ShutDownAndCore(PANIC);
+ }
+ }
if (next && !H_ENUMERATE_ISSET_BAIL(flags))
h_Hold_r(next);
- flags = (*proc) (host, flags, param);
- if (H_ENUMERATE_ISSET_BAIL(flags)) {
- h_Release_r(host); /* this might free up the host */
- break;
+
+ if (!(host->hostFlags & HOSTDELETED)) {
+ flags = (*proc) (host, flags, param);
+ if (H_ENUMERATE_ISSET_BAIL(flags)) {
+ h_Release_r(host); /* this might free up the host */
+ break;
+ }
}
h_Release_r(host); /* this might free up the host */
}
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (client && client->sid == rxr_CidOf(tcon)
- && client->VenusEpoch == rxr_GetEpoch(tcon)) {
+ && client->VenusEpoch == rxr_GetEpoch(tcon)
+ && !(client->host->hostFlags & HOSTDELETED)) {
+
client->refCount++;
h_Hold_r(client->host);
if (!client->deleted && client->prfail != 2) {