windows-revoke-callback-20070619
[openafs.git] / src / WINNT / afsd / cm_callback.c
index 23bcd26..1b694ec 100644 (file)
 #include <afs/afs_args.h>
 #include <afs/stds.h>
 
-#ifndef DJGPP
 #include <windows.h>
 #include <winsock2.h>
-#else
-#include <sys/socket.h>
-#endif /* !DJGPP */
 #include <malloc.h>
 #include <string.h>
 #include <stdlib.h>
 
+#include "afsd.h"
 #include <osi.h>
 #include <rx_pthread.h>
 
-#include "afsd.h"
 #include <WINNT/syscfg.h>
 #include <WINNT/afsreg.h>
 #include <../afsrdr/kif.h>
@@ -125,7 +121,7 @@ void cm_CallbackNotifyChange(cm_scache_t *scp)
         Sleep(dwDelay);
 
     /* for directories, this sends a change notification on the dir itself */
-       if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
+    if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
 #ifndef AFSIFS
         if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
             smb_NotifyChange(0,
@@ -149,7 +145,7 @@ void cm_CallbackNotifyChange(cm_scache_t *scp)
              dscp->flags & CM_SCACHEFLAG_ANYWATCH )
             smb_NotifyChange( 0,
                               FILE_NOTIFY_GENERIC_FILE_FILTER,
-                              dscp,   NULL, NULL, TRUE);
+                              dscp, NULL, NULL, TRUE);
 #else
         if (dscp)
             dc_break_callback(FID_HASH_FN(&dscp->fid));
@@ -165,7 +161,7 @@ void cm_CallbackNotifyChange(cm_scache_t *scp)
  *
  * The callp parameter is currently unused.
  */
-void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp)
+void cm_RevokeCallback(struct rx_call *callp, cm_cell_t * cellp, AFSFid *fidp)
 {
     cm_fid_t tfid;
     cm_scache_t *scp;
@@ -195,10 +191,11 @@ void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp)
     /* do all in the hash bucket, since we don't know how many we'll find with
      * varying cells.
      */
-    for (scp = cm_data.hashTablep[hash]; scp; scp=scp->nextp) {
+    for (scp = cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
         if (scp->fid.volume == tfid.volume &&
              scp->fid.vnode == tfid.vnode &&
              scp->fid.unique == tfid.unique &&
+             (cellp == NULL || scp->fid.cell == cellp->cellID) &&
              scp->cbExpires > 0 && 
              scp->cbServerp != NULL)
         {
@@ -225,7 +222,7 @@ void cm_RevokeCallback(struct rx_call *callp, AFSFid *fidp)
  *
  * Called with no locks held.
  */
-void cm_RevokeVolumeCallback(struct rx_call *callp, AFSFid *fidp)
+void cm_RevokeVolumeCallback(struct rx_call *callp, cm_cell_t *cellp, AFSFid *fidp)
 {
     long hash;
     cm_scache_t *scp;
@@ -244,9 +241,10 @@ void cm_RevokeVolumeCallback(struct rx_call *callp, AFSFid *fidp)
 
 
     lock_ObtainWrite(&cm_scacheLock);
-    for (hash = 0; hash < cm_data.hashTableSize; hash++) {
-        for(scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) {
+    for (hash = 0; hash < cm_data.scacheHashTableSize; hash++) {
+        for(scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
             if (scp->fid.volume == fidp->Volume &&
+                (cellp == NULL || scp->fid.cell == cellp->cellID) &&
                  scp->cbExpires > 0 &&
                  scp->cbServerp != NULL) {
                 cm_HoldSCacheNoLock(scp);
@@ -343,12 +341,18 @@ SRXAFSCB_CallBack(struct rx_call *callp, AFSCBFids *fidsArrayp, AFSCBs *cbsArray
     struct rx_peer *peerp;
     unsigned long host = 0;
     unsigned short port = 0;
+    cm_server_t *tsp = NULL;
+    cm_cell_t * cellp = NULL;
 
     MUTEX_ENTER(&callp->lock);
 
     if ((connp = rx_ConnectionOf(callp)) && (peerp = rx_PeerOf(connp))) {
         host = rx_HostOf(peerp);
         port = rx_PortOf(peerp);
+
+        tsp = cm_FindServerByIP(host);
+        if (tsp)
+            cellp = tsp->cellp;
     }
 
     osi_Log2(afsd_logp, "SRXAFSCB_CallBack from host 0x%x port %d",
@@ -361,9 +365,9 @@ SRXAFSCB_CallBack(struct rx_call *callp, AFSCBFids *fidsArrayp, AFSCBs *cbsArray
         if (tfidp->Volume == 0)
             continue;   /* means don't do anything */
         else if (tfidp->Vnode == 0)
-            cm_RevokeVolumeCallback(callp, tfidp);
+            cm_RevokeVolumeCallback(callp, cellp, tfidp);
         else
-            cm_RevokeCallback(callp, tfidp);
+            cm_RevokeCallback(callp, cellp, tfidp);
     }
 
     MUTEX_EXIT(&callp->lock);
@@ -450,8 +454,8 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp)
         * are "rare," hopefully this won't be a problem.
         */
        lock_ObtainWrite(&cm_scacheLock);
-       for (hash = 0; hash < cm_data.hashTableSize; hash++) {
-            for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) {
+       for (hash = 0; hash < cm_data.scacheHashTableSize; hash++) {
+            for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
                 cm_HoldSCacheNoLock(scp);
                 lock_ReleaseWrite(&cm_scacheLock);
                 lock_ObtainMutex(&scp->mx);
@@ -475,9 +479,14 @@ SRXAFSCB_InitCallBackState(struct rx_call *callp)
        
        lock_ReleaseWrite(&cm_scacheLock);
        
-       /* we're done with the server structure */
-       if (tsp) 
+       if (tsp) {
+           /* reset the No flags on the server */
+           cm_SetServerNo64Bit(tsp, 0);
+           cm_SetServerNoInlineBulk(tsp, 0);
+
+           /* we're done with the server structure */
             cm_PutServer(tsp);
+       }
     }
     MUTEX_EXIT(&callp->lock);
     return 0;
@@ -688,8 +697,8 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
              ntohl(host), ntohs(port));
 
     lock_ObtainRead(&cm_scacheLock);
-    for (i = 0; i < cm_data.hashTableSize; i++) {
-        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+    for (i = 0; i < cm_data.scacheHashTableSize; i++) {
+        for (scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp) {
             if (index == 0)
                 goto searchDone;
             index--;
@@ -794,8 +803,8 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
              ntohl(host), ntohs(port));
 
     lock_ObtainRead(&cm_scacheLock);
-    for (i = 0; i < cm_data.hashTableSize; i++) {
-        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+    for (i = 0; i < cm_data.scacheHashTableSize; i++) {
+        for (scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp) {
             if (index == 0)
                 goto searchDone;
             index--;
@@ -829,7 +838,7 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
     cep->Length.high = scp->length.HighPart;
     cep->Length.low = scp->length.LowPart;
 #else
-    cep->Length = ((afs_int64)scp->length.HighPart)<<32 | scp->length.LowPart;
+    cep->Length = (afs_int64) scp->length.QuadPart;
 #endif
     cep->DataVersion = scp->dataVersion;
     cep->callback = afs_data_pointer_to_int32(scp->cbServerp);
@@ -1613,17 +1622,17 @@ void cm_EndCallbackGrantingCall(cm_scache_t *scp, cm_callbackRequest_t *cbrp,
 long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
                     struct cm_req *reqp, long flags)
 {
-    long code;
-    cm_conn_t *connp;
+    long code = 0;
+    cm_conn_t *connp = NULL;
     AFSFetchStatus afsStatus;
     AFSVolSync volSync;
     AFSCallBack callback;
     AFSFid tfid;
     cm_callbackRequest_t cbr;
     int mustCall;
-    long sflags;
     cm_fid_t sfid;
-    struct rx_connection * callp;
+    struct rx_connection * callp = NULL;
+    int syncop_done = 0;
 
     osi_Log4(afsd_logp, "GetCallback scp 0x%p cell %d vol %d flags %lX", 
              scp, scp->fid.cell, scp->fid.volume, flags);
@@ -1646,7 +1655,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
             lock_ReleaseMutex(&cm_Freelance_Lock);
 
             // Fetch the status info 
-            cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
+            cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
 
             // Indicate that the callback is not done
             lock_ObtainMutex(&cm_Freelance_Lock);
@@ -1670,27 +1679,29 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
     mustCall = (flags & 1);
     cm_AFSFidFromFid(&tfid, &scp->fid);
     while (1) {
-        if (!mustCall && cm_HaveCallback(scp)) {
-            osi_Log3(afsd_logp, "GetCallback Complete scp 0x%p cell %d vol %d", 
-                      scp, scp->fid.cell, scp->fid.volume);
-            return 0;
-        }
+        if (!mustCall && cm_HaveCallback(scp))
+           break;
 
         /* turn off mustCall, since it has now forced us past the check above */
         mustCall = 0;
 
         /* otherwise, we have to make an RPC to get the status */
-        sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK;
-        cm_SyncOp(scp, NULL, NULL, NULL, 0, sflags);
+       if (!syncop_done) {
+           code = cm_SyncOp(scp, NULL, userp, reqp, 0, 
+                            CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK);
+           if (code)
+               break;
+           syncop_done = 1;
+       }
         cm_StartCallbackGrantingCall(scp, &cbr);
         sfid = scp->fid;
         lock_ReleaseMutex(&scp->mx);
                
         /* now make the RPC */
         osi_Log4(afsd_logp, "CALL FetchStatus scp 0x%p vol %u vn %u uniq %u", 
-                 scp, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
+                 scp, sfid.volume, sfid.vnode, sfid.unique);
         do {
-            code = cm_Conn(&sfid, userp, reqp, &connp);
+            code = cm_ConnFromFID(&sfid, userp, reqp, &connp);
             if (code) 
                 continue;
 
@@ -1712,20 +1723,29 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
         lock_ObtainMutex(&scp->mx);
         if (code == 0) {
             cm_EndCallbackGrantingCall(scp, &cbr, &callback, 0);
-            cm_MergeStatus(scp, &afsStatus, &volSync, userp, 0);
+            cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, 0);
         } else {
             cm_EndCallbackGrantingCall(NULL, &cbr, NULL, 0);
         }
-        cm_SyncOpDone(scp, NULL, sflags);
-
-        /* now check to see if we got an error */
-        if (code) {
-            osi_Log2(afsd_logp, "GetCallback Failed code 0x%x scp 0x%p -->",code, scp);
-            osi_Log4(afsd_logp, "            cell %u vol %u vn %u uniq %u",
-                     scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
-            return code;
-        }
+
+        /* if we got an error, return to caller */
+        if (code)
+           break;
+    }
+
+    if (syncop_done)
+       cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK);
+    
+    if (code) {
+       osi_Log2(afsd_logp, "GetCallback Failed code 0x%x scp 0x%p -->",code, scp);
+       osi_Log4(afsd_logp, "            cell %u vol %u vn %u uniq %u",
+                scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
+    } else {
+       osi_Log3(afsd_logp, "GetCallback Complete scp 0x%p cell %d vol %d", 
+                 scp, scp->fid.cell, scp->fid.volume);
     }
+
+    return code;
 }
 
 /* called periodically by cm_daemon to shut down use of expired callbacks */
@@ -1739,8 +1759,8 @@ void cm_CheckCBExpiration(void)
 
     now = osi_Time();
     lock_ObtainWrite(&cm_scacheLock);
-    for (i=0; i<cm_data.hashTableSize; i++) {
-        for (scp = cm_data.hashTablep[i]; scp; scp=scp->nextp) {
+    for (i=0; i<cm_data.scacheHashTableSize; i++) {
+        for (scp = cm_data.scacheHashTablep[i]; scp; scp=scp->nextp) {
             cm_HoldSCacheNoLock(scp);
             if (scp->cbExpires > 0 && (scp->cbServerp == NULL || now > scp->cbExpires)) {
                 lock_ReleaseWrite(&cm_scacheLock);