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);
ViceLog(5,
("GSS: Delete longest inactive host %s\n",
afs_inet_ntoa_r(hp->host, hoststr)));
+
+ 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;
+ }
+
if (!(held = h_Held_r(hp)))
h_Hold_r(hp);
register struct host *host, **list;
register int *held;
register int i, count;
+ int totalCount;
H_LOCK;
if (hostCount == 0) {
ViceLog(0, ("Failed malloc in h_Enumerate\n"));
assert(0);
}
- for (count = 0, host = hostList; host && count < hostCount; host = host->next, count++) {
- list[count] = host;
- if (!(held[count] = h_Held_r(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;
+ if (!(held[count] = h_Held_r(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);
if (hostCount == 0) {
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;
+ }
+
if (enumstart && !(held = h_Held_r(enumstart)))
h_Hold_r(enumstart);
+
/* remember hostCount, lest it change over the potential H_LOCK drop in
* h_Release_r */
origHostCount = hostCount;
for (count = 0, host = enumstart; host && count < origHostCount; host = next, held = nheld, 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 && !(nheld = h_Held_r(next)))
h_Hold_r(next);
held = (*proc) (host, held, param);
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) {