]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-buf-data-versions-20080224
authorJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 24 Feb 2008 06:33:20 +0000 (06:33 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sun, 24 Feb 2008 06:33:20 +0000 (06:33 +0000)
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.

(cherry picked from commit 9e41258fad54e3122a0722b3f1c24810590c8d0a)

src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/cm_scache.h

index aa94fa56ba2333ad8ada39c6f50a456d9076ddf6..c03b1b31ac7868d9296e61ee7d2defe59cddca63 100644 (file)
@@ -505,7 +505,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);
@@ -1161,7 +1161,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);
@@ -1355,7 +1355,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;
     }
@@ -1376,7 +1376,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)) 
         {
index ac4d88465e4053cd64dba3d50761e5d16b467cc8..e4f73568fbabbf5a199fe7df45431ece41ba6c03 100644 (file)
@@ -166,6 +166,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;
@@ -768,6 +769,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);
@@ -1544,6 +1546,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;
@@ -1654,9 +1657,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)) {
         /* 
@@ -1714,6 +1715,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;
 }
 
index a3b6f17f1659bdd93cfa050bdb924b38b72dfb75..280ebba688b7280b86c9ad4be6f11bad7a5f968a 100644 (file)
@@ -123,6 +123,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 */