windows-afsd-service-20051121
authorJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 7 Dec 2005 12:01:32 +0000 (12:01 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Wed, 7 Dec 2005 12:01:32 +0000 (12:01 +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.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================

improvements to VNOVNODE fix

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 518f3b4..bf8a7f1 100644 (file)
@@ -401,6 +401,19 @@ 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);
+           if (!cm_GetSCache(fidp, &scp, userp, reqp)) {
+               cm_FlushParent(scp, userp, reqp);
+               cm_FlushFile(scp, userp, reqp);
+               cm_ReleaseSCache(scp);
+           }
+       } else {
+           osi_Log0(afsd_logp, "cm_Analyze passed VNOVNODE unknown fid.");
+       }
     }
 
     /* RX codes */
@@ -430,6 +443,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 +710,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 +719,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 +765,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 8692c07..bf97f82 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 340a357..5ce42b9 100644 (file)
@@ -1370,7 +1370,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 770bbf6..ee70d7d 100644 (file)
@@ -77,10 +77,71 @@ 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);
-    afsi_log("cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
+    osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
+    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;
 }
 
@@ -562,6 +623,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;
@@ -593,7 +656,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);
@@ -602,23 +665,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;
 }
@@ -1482,13 +1532,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 bbc4f15..a0d3c01 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 b945c83..99bca36 100644 (file)
@@ -103,6 +103,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);
         }
@@ -428,21 +430,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 e6b0952..922f260 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 */