]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-windows-afsd-service-20051121
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 22 Nov 2005 00:30:01 +0000 (00:30 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 22 Nov 2005 00:30:01 +0000 (00:30 +0000)
add logic to process VNOVNODE in cm_Analyze.  Force re-evaluation of symlink
strings and flush the stat cache entry.

force the use of new rx_connections when the server is marked down.

prevent server objects from being freed if user preferences are set.

src/WINNT/afsd/cm_conn.c
src/WINNT/afsd/cm_conn.h
src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_ioctl.h
src/WINNT/afsd/cm_server.c
src/WINNT/afsd/cm_server.h

index c7cc7eebe505538c938661e94f400abb1667dd4c..6251c7ef4b2d26b65fc424a90544bd746bbc3d4f 100644 (file)
@@ -401,6 +401,25 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
         }
         if ( timeLeft > 2 )
             retry = 1;
+    } else if ( errorCode == VNOVNODE ) {
+       if ( fidp ) {
+           cm_scache_t * scp;
+           osi_Log4(afsd_logp, "cm_Analyze passed VNOVNODE cell %u vol %u vn %u uniq %u.",
+                     fidp->cell, fidp->volume, fidp->vnode, fidp->unique);
+#ifdef VNOVNODE_FLUSH_VOLUME
+           cm_FlushVolume(userp, reqp, fidp->cell, fidp->volume);
+#else /* VNOVNODE_FLUSH_FILE */
+           if (!cm_GetSCache(fidp, &scp, userp, reqp)) {
+               cm_FlushFile(scp, userp, reqp);
+#ifdef VNOVNODE_FLUSH_PARENT
+               cm_FlushParent(scp, userp, reqp);
+#endif /* VNOVNODE_FLUSH_PARENT */
+               cm_ReleaseSCache(scp);
+           }
+#endif /* VNODE_FLUSH_xxxx */
+       } else {
+           osi_Log0(afsd_logp, "cm_Analyze passed VNOVNODE unknown fid.");
+       }
     }
 
     /* RX codes */
@@ -430,6 +449,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
         lock_ObtainMutex(&serverp->mx);
         serverp->flags |= CM_SERVERFLAG_DOWN;
         lock_ReleaseMutex(&serverp->mx);
+       cm_ForceNewConnections(serverp);
         if ( timeLeft > 2 )
             retry = 1;
     }
@@ -696,7 +716,8 @@ long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp)
         tcp->refCount = 1;
         lock_ReleaseMutex(&tcp->mx);
     } else {
-        if ((tcp->ucgen < ucellp->gen) ||
+        if ((tcp->flags & CM_CONN_FLAG_FORCE_NEW) ||
+            (tcp->ucgen < ucellp->gen) ||
             (tcp->cryptlevel != (cryptall ? (ucellp->flags & CM_UCELLFLAG_RXKAD ? rxkad_crypt : rxkad_clear) : rxkad_clear)))
         {
             if (tcp->ucgen < ucellp->gen)
@@ -704,6 +725,7 @@ long cm_ConnByServer(cm_server_t *serverp, cm_user_t *userp, cm_conn_t **connpp)
             else
                 osi_Log0(afsd_logp, "cm_ConnByServer replace connection due to crypt change");
             lock_ObtainMutex(&tcp->mx);
+           tcp->flags &= ~CM_CONN_FLAG_FORCE_NEW;
             rx_DestroyConnection(tcp->callp);
             cm_NewRXConnection(tcp, ucellp, serverp);
             lock_ReleaseMutex(&tcp->mx);
@@ -749,3 +771,15 @@ cm_GetRxConn(cm_conn_t *connp)
     return rxconn;
 }
 
+void cm_ForceNewConnections(cm_server_t *serverp)
+{
+    cm_conn_t *tcp;
+
+    lock_ObtainWrite(&cm_connLock);
+    for (tcp = serverp->connsp; tcp; tcp=tcp->nextp) {
+       lock_ObtainMutex(&tcp->mx);
+       tcp->flags |= CM_CONN_FLAG_FORCE_NEW;
+       lock_ReleaseMutex(&tcp->mx);
+    }
+    lock_ReleaseWrite(&cm_connLock);
+}
index e993edaabcee193db732c97345438a9ea932b288..29ce89bd318dba609ded20f43bf3b3aa08f63be0 100644 (file)
@@ -29,6 +29,8 @@ typedef struct cm_conn {
        int cryptlevel;                 /* encrytion status */
 } cm_conn_t;
 
+#define CM_CONN_FLAG_FORCE_NEW 1
+
 /* structure used for tracking RPC progress */
 typedef struct cm_req {
        DWORD startTime;                /* Quit before RDR times us out */
@@ -115,4 +117,6 @@ extern void cm_GCConnections(cm_server_t *serverp);
 
 extern struct rx_connection * cm_GetRxConn(cm_conn_t *connp);
 
+extern void cm_ForceNewConnections(cm_server_t *serverp);
+
 #endif /*  __CM_CONN_H_ENV__ */
index ae7b9f2d3573b36b0c80f0e778bf020270994486..7e92a10ea6612e85009a2d1bc0ae90499924bae1 100644 (file)
@@ -1368,7 +1368,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *up,
         if (code == 0)
             code = EndRXAFS_FetchData(callp, &afsStatus, &callback, &volSync);
         else
-            osi_Log0(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error");
+            osi_Log1(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error %d", code);
         code = rx_EndCall(callp, code);
         if (code == RXKADUNKNOWNKEY)
             osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY");
index 6190774ee6bed68c5eb6edc58fb052cba57eb70a..8e41311a1be2ab9b63b917432611ed66128a5ef2 100644 (file)
@@ -75,6 +75,10 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
     cm_dnlcPurgedp(scp);
     cm_dnlcPurgevp(scp);
     cm_FreeAllACLEnts(scp);
+
+    /* Force mount points and symlinks to be re-evaluated */
+    scp->mountPointStringp[0] = '\0';
+
     lock_ReleaseMutex(&scp->mx);
 
     lock_ReleaseWrite(&scp->bufCreateLock);
@@ -82,6 +86,63 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
     return code;
 }
 
+long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+{
+    long code = 0;
+    int i;
+    cm_fid_t    parent_fid;
+
+    lock_ObtainWrite(&cm_scacheLock);
+    cm_HoldSCacheNoLock(scp);
+    parent_fid = scp->fid;
+    parent_fid.vnode = scp->parentVnode;
+    parent_fid.unique = scp->parentUnique;
+    cm_ReleaseSCacheNoLock(scp);
+
+    for (i=0; i<cm_data.hashTableSize; i++) {
+        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+            if (cm_FidCmp(&scp->fid, &parent_fid)) {
+                cm_HoldSCacheNoLock(scp);
+                lock_ReleaseWrite(&cm_scacheLock);
+
+                /* now flush the file */
+                code = cm_FlushFile(scp, userp, reqp);
+                lock_ObtainWrite(&cm_scacheLock);
+                cm_ReleaseSCacheNoLock(scp);
+            }
+        }
+    }
+    lock_ReleaseWrite(&cm_scacheLock);
+
+    return code;
+}
+
+
+long cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume)
+{
+    long code = 0;
+    cm_scache_t *scp;
+    int i;
+
+    lock_ObtainWrite(&cm_scacheLock);
+    for (i=0; i<cm_data.hashTableSize; i++) {
+        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+            if (scp->fid.volume == volume && scp->fid.cell == cell) {
+                cm_HoldSCacheNoLock(scp);
+                lock_ReleaseWrite(&cm_scacheLock);
+
+                /* now flush the file */
+                code = cm_FlushFile(scp, userp, reqp);
+                lock_ObtainWrite(&cm_scacheLock);
+                cm_ReleaseSCacheNoLock(scp);
+            }
+        }
+    }
+    lock_ReleaseWrite(&cm_scacheLock);
+
+    return code;
+}
+
 /*
  * cm_ResetACLCache -- invalidate ACL info for a user that has just
  *                     obtained or lost tokens
@@ -533,6 +594,8 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return code;
 }
 
+
+
 long cm_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
     long code;
@@ -564,7 +627,7 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
     long code;
     cm_scache_t *scp;
     unsigned long volume;
-    int i;
+    unsigned long cell;
     cm_req_t req;
 
     cm_InitReq(&req);
@@ -573,23 +636,10 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
     if (code) return code;
         
     volume = scp->fid.volume;
+    cell = scp->fid.cell;
     cm_ReleaseSCache(scp);
 
-    lock_ObtainWrite(&cm_scacheLock);
-    for (i=0; i<cm_data.hashTableSize; i++) {
-        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
-            if (scp->fid.volume == volume) {
-                cm_HoldSCacheNoLock(scp);
-                lock_ReleaseWrite(&cm_scacheLock);
-
-                /* now flush the file */
-                code = cm_FlushFile(scp, userp, &req);
-                lock_ObtainWrite(&cm_scacheLock);
-                cm_ReleaseSCacheNoLock(scp);
-            }
-        }
-    }
-    lock_ReleaseWrite(&cm_scacheLock);
+    code = cm_FlushVolume(userp, &req, cell, volume);
 
     return code;
 }
@@ -1453,13 +1503,16 @@ long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
                 /* set preferences for an existing vlserver */
                 cm_ChangeRankCellVLServer(tsp);
             }
-            cm_PutServer(tsp);  /* decrease refcount */
         }
         else   /* add a new server without a cell */
         {
             tsp = cm_NewServer(&tmp, type, NULL); /* refcount = 1 */
             tsp->ipRank = rank;
         }
+       lock_ObtainMutex(&tsp->mx);
+       tsp->flags |= CM_SERVERFLAG_PREF_SET;
+       lock_ReleaseMutex(&tsp->mx);
+       cm_PutServer(tsp);  /* decrease refcount */
     }
     return 0;
 }
index bbc4f15aee112b98727b541e50e43e9783a8e07f..a0d3c01735b4410f11f1ee08506fa2a340da7590 100644 (file)
@@ -118,6 +118,10 @@ extern long cm_IoctlCreateMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
 
+extern long cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
+
+extern long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+
 extern long cm_IoctlTraceControl(smb_ioctl_t *ioctlp, cm_user_t *userp);
 
 extern long cm_IoctlSetToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
index d8b1faa1f7c8af3dbbe1e3d575fdeb7d6628171a..309b57717fc666ff514ae6a5740e4dfadefa34e0 100644 (file)
@@ -107,6 +107,8 @@ void cm_CheckServers(long flags, cm_cell_t *cellp)
             else {
                 /* mark server as down */
                 tsp->flags |= CM_SERVERFLAG_DOWN;
+               if (code != VRESTARTING)
+                   cm_ForceNewConnections(tsp);
             }
             lock_ReleaseMutex(&tsp->mx);
         }
@@ -438,21 +440,24 @@ void cm_FreeServer(cm_server_t* serverp)
          */
         cm_GCConnections(serverp);  /* connsp */
 
-        lock_FinalizeMutex(&serverp->mx);
-        if ( cm_allServersp == serverp )
-            cm_allServersp = serverp->allNextp;
-        else {
-            cm_server_t *tsp;
-
-            for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
-                if ( tsp->allNextp == serverp ) {
-                    tsp->allNextp = serverp->allNextp;
-                    break;
-                }
+       if (!(serverp->flags & CM_SERVERFLAG_PREF_SET)) {
+           lock_FinalizeMutex(&serverp->mx);
+           if ( cm_allServersp == serverp )
+               cm_allServersp = serverp->allNextp;
+           else {
+               cm_server_t *tsp;
+
+               for(tsp = cm_allServersp; tsp->allNextp; tsp=tsp->allNextp) {
+                   if ( tsp->allNextp == serverp ) {
+                       tsp->allNextp = serverp->allNextp;
+                       break;
+                   }
+               }
             }
+           free(serverp);
         }
     }
- }
+}
 
 void cm_FreeServerList(cm_serverRef_t** list)
 {
index 5643512e0ebfc14b235b2821d9dcd7f20c1dc79e..265eb1a1abb319e7cc3907730e8e9437cc184663 100644 (file)
@@ -24,12 +24,12 @@ typedef struct cm_server {
     struct cm_server *allNextp;                /* locked by cm_serverLock */
     struct sockaddr_in addr;           /* by mx */
     int type;                          /* by mx */
-    struct cm_conn *connsp;                    /* locked by cm_connLock */
+    struct cm_conn *connsp;            /* locked by cm_connLock */
     long flags;                                /* by mx */
-    struct cm_cell *cellp;                     /* cell containing this server */
-    unsigned long refCount;                            /* locked by cm_serverLock */
+    struct cm_cell *cellp;             /* cell containing this server */
+    unsigned long refCount;            /* locked by cm_serverLock */
     osi_mutex_t mx;
-    unsigned short ipRank;                     /* server priority */
+    unsigned short ipRank;             /* server priority */
 } cm_server_t;
 
 enum repstate {not_busy, busy, offline};
@@ -47,6 +47,7 @@ typedef struct cm_serverRef {
 
 /* flags */
 #define CM_SERVERFLAG_DOWN     1       /* server is down */
+#define CM_SERVERFLAG_PREF_SET 2       /* server preference set by user */
 
 /* flags for procedures */
 #define CM_FLAG_CHECKUPSERVERS         1       /* check working servers */