Windows: record mount point string data version
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 9 Jul 2012 04:49:13 +0000 (00:49 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Mon, 9 Jul 2012 05:37:39 +0000 (22:37 -0700)
The Windows cache manager stores the mount point or symlink target
string in the cm_scache_t object.  If the string is the empty string
then the target needs to be resolved.  Otherwise it is considered
up to date.  With this approach, care must be taken to ensure that
the string is erased whenever the data version changes.

This patchset records the data version of the mount point target
string in the cm_scache_t object.  Being up to date is determined
by comparing the current data version of the object to the mount
point string version.  A match and the string is up to date.

Change-Id: I4dfdc1af5894548afb35e84e77f7f607674bd7af
Reviewed-on: http://gerrit.openafs.org/7745
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_memmap.h
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_scache.h
src/WINNT/afsd/cm_vnodeops.c

index f933bb2..d1ed5f0 100644 (file)
@@ -731,7 +731,7 @@ SRXAFSCB_GetCE(struct rx_call *callp, long index, AFSDBCacheEntry *cep)
     if (scp->flags & CM_SCACHEFLAG_RO || scp->flags & CM_SCACHEFLAG_PURERO)
         cep->states |= 4;
     if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
-        scp->mountPointStringp[0])
+        scp->mpDataVersion == scp->dataVersion)
         cep->states |= 8;
     if (scp->flags & CM_SCACHEFLAG_WAITING)
         cep->states |= 0x40;
@@ -846,7 +846,7 @@ SRXAFSCB_GetCE64(struct rx_call *callp, long index, AFSDBCacheEntry64 *cep)
     if (scp->flags & CM_SCACHEFLAG_RO || scp->flags & CM_SCACHEFLAG_PURERO)
         cep->states |= 4;
     if (scp->fileType == CM_SCACHETYPE_MOUNTPOINT &&
-        scp->mountPointStringp[0])
+        scp->mpDataVersion == scp->dataVersion)
         cep->states |= 8;
     if (scp->flags & CM_SCACHEFLAG_WAITING)
         cep->states |= 0x40;
index a70d95b..2a59014 100644 (file)
@@ -1535,13 +1535,14 @@ long
 cm_FreelanceFetchMountPointString(cm_scache_t *scp)
 {
     lock_ObtainMutex(&cm_Freelance_Lock);
-    if (!scp->mountPointStringp[0] &&
+    if (scp->mpDataVersion != scp->dataVersion &&
         scp->fid.cell == AFS_FAKE_ROOT_CELL_ID &&
         scp->fid.volume == AFS_FAKE_ROOT_VOL_ID &&
         (afs_int32)(scp->fid.unique - cm_data.fakeUnique) - 1 >= 0 &&
         scp->fid.unique - cm_data.fakeUnique <= cm_noLocalMountPoints) {
         strncpy(scp->mountPointStringp, cm_localMountPoints[scp->fid.unique-cm_data.fakeUnique-1].mountPointStringp, MOUNTPOINTLEN);
         scp->mountPointStringp[MOUNTPOINTLEN-1] = 0;   /* null terminate */
+        scp->mpDataVersion = scp->dataVersion;
     }
     lock_ReleaseMutex(&cm_Freelance_Lock);
 
index b21a15f..e271eb3 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef CM_MEMMAP_H
 #define CM_MEMMAP_H 1
 
-#define CM_CONFIG_DATA_VERSION  20
+#define CM_CONFIG_DATA_VERSION  21
 #define CM_CONFIG_DATA_MAGIC            ('A' | 'F'<<8 | 'S'<<16 | CM_CONFIG_DATA_VERSION<<24)
 
 typedef struct cm_config_data {
index dbcf940..61c1519 100644 (file)
@@ -221,6 +221,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags)
     scp->mask = 0;
 
     /* discard symlink info */
+    scp->mpDataVersion = CM_SCACHE_VERSION_BAD;
     scp->mountPointStringp[0] = '\0';
     memset(&scp->mountRootFid, 0, sizeof(cm_fid_t));
     memset(&scp->dotdotFid, 0, sizeof(cm_fid_t));
@@ -1900,15 +1901,7 @@ void cm_MergeStatus(cm_scache_t *dscp,
         lock_ReleaseWrite(&buf_globalLock);
     }
 
-    /*
-     * If the dataVersion has changed, the mountPointStringp must be cleared
-     * in order to force a re-evaluation by cm_HandleLink().  The Windows CM
-     * does not update a mountpoint or symlink by altering the contents of
-     * the file data; but the Unix CM does.
-     */
     if (scp->dataVersion != dataVersion && !(flags & CM_MERGEFLAG_FETCHDATA)) {
-        scp->mountPointStringp[0] = '\0';
-
         osi_Log5(afsd_logp, "cm_MergeStatus data version change scp 0x%p cell %u vol %u vn %u uniq %u",
                  scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique);
 
@@ -2042,9 +2035,6 @@ void cm_DiscardSCache(cm_scache_t *scp)
 
     if (scp->fileType == CM_SCACHETYPE_DFSLINK)
         cm_VolStatus_Invalidate_DFS_Mapping(scp);
-
-    /* Force mount points and symlinks to be re-evaluated */
-    scp->mountPointStringp[0] = '\0';
 }
 
 void cm_AFSFidFromFid(AFSFid *afsFidp, cm_fid_t *fidp)
@@ -2251,10 +2241,10 @@ int cm_DumpSCache(FILE *outputFile, char *cookie, int lock)
         }
         sprintf(output,
                 "%s scp=0x%p, fid (cell=%d, volume=%d, vnode=%d, unique=%d) type=%d dv=%I64d len=0x%I64x "
-                "mp='%s' Locks (server=0x%x shared=%d excl=%d clnt=%d) fsLockCount=%d linkCount=%d anyAccess=0x%x "
+                "mpDV=%I64d mp='%s' Locks (server=0x%x shared=%d excl=%d clnt=%d) fsLockCount=%d linkCount=%d anyAccess=0x%x "
                 "flags=0x%x cbServer='%s' cbExpires='%s' volumeCreationDate='%s' refCount=%u\r\n",
                 cookie, scp, scp->fid.cell, scp->fid.volume, scp->fid.vnode, scp->fid.unique,
-                scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mountPointStringp,
+                scp->fileType, scp->dataVersion, scp->length.QuadPart, scp->mpDataVersion, scp->mountPointStringp,
                 scp->serverLock, scp->sharedLocks, scp->exclusiveLocks, scp->clientLocks, scp->fsLockCount,
                 scp->linkCount, scp->anyAccess, scp->flags, srvStr ? srvStr : "<none>", cbt ? cbt : "<none>",
                 cdrot ? cdrot : "<none>", scp->refCount);
index 3a4cd05..d7d39d5 100644 (file)
@@ -144,6 +144,7 @@ typedef struct cm_scache {
                                          * storing data */
 
     /* symlink and mount point info */
+    afs_uint64   mpDataVersion;         /* data version represented by mountPointStringp */
     char mountPointStringp[MOUNTPOINTLEN];     /* the string stored in a mount point;
                                                  * first char is type, then vol name.
                                          * If this is a normal symlink, we store
index 1706b3b..21f697e 100644 (file)
@@ -842,7 +842,8 @@ long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 {
     long code;
 
-    if (scp->mountPointStringp[0])
+    if (scp->mountPointStringp[0] &&
+        scp->mpDataVersion == scp->dataVersion)
         return 0;
 
 #ifdef AFS_FREELANCE_CLIENT
@@ -877,6 +878,7 @@ long cm_ReadMountPoint(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
         /* convert the terminating dot to a NUL */
         temp[scp->length.LowPart - 1] = 0;
         memcpy(scp->mountPointStringp, temp, scp->length.LowPart);
+        scp->mpDataVersion = scp->dataVersion;
     }
 
     return code;
@@ -1763,7 +1765,8 @@ long cm_HandleLink(cm_scache_t *linkScp, cm_user_t *userp, cm_req_t *reqp)
     long code = 0;
 
     lock_AssertWrite(&linkScp->rw);
-    if (!linkScp->mountPointStringp[0]) {
+    if (!linkScp->mountPointStringp[0] ||
+        linkScp->mpDataVersion != linkScp->dataVersion) {
 
 #ifdef AFS_FREELANCE_CLIENT
        /* File servers do not have data for freelance entries */