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 <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
This commit is contained in:
Jeffrey Altman 2012-07-09 00:49:13 -04:00
parent df46bb407a
commit 606d9554e2
6 changed files with 14 additions and 19 deletions

View 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;

View 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);

View 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 {

View 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);

View 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

View 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 */