callback-rxcon-use-safely-20041108
[openafs.git] / src / viced / callback.c
index 65e3be2..cd90063 100644 (file)
@@ -572,6 +572,7 @@ XCallBackBulk_r(struct host * ahost, struct AFSFid * fids, afs_int32 nfids)
     struct AFSCBs tc;
     int code;
     int j;
+    struct rx_connection *cb_conn = NULL;
 
 #ifdef ADAPT_MTU
     rx_SetConnDeadTime(ahost->callback_rxcon, 4);
@@ -594,8 +595,12 @@ XCallBackBulk_r(struct host * ahost, struct AFSFid * fids, afs_int32 nfids)
        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;
     }
 
@@ -776,6 +781,7 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
        if (!thishost || (thishost->hostFlags & HOSTDELETED)) {
            continue;
        }
+       rx_GetConnection(thishost->callback_rxcon);
        conns[j++] = thishost->callback_rxcon;
 
 #ifdef ADAPT_MTU
@@ -832,14 +838,14 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
                        }
 
                        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;
                    }
                }
@@ -853,9 +859,20 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
     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;
 }
@@ -1073,21 +1090,24 @@ BreakDelayedCallBacks_r(struct host *host)
     struct CallBack *cb;
     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) {
@@ -1623,6 +1643,7 @@ ClearHostCallbacks_r(struct host *hp, int locked)
     int code;
     int held = 0;
     char hoststr[16];
+    struct rx_connection *cb_conn = NULL;
 
     ViceLog(5,
            ("GSS: Delete longest inactive host %s\n",
@@ -1658,16 +1679,19 @@ ClearHostCallbacks_r(struct host *hp, int locked)
     } 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 */