From 9e41258fad54e3122a0722b3f1c24810590c8d0a Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 24 Feb 2008 06:31:54 +0000 Subject: [PATCH] windows-buf-data-versions-20080224 LICENSE MIT An implementation of Asanka's idea. Avoid the need to update the data version number on each buffer associated with a scache when MergeStatus is called after a StoreData by maintaining a range of valid data versions as part of the cm_scache_t object. --- src/WINNT/afsd/cm_dcache.c | 8 ++++---- src/WINNT/afsd/cm_scache.c | 18 +++++++++++++++--- src/WINNT/afsd/cm_scache.h | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 3243e3804..518dbc7e6 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -503,7 +503,7 @@ int cm_HaveBuffer(cm_scache_t *scp, cm_buf_t *bufp, int isBufLocked) return 0; if ((bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) == (CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED)) return 1; - if (bufp->dataVersion == scp->dataVersion) + if (bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow) return 1; if (!isBufLocked) { code = lock_TryMutex(&bufp->mx); @@ -1159,7 +1159,7 @@ long cm_SetupFetchBIOD(cm_scache_t *scp, osi_hyper_t *offsetp, lock_ObtainMutex(&scp->mx); /* don't bother fetching over data that is already current */ - if (tbp->dataVersion == scp->dataVersion) { + if (tbp->dataVersion <= scp->dataVersion && tbp->dataVersion >= scp->bufDataVersionLow) { /* we don't need this buffer, since it is current */ lock_ReleaseMutex(&scp->mx); lock_ReleaseMutex(&tbp->mx); @@ -1353,7 +1353,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *userp osi_Log1(afsd_logp,"GetBuffer returns cm_data.rootSCachep=%x",cm_data.rootSCachep); #endif - if (cm_HaveCallback(scp) && bufp->dataVersion == scp->dataVersion) { + if (cm_HaveCallback(scp) && bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow) { /* We already have this buffer don't do extra work */ return 0; } @@ -1374,7 +1374,7 @@ long cm_GetBuffer(cm_scache_t *scp, cm_buf_t *bufp, int *cpffp, cm_user_t *userp * We can lose a race condition and end up with biod.length zero, in * which case we just retry. */ - if (bufp->dataVersion == scp->dataVersion || biod.length == 0) { + if (bufp->dataVersion <= scp->dataVersion && bufp->dataVersion >= scp->bufDataVersionLow || biod.length == 0) { if ((bufp->dataVersion == -1 || bufp->dataVersion < scp->dataVersion) && LargeIntegerGreaterThanOrEqualTo(bufp->offset, scp->serverLength)) { diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index c9e298f4e..9aa04751b 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -164,6 +164,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags) | CM_SCACHEFLAG_EACCESS); scp->serverModTime = 0; scp->dataVersion = 0; + scp->bufDataVersionLow = 0; scp->bulkStatProgress = hzero; scp->waitCount = 0; scp->waitQueueT = NULL; @@ -766,6 +767,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, scp->parentVnode=0x1; scp->group=0; scp->dataVersion=cm_data.fakeDirVersion; + scp->bufDataVersionLow=cm_data.fakeDirVersion; scp->lockDataVersion=-1; /* no lock yet */ #if not_too_dangerous lock_ReleaseMutex(&scp->mx); @@ -1542,6 +1544,7 @@ void cm_MergeStatus(cm_scache_t *dscp, scp->unixModeBits = 0; scp->anyAccess = 0; scp->dataVersion = 0; + scp->bufDataVersionLow = 0; if (dscp) { scp->parentVnode = dscp->fid.vnode; @@ -1652,9 +1655,7 @@ void cm_MergeStatus(cm_scache_t *dscp, cm_AddACLCache(scp, userp, statusp->CallerAccess); } - if ((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion == 1) { - buf_ForceDataVersion(scp, scp->dataVersion, dataVersion); - } else if (scp->dataVersion != 0 && + if (scp->dataVersion != 0 && (!(flags & CM_MERGEFLAG_DIROP) && dataVersion != scp->dataVersion || (flags & CM_MERGEFLAG_DIROP) && dataVersion - scp->dataVersion > 1)) { /* @@ -1712,6 +1713,17 @@ void cm_MergeStatus(cm_scache_t *dscp, } lock_ReleaseWrite(&buf_globalLock); } + + /* We maintain a range of buffer dataVersion values which are considered + * valid. This avoids the need to update the dataVersion on each buffer + * object during an uncontested storeData operation. As a result this + * merge status no longer has performance characteristics derived from + * the size of the file. + */ + if (((flags & CM_MERGEFLAG_STOREDATA) && dataVersion - scp->dataVersion > 1) || + (!(flags & CM_MERGEFLAG_STOREDATA) && scp->dataVersion != dataVersion)) + scp->bufDataVersionLow = dataVersion; + scp->dataVersion = dataVersion; } diff --git a/src/WINNT/afsd/cm_scache.h b/src/WINNT/afsd/cm_scache.h index b4b4b1446..b00220a58 100644 --- a/src/WINNT/afsd/cm_scache.h +++ b/src/WINNT/afsd/cm_scache.h @@ -119,6 +119,7 @@ typedef struct cm_scache { afs_uint32 unixModeBits; /* unix protection mode bits */ afs_uint32 linkCount; /* link count */ afs_uint64 dataVersion; /* data version */ + afs_uint64 bufDataVersionLow; /* range of valid cm_buf_t dataVersions */ afs_uint32 owner; /* file owner */ afs_uint32 group; /* file owning group */ cm_user_t *creator; /* user, if new file */ -- 2.39.5