Windows: Add cm_req_t parameter to cm_MergeStatus
[openafs.git] / src / WINNT / afsd / cm_scache.c
index 066781c..3f64b83 100644 (file)
@@ -76,17 +76,36 @@ void cm_RemoveSCacheFromHashTable(cm_scache_t *scp)
 }
 
 /* called with cm_scacheLock and scp write-locked */
-void cm_ResetSCacheDirectory(cm_scache_t *scp)
+void cm_ResetSCacheDirectory(cm_scache_t *scp, afs_int32 dirlock)
 {
 #ifdef USE_BPLUS
     /* destroy directory Bplus Tree */
     if (scp->dirBplus) {
         LARGE_INTEGER start, end;
+
+        if (!dirlock && !lock_TryWrite(&scp->dirlock)) {
+            /* 
+             * We are not holding the dirlock and obtaining it
+             * requires that we drop the scp->rw.  As a result
+             * we will leave the dirBplus tree intact but 
+             * invalidate the version number so that whatever
+             * operation is currently active can safely complete
+             * but the contents will be ignored on the next 
+             * directory operation.
+             */
+            scp->dirDataVersion = CM_SCACHE_VERSION_BAD;
+            return;
+        }
+
         QueryPerformanceCounter(&start);
         bplus_free_tree++;
         freeBtree(scp->dirBplus);
         scp->dirBplus = NULL;
+        scp->dirDataVersion = CM_SCACHE_VERSION_BAD;
         QueryPerformanceCounter(&end);
+        
+        if (!dirlock) 
+            lock_ReleaseWrite(&scp->dirlock);
 
         bplus_free_time += (end.QuadPart - start.QuadPart);
     }
@@ -222,7 +241,7 @@ long cm_RecycleSCache(cm_scache_t *scp, afs_int32 flags)
      */
     cm_FreeAllACLEnts(scp);
 
-    cm_ResetSCacheDirectory(scp);
+    cm_ResetSCacheDirectory(scp, 0);
     return 0;
 }
 
@@ -1481,7 +1500,7 @@ void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, afs_uint32 flags)
 void cm_MergeStatus(cm_scache_t *dscp, 
                    cm_scache_t *scp, AFSFetchStatus *statusp, 
                    AFSVolSync *volsyncp,
-                    cm_user_t *userp, afs_uint32 flags)
+                    cm_user_t *userp, cm_req_t *reqp, afs_uint32 flags)
 {
     afs_uint64 dataVersion;
 
@@ -1557,9 +1576,8 @@ void cm_MergeStatus(cm_scache_t *dscp,
         cellp = cm_FindCellByID(scp->fid.cell, 0);
         if (scp->cbServerp) {
             struct cm_volume *volp = NULL;
-
             cm_FindVolumeByID(cellp, scp->fid.volume, userp,
-                              (cm_req_t *) NULL, CM_GETVOL_FLAG_CREATE, &volp);
+                              reqp, CM_GETVOL_FLAG_CREATE, &volp);
             osi_Log2(afsd_logp, "old data from server %x volume %s",
                       scp->cbServerp->addr.sin_addr.s_addr,
                       volp ? volp->namep : "(unknown)");