From 606d9554e2880c2978675b7eae3fa5f53bd07c3d Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 9 Jul 2012 00:49:13 -0400 Subject: [PATCH] Windows: record mount point string data version 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 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_callback.c | 4 ++-- src/WINNT/afsd/cm_freelance.c | 3 ++- src/WINNT/afsd/cm_memmap.h | 2 +- src/WINNT/afsd/cm_scache.c | 16 +++------------- src/WINNT/afsd/cm_scache.h | 1 + src/WINNT/afsd/cm_vnodeops.c | 7 +++++-- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index f933bb2c9..d1ed5f0e0 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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; diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index a70d95bb4..2a5901481 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -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); diff --git a/src/WINNT/afsd/cm_memmap.h b/src/WINNT/afsd/cm_memmap.h index b21a15f15..e271eb39e 100644 --- a/src/WINNT/afsd/cm_memmap.h +++ b/src/WINNT/afsd/cm_memmap.h @@ -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 { diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index dbcf940fd..61c15190c 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -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 : "", cbt ? cbt : "", cdrot ? cdrot : "", scp->refCount); diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index 3a4cd0561..d7d39d55f 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -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 diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 1706b3b31..21f697e44 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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 */ -- 2.39.5