Windows: Fcb sectionObjectResource
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index 2823940..15af3e2 100644 (file)
@@ -672,7 +672,7 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -779,7 +779,7 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -976,7 +976,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                           FileName);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -1139,16 +1139,6 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
 
             //
-            // Object specific information
-            //
-
-            pObjectInfoCB->Links = DirEnumEntry->Links;
-
-            pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
-
-            pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
-
-            //
             // Check for the case where we have a filetype of SymLink but both the TargetFid and the
             // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
             // the code
@@ -1174,6 +1164,16 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             }
         }
 
+        //
+        // Object specific information
+        //
+
+        pObjectInfoCB->Links = DirEnumEntry->Links;
+
+        pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
+
+        pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
+
 try_exit:
 
         if( !NT_SUCCESS( ntStatus))
@@ -1202,7 +1202,7 @@ try_exit:
             if( pObjectInfoCB != NULL)
             {
 
-                lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pObjectInfoCB);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1658,6 +1658,8 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
             // Mark this node as invalid
             //
 
+            (*ppObjectInfo)->Links = 0;
+
             SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -1724,7 +1726,7 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                               (*ppObjectInfo)->FileId.Vnode,
                               (*ppObjectInfo)->FileId.Unique);
 
-                AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
+                AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
                                 TRUE);
 
                 __try
@@ -1751,21 +1753,26 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                         ntStatus = stIoStatus.Status;
                     }
 
-                    if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
-                                               NULL,
-                                               0,
-                                               FALSE))
+
+                    if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                      AFS_TRACE_LEVEL_WARNING,
-                                      "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                      (*ppObjectInfo)->FileId.Cell,
-                                      (*ppObjectInfo)->FileId.Volume,
-                                      (*ppObjectInfo)->FileId.Vnode,
-                                      (*ppObjectInfo)->FileId.Unique);
+                        if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                          AFS_TRACE_LEVEL_WARNING,
+                                          "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                          (*ppObjectInfo)->FileId.Cell,
+                                          (*ppObjectInfo)->FileId.Volume,
+                                          (*ppObjectInfo)->FileId.Vnode,
+                                          (*ppObjectInfo)->FileId.Unique);
 
-                        SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                            SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
                     }
                 }
                 __except( EXCEPTION_EXECUTE_HANDLER)
@@ -1785,7 +1792,7 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                     SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                 }
 
-                AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
+                AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
 
                 //
                 // Clear out the extents
@@ -1993,8 +2000,6 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             ntStatus = AFSInvalidateVolume( pVolumeCB,
                                             InvalidateCB->Reason);
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
             try_return( ntStatus);
         }
 
@@ -2009,14 +2014,6 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         else
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
-                          pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
-
             ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
 
             ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
@@ -2031,7 +2028,7 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2066,7 +2063,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2074,6 +2071,18 @@ try_exit:
                           pObjectInfo,
                           lCount);
         }
+
+        if ( pVolumeCB != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+        }
     }
 
     return ntStatus;
@@ -2510,7 +2519,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
         if ( pCurrentObject )
         {
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2524,7 +2533,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             if ( pCurrentObject)
             {
 
-                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2550,7 +2559,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2571,7 +2580,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                 // Reference the node so it won't be torn down
                 //
 
-                lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pNextObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2588,7 +2597,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             if ( pCurrentObject )
             {
 
-                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2640,6 +2649,12 @@ AFSInvalidateAllVolumes( VOID)
                       PsGetCurrentThread());
 
         lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateAllVolumes Increment count on volume %08lX Cnt %d\n",
+                      pVolumeCB,
+                      lCount);
     }
 
     while( pVolumeCB != NULL)
@@ -2651,6 +2666,12 @@ AFSInvalidateAllVolumes( VOID)
         {
 
             lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateAllVolumes Increment count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
         }
 
         AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
@@ -2664,6 +2685,12 @@ AFSInvalidateAllVolumes( VOID)
 
         lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateAllVolumes Decrement count on volume %08lX Cnt %d\n",
+                      pVolumeCB,
+                      lCount);
+
         pVolumeCB = pNextVolumeCB;
     }
 
@@ -2781,8 +2808,6 @@ AFSVerifyEntry( IN GUID *AuthGroup,
             case AFS_FILE_TYPE_SYMLINK:
             {
 
-                ASSERT( pDirEnumEntry->TargetNameLength > 0);
-
                 //
                 // Update the metadata for the entry
                 //
@@ -2851,7 +2876,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                                   pObjectInfo->FileId.Vnode,
                                   pObjectInfo->FileId.Unique);
 
-                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
                                     TRUE);
 
                     __try
@@ -2879,7 +2904,8 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                             ntStatus = stIoStatus.Status;
                         }
 
-                        if ( bPurgeExtents)
+                        if ( bPurgeExtents &&
+                             pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                         {
 
                             if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
@@ -2918,7 +2944,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                         SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                     }
 
-                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
+                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
 
                     if ( bPurgeExtents)
                     {
@@ -2970,6 +2996,15 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                     pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
                     pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
 
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                  &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread());
+
+                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                    TRUE);
+
                     pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
 
                     if ( pCCFileObject != NULL)
@@ -2978,6 +3013,14 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
                     }
 
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyEntry Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                  &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread());
+
+                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
+
                     AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
                 }
                 else
@@ -3211,6 +3254,12 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
 
             lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetVolumeState Increment count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
             //
@@ -3306,6 +3355,12 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
             AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
 
             lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetVolumeState Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
         }
         else
         {
@@ -3434,7 +3489,7 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                 //
 
                 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
-                    pCurrentDirEntry->OpenReferenceCount == 0)
+                    pCurrentDirEntry->DirOpenReferenceCount <= 0)
                 {
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -3455,7 +3510,7 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
                                   pCurrentDirEntry,
-                                  pCurrentDirEntry->OpenReferenceCount);
+                                  pCurrentDirEntry->DirOpenReferenceCount);
 
                     //
                     // We pull the short name from the parent tree since it could change below
@@ -3561,9 +3616,9 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
                           pCurrentDirEntry,
-                          pCurrentDirEntry->OpenReferenceCount);
+                          pCurrentDirEntry->DirOpenReferenceCount);
 
-            if( pCurrentDirEntry->OpenReferenceCount == 0)
+            if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
             {
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -3712,7 +3767,9 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
 
         pObjectInfo->Links = DirEnumEntry->Links;
 
-        if( DirEnumEntry->TargetNameLength > 0)
+        if( DirEnumEntry->TargetNameLength > 0 &&
+            ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
+              DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
         {
 
             //
@@ -3754,7 +3811,8 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
 
             AFSReleaseResource( &DirEntry->NonPaged->Lock);
         }
-        else if( DirEntry->NameInformation.TargetName.Length > 0)
+        else if( DirEntry->NameInformation.TargetName.Length > 0 &&
+                 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
         {
 
             AFSAcquireExcl( &DirEntry->NonPaged->Lock,
@@ -3786,7 +3844,8 @@ try_exit:
 NTSTATUS
 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                   IN GUID *AuthGroup,
-                  IN BOOLEAN FastCall)
+                  IN BOOLEAN FastCall,
+                  IN BOOLEAN bSafeToPurge)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
@@ -3944,6 +4003,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
             case AFS_FILE_TYPE_FILE:
             {
 
+                BOOLEAN bPurgeExtents = FALSE;
+
                 //
                 // For a file where the data version has become invalid we need to
                 // fail any current extent requests and purge the cache for the file
@@ -3976,7 +4037,6 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                     {
 
                         IO_STATUS_BLOCK stIoStatus;
-                        BOOLEAN bPurgeExtents = FALSE;
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE_2,
@@ -4005,91 +4065,133 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                             bPurgeExtents = TRUE;
                         }
 
-                        if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+                        if ( bSafeToPurge)
                         {
-                            bPurgeExtents = TRUE;
-
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                          AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                                          &DirEntry->NameInformation.FileName,
-                                          pObjectInfo->FileId.Cell,
-                                          pObjectInfo->FileId.Volume,
-                                          pObjectInfo->FileId.Vnode,
-                                          pObjectInfo->FileId.Unique);
 
-                            ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                        }
-
-                        __try
-                        {
-
-                            CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
-                                          NULL,
-                                          0,
-                                          &stIoStatus);
-
-                            if( !NT_SUCCESS( stIoStatus.Status))
+                            if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
                             {
+                                bPurgeExtents = TRUE;
 
-                                AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                              AFS_TRACE_LEVEL_ERROR,
-                                              "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                               &DirEntry->NameInformation.FileName,
                                               pObjectInfo->FileId.Cell,
                                               pObjectInfo->FileId.Volume,
                                               pObjectInfo->FileId.Vnode,
-                                              pObjectInfo->FileId.Unique,
-                                              stIoStatus.Status,
-                                              stIoStatus.Information);
+                                              pObjectInfo->FileId.Unique);
 
-                                ntStatus = stIoStatus.Status;
+                                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
                             }
 
-                            if ( bPurgeExtents)
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                          &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                          PsGetCurrentThread());
+
+                            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                            TRUE);
+
+                            //
+                            // Release Fcb->Resource to avoid Trend Micro deadlock
+                            //
+
+                            AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
+
+                            __try
                             {
 
-                                if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                           NULL,
-                                                           0,
-                                                           FALSE))
+                                CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
+                                              NULL,
+                                              0,
+                                              &stIoStatus);
+
+                                if( !NT_SUCCESS( stIoStatus.Status))
                                 {
 
                                     AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                                  AFS_TRACE_LEVEL_WARNING,
-                                                  "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                                  AFS_TRACE_LEVEL_ERROR,
+                                                  "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                                   &DirEntry->NameInformation.FileName,
                                                   pObjectInfo->FileId.Cell,
                                                   pObjectInfo->FileId.Volume,
                                                   pObjectInfo->FileId.Vnode,
-                                                  pObjectInfo->FileId.Unique);
+                                                  pObjectInfo->FileId.Unique,
+                                                  stIoStatus.Status,
+                                                  stIoStatus.Information);
 
-                                    SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    ntStatus = stIoStatus.Status;
                                 }
+
+                                if ( bPurgeExtents &&
+                                     pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                                {
+
+                                    if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                               NULL,
+                                                               0,
+                                                               FALSE))
+                                    {
+
+                                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                      AFS_TRACE_LEVEL_WARNING,
+                                                      "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                                      &DirEntry->NameInformation.FileName,
+                                                      pObjectInfo->FileId.Cell,
+                                                      pObjectInfo->FileId.Volume,
+                                                      pObjectInfo->FileId.Vnode,
+                                                      pObjectInfo->FileId.Unique);
+
+                                        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    }
+                                }
+                            }
+                            __except( EXCEPTION_EXECUTE_HANDLER)
+                            {
+                                ntStatus = GetExceptionCode();
+
+                                AFSDbgLogMsg( 0,
+                                              0,
+                                              "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                              &DirEntry->NameInformation.FileName,
+                                              pObjectInfo->FileId.Cell,
+                                              pObjectInfo->FileId.Volume,
+                                              pObjectInfo->FileId.Vnode,
+                                              pObjectInfo->FileId.Unique,
+                                              ntStatus);
+
+                                SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                             }
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                          &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                          PsGetCurrentThread());
+
+                            AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
+
+                            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                                            TRUE);
                         }
-                        __except( EXCEPTION_EXECUTE_HANDLER)
+                        else
                         {
-                            ntStatus = GetExceptionCode();
 
-                            AFSDbgLogMsg( 0,
-                                          0,
-                                          "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
-                                          &DirEntry->NameInformation.FileName,
-                                          pObjectInfo->FileId.Cell,
-                                          pObjectInfo->FileId.Volume,
-                                          pObjectInfo->FileId.Vnode,
-                                          pObjectInfo->FileId.Unique,
-                                          ntStatus);
+                            if ( bPurgeExtents)
+                            {
 
-                            SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                            }
                         }
 
+
                         AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
 
                         bReleaseFcb = FALSE;
 
-                        if ( bPurgeExtents)
+                        if ( bPurgeExtents &&
+                             bSafeToPurge)
                         {
                             AFSFlushExtents( pCurrentFcb,
                                              AuthGroup);
@@ -4098,46 +4200,74 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                 }
 
                 //
-                // Update the metadata for the entry
+                // Update the metadata for the entry but only if it is safe to do so.
+                // If it was determined that a data version change has occurred or
+                // that a pending data verification was required, do not update the
+                // ObjectInfo meta data or the FileObject size information.  That
+                // way it is consistent for the next time that the data is verified
+                // or validated.
                 //
 
-                ntStatus = AFSUpdateMetaData( DirEntry,
-                                              pDirEnumEntry);
-
-                if( !NT_SUCCESS( ntStatus))
+                if ( !(bPurgeExtents && bSafeToPurge))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
-                                  &DirEntry->NameInformation.FileName,
-                                  pObjectInfo->FileId.Cell,
-                                  pObjectInfo->FileId.Volume,
-                                  pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique,
-                                  ntStatus);
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
 
-                    break;
-                }
+                    if( !NT_SUCCESS( ntStatus))
+                    {
 
-                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                      &DirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      ntStatus);
 
-                //
-                // Update file sizes
-                //
+                        break;
+                    }
 
-                if( pObjectInfo->Fcb != NULL)
-                {
-                    FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
+                    ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
 
-                    pObjectInfo->Fcb->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
-                    pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
-                    pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
+                    //
+                    // Update file sizes
+                    //
 
-                    if ( pCCFileObject != NULL)
+                    if( pObjectInfo->Fcb != NULL)
                     {
-                        CcSetFileSizes( pCCFileObject,
-                                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        FILE_OBJECT *pCCFileObject;
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                      &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread());
+
+                        AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                        TRUE);
+
+                        pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
+
+                        pObjectInfo->Fcb->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
+                        pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
+                        pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
+
+                        if ( pCCFileObject != NULL)
+                        {
+                            CcSetFileSizes( pCCFileObject,
+                                            (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        }
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSValidateEntry Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                      &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread());
+
+                        AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
                     }
                 }
                 break;
@@ -4265,7 +4395,7 @@ AFSInitializeSpecialShareNameList()
     {
 
         RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\srvsvc");
+                              L"PIPE");
 
         pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
                                                0);
@@ -4330,7 +4460,7 @@ AFSInitializeSpecialShareNameList()
         // Set valid entry
         //
 
-        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
+        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
 
         pDirNode->NameInformation.FileName.Length = uniShareName.Length;
 
@@ -4349,92 +4479,6 @@ AFSInitializeSpecialShareNameList()
 
         pLastDirNode = pDirNode;
 
-        RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\wkssvc");
-
-        pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
-                                               0);
-
-        if( pObjectInfoCB == NULL)
-        {
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
-                      pObjectInfoCB);
-
-        pObjectInfoCB->ObjectReferenceCount = 1;
-
-        pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
-
-        ulEntryLength = sizeof( AFSDirectoryCB) +
-                                     uniShareName.Length;
-
-        pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
-                                                                  ulEntryLength,
-                                                                  AFS_DIR_ENTRY_TAG);
-
-        if( pDirNode == NULL)
-        {
-
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
-                                                                                   sizeof( AFSNonPagedDirectoryCB),
-                                                                                   AFS_DIR_ENTRY_NP_TAG);
-
-        if( pNonPagedDirEntry == NULL)
-        {
-
-            ExFreePool( pDirNode);
-
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        RtlZeroMemory( pDirNode,
-                       ulEntryLength);
-
-        RtlZeroMemory( pNonPagedDirEntry,
-                       sizeof( AFSNonPagedDirectoryCB));
-
-        ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
-
-        pDirNode->NonPaged = pNonPagedDirEntry;
-
-        pDirNode->ObjectInformation = pObjectInfoCB;
-
-        //
-        // Set valid entry
-        //
-
-        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
-
-        pDirNode->NameInformation.FileName.Length = uniShareName.Length;
-
-        pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
-
-        pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
-
-        RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
-                       uniShareName.Buffer,
-                       pDirNode->NameInformation.FileName.Length);
-
-        pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
-                                                                       TRUE);
-
-        pLastDirNode->ListEntry.fLink = pDirNode;
-
-        pDirNode->ListEntry.bLink = pLastDirNode;
-
-        pLastDirNode = pDirNode;
 
         RtlInitUnicodeString( &uniShareName,
                               L"IPC$");
@@ -4567,38 +4611,14 @@ AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
     __Enter
     {
 
-        //
-        // Build up the entire name here. We are guaranteed that if there is a
-        // secondary name, it is pointing to a portion of the share name buffer
-        //
-
-        if( SecondaryName->Length > 0 &&
-            SecondaryName->Buffer != NULL)
-        {
-
-            uniFullShareName = *SecondaryName;
-
-            //
-            // The calling routine strips off the leading slash so add it back in
-            //
-
-            uniFullShareName.Buffer--;
-            uniFullShareName.Length += sizeof( WCHAR);
-            uniFullShareName.MaximumLength += sizeof( WCHAR);
 
-            //
-            // And the share name
-            //
-
-            uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
-            uniFullShareName.Length += ShareName->Length;
-            uniFullShareName.MaximumLength += ShareName->Length;
-        }
-        else
-        {
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE_2,
+                      "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
+                      ShareName,
+                      SecondaryName);
 
-            uniFullShareName = *ShareName;
-        }
+        uniFullShareName = *ShareName;
 
         //
         // Generate our hash value
@@ -4708,7 +4728,7 @@ AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
 
             pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
 
-            if( pCurrentDirEntry->OpenReferenceCount == 0)
+            if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
             {
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
@@ -4882,21 +4902,69 @@ try_exit:
     return ntStatus;
 }
 
-BOOLEAN
-AFSIsRelativeName( IN UNICODE_STRING *Name)
-{
+BOOLEAN
+AFSIsRelativeName( IN UNICODE_STRING *Name)
+{
+
+    BOOLEAN bIsRelative = FALSE;
+
+    if( Name->Length > 0 &&
+        Name->Buffer[ 0] != L'\\')
+    {
+
+        bIsRelative = TRUE;
+    }
+
+    return bIsRelative;
+}
+
+BOOLEAN
+AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
+{
+    UNICODE_STRING uniTempName;
+    BOOLEAN        bIsAbsolute = FALSE;
+
+    //
+    // An absolute AFS path must begin with \afs\... or equivalent
+    //
+
+    if ( Name->Length == 0 ||
+         Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
+         Name->Buffer[ 0] != L'\\' ||
+         Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
+    {
+
+        return FALSE;
+    }
 
-    BOOLEAN bIsRelative = FALSE;
+    uniTempName.Length = AFSMountRootName.Length;
+    uniTempName.MaximumLength = AFSMountRootName.Length;
+
+    uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                            uniTempName.MaximumLength,
+                                                            AFS_NAME_BUFFER_TWO_TAG);
 
-    if( Name->Buffer[ 0] != L'\\')
+    if( uniTempName.Buffer == NULL)
     {
 
-        bIsRelative = TRUE;
+        return FALSE;
     }
 
-    return bIsRelative;
+    RtlCopyMemory( uniTempName.Buffer,
+                   Name->Buffer,
+                   AFSMountRootName.Length);
+
+    bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
+                                                 &AFSMountRootName,
+                                                 TRUE));
+
+    AFSExFreePoolWithTag( uniTempName.Buffer,
+                          AFS_NAME_BUFFER_TWO_TAG);
+
+    return bIsAbsolute;
 }
 
+
 void
 AFSUpdateName( IN UNICODE_STRING *Name)
 {
@@ -5033,7 +5101,7 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
 
             pNameArray->LinkCount = 0;
 
-            lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -5120,7 +5188,7 @@ AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
 
         pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
 
-        lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -5238,7 +5306,7 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
                 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
             }
 
-            lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -5305,7 +5373,7 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
 
             pCurrentElement = &NameArray->ElementArray[ lElement];
 
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -5313,6 +5381,8 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
                           &pCurrentElement->DirectoryCB->NameInformation.FileName,
                           pCurrentElement->DirectoryCB,
                           lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
@@ -5388,7 +5458,7 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
 
         lCount = InterlockedIncrement( &NameArray->Count);
 
-        lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
+        lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -5397,6 +5467,8 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
                       DirectoryCB,
                       lCount);
 
+        ASSERT( lCount >= 2);
+
         pCurrentElement->DirectoryCB = DirectoryCB;
 
         pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
@@ -5460,7 +5532,7 @@ AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
             try_return( pCurrentElement);
         }
 
-        lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+        lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -5469,6 +5541,8 @@ AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
                       NameArray->CurrentEntry->DirectoryCB,
                       lCount);
 
+        ASSERT( lCount >= 0);
+
         NameArray->CurrentEntry->DirectoryCB = NULL;
 
         lCount = InterlockedDecrement( &NameArray->Count);
@@ -5616,7 +5690,7 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
 
             pCurrentElement = &NameArray->ElementArray[ lElement];
 
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -5624,6 +5698,8 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
                           &pCurrentElement->DirectoryCB->NameInformation.FileName,
                           pCurrentElement->DirectoryCB,
                           lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         RtlZeroMemory( NameArray,
@@ -5643,7 +5719,7 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
 
             NameArray->LinkCount = 0;
 
-            lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
+            lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -5922,7 +5998,7 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
             // Increment the open reference and handle on the node
             //
 
-            lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -6237,7 +6313,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       pVolumeCB,
                       lCount);
 
-        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -6284,7 +6360,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                 if( pDirectoryEntry != NULL)
                 {
 
-                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -6293,11 +6369,13 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   pDirectoryEntry,
                                   NULL,
                                   lCount);
+
+                    ASSERT( lCount >= 0);
                 }
                 else
                 {
 
-                    lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -6306,6 +6384,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   pParentDirEntry,
                                   NULL,
                                   lCount);
+
+                    ASSERT( lCount >= 0);
                 }
             }
 
@@ -6361,7 +6441,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Remove the reference made above
         //
 
-        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -6371,6 +6451,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       NULL,
                       lCount);
 
+        ASSERT( lCount >= 0);
+
 try_exit:
 
         if( pDirEntry != NULL)
@@ -6461,6 +6543,8 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
+        ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
         pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
 
         pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
@@ -6469,7 +6553,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         if( ParentObjectInfo != NULL)
         {
-            lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( ParentObjectInfo);
         }
 
         //
@@ -6535,6 +6619,74 @@ try_exit:
     return pObjectInfo;
 }
 
+LONG
+AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    if ( ObjectInfo->ObjectReferenceCount == 0)
+    {
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+    }
+    else
+    {
+
+        AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                          TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        if ( lCount == 1)
+        {
+
+            AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+            AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                            TRUE);
+        }
+    }
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+LONG
+AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                      TRUE);
+
+    lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+
+    if ( lCount == 0)
+    {
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+    }
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+
+
 void
 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 {
@@ -6542,6 +6694,19 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
     BOOLEAN bAcquiredTreeLock = FALSE;
     LONG lCount;
 
+    if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
+    {
+
+        //
+        // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
+        // embedded in the VolumeCB.
+        //
+
+        ASSERT( TRUE);
+
+        return;
+    }
+
     if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
     {
 
@@ -6605,7 +6770,7 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
     if( ObjectInfo->ParentObjectInformation != NULL)
     {
 
-        lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
+        lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
     }
 
     if( bAcquiredTreeLock)
@@ -6624,6 +6789,8 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
         AFSReleaseFid( &ObjectInfo->FileId);
     }
 
+    ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
     ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
     AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
@@ -6810,7 +6977,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                       pVolumeCB,
                       lCount);
 
-        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -6857,7 +7024,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                 if( pDirectoryEntry != NULL)
                 {
 
-                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -6866,19 +7033,23 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                   pDirectoryEntry,
                                   NULL,
                                   lCount);
+
+                    ASSERT( lCount >= 0);
                 }
                 else
                 {
 
-                    lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
                                   &pParentDirEntry->NameInformation.FileName,
                                   pParentDirEntry,
                                   NULL,
                                   lCount);
+
+                    ASSERT( lCount >= 0);
                 }
             }
 
@@ -6908,7 +7079,7 @@ try_exit:
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
+                          "AFSEvaluateRootEntry Decrement2 count on volume %08lX Cnt %d\n",
                           pVolumeCB,
                           lCount);
         }
@@ -6968,12 +7139,27 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
             {
 
-                AFSAcquireExcl( &Fcb->NPFcb->Resource,
-                                TRUE);
+                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupEntry Acquiring Fcb lock %08lX SHARED %08lX\n",
+                              &Fcb->NPFcb->Resource,
+                              PsGetCurrentThread());
+
+                AFSAcquireShared( &Fcb->NPFcb->Resource,
+                                  TRUE);
 
                 if( Fcb->OpenReferenceCount > 0)
                 {
 
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCleanupEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                  &Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread());
+
+                    AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
+                                    TRUE);
+
                     __try
                     {
 
@@ -6998,21 +7184,25 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                             ntStatus = stIoStatus.Status;
                         }
 
-                        if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                                   NULL,
-                                                   0,
-                                                   FALSE))
+                        if (  Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                          AFS_TRACE_LEVEL_WARNING,
-                                          "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                          Fcb->ObjectInformation->FileId.Cell,
-                                          Fcb->ObjectInformation->FileId.Volume,
-                                          Fcb->ObjectInformation->FileId.Vnode,
-                                          Fcb->ObjectInformation->FileId.Unique);
+                            if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                       NULL,
+                                                       0,
+                                                       FALSE))
+                            {
 
-                            SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                              AFS_TRACE_LEVEL_WARNING,
+                                              "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                              Fcb->ObjectInformation->FileId.Cell,
+                                              Fcb->ObjectInformation->FileId.Volume,
+                                              Fcb->ObjectInformation->FileId.Vnode,
+                                              Fcb->ObjectInformation->FileId.Unique);
+
+                                SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                            }
                         }
                     }
                     __except( EXCEPTION_EXECUTE_HANDLER)
@@ -7031,8 +7221,22 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
 
                         SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                     }
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCleanupFcb Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                  &Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread());
+
+                    AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
                 }
 
+                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupEntry Releasing Fcb lock %08lX SHARED %08lX\n",
+                              &Fcb->NPFcb->Resource,
+                              PsGetCurrentThread());
+
                 AFSReleaseResource( &Fcb->NPFcb->Resource);
 
                 //
@@ -7110,82 +7314,102 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
               ( 0 != Fcb->Specific.File.ExtentCount &&
                 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
                 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
-                                        (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
-            AFSAcquireExcl( &Fcb->NPFcb->Resource,
-                            ForceFlush))
+                                        (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
         {
 
-            __try
-            {
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCleanupFcb Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                          &Fcb->NPFcb->SectionObjectResource,
+                          PsGetCurrentThread());
 
-                CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
-                              NULL,
-                              0,
-                              &stIoStatus);
+            if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
+            {
 
-                if( !NT_SUCCESS( stIoStatus.Status))
+                __try
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
-                                  Fcb->ObjectInformation->FileId.Cell,
-                                  Fcb->ObjectInformation->FileId.Volume,
-                                  Fcb->ObjectInformation->FileId.Vnode,
-                                  Fcb->ObjectInformation->FileId.Unique,
-                                  stIoStatus.Status,
-                                  stIoStatus.Information);
-
-                    ntStatus = stIoStatus.Status;
-                }
-
-                if( ForceFlush)
-                {
+                    CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
+                                  NULL,
+                                  0,
+                                  &stIoStatus);
 
-                    if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                               NULL,
-                                               0,
-                                               FALSE))
+                    if( !NT_SUCCESS( stIoStatus.Status))
                     {
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                      AFS_TRACE_LEVEL_WARNING,
-                                      "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                       Fcb->ObjectInformation->FileId.Cell,
                                       Fcb->ObjectInformation->FileId.Volume,
                                       Fcb->ObjectInformation->FileId.Vnode,
-                                      Fcb->ObjectInformation->FileId.Unique);
+                                      Fcb->ObjectInformation->FileId.Unique,
+                                      stIoStatus.Status,
+                                      stIoStatus.Information);
 
-                        SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        ntStatus = stIoStatus.Status;
+                    }
+
+                    if( ForceFlush &&
+                        Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                    {
+
+                        if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                          AFS_TRACE_LEVEL_WARNING,
+                                          "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                          Fcb->ObjectInformation->FileId.Cell,
+                                          Fcb->ObjectInformation->FileId.Volume,
+                                          Fcb->ObjectInformation->FileId.Vnode,
+                                          Fcb->ObjectInformation->FileId.Unique);
+
+                            SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
                     }
                 }
-            }
-            __except( EXCEPTION_EXECUTE_HANDLER)
-            {
+                __except( EXCEPTION_EXECUTE_HANDLER)
+                {
 
-                ntStatus = GetExceptionCode();
+                    ntStatus = GetExceptionCode();
 
-                AFSDbgLogMsg( 0,
-                              0,
-                              "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
-                              Fcb->ObjectInformation->FileId.Cell,
-                              Fcb->ObjectInformation->FileId.Volume,
-                              Fcb->ObjectInformation->FileId.Vnode,
-                              Fcb->ObjectInformation->FileId.Unique,
-                              ntStatus);
-            }
+                    AFSDbgLogMsg( 0,
+                                  0,
+                                  "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                  Fcb->ObjectInformation->FileId.Cell,
+                                  Fcb->ObjectInformation->FileId.Volume,
+                                  Fcb->ObjectInformation->FileId.Vnode,
+                                  Fcb->ObjectInformation->FileId.Unique,
+                                  ntStatus);
+                }
 
-            AFSReleaseResource( &Fcb->NPFcb->Resource);
+                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupFcb Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                              &Fcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread());
 
-            if( Fcb->OpenReferenceCount <= 0)
-            {
+                AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
 
-                //
-                // Tear em down we'll not be needing them again
-                //
+                if( Fcb->OpenReferenceCount <= 0)
+                {
 
-                AFSTearDownFcbExtents( Fcb,
-                                       NULL);
+                    //
+                    // Tear em down we'll not be needing them again
+                    //
+
+                    AFSTearDownFcbExtents( Fcb,
+                                           NULL);
+                }
+            }
+            else
+            {
+
+                ntStatus = STATUS_RETRY;
             }
         }
 
@@ -7766,6 +7990,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSServerName = LibraryInit->AFSServerName;
 
+        AFSMountRootName = LibraryInit->AFSMountRootName;
+
         AFSDebugFlags = LibraryInit->AFSDebugFlags;
 
         //
@@ -7844,6 +8070,12 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
             lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeLibrary Increment count on volume %08lX Cnt %d\n",
+                          AFSGlobalRoot,
+                          lCount);
+
             AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
             try_return( ntStatus);
@@ -7872,6 +8104,12 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeLibrary Decrement count on volume %08lX Cnt %d\n",
+                      AFSGlobalRoot,
+                      lCount);
+
         AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
         AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
@@ -8051,9 +8289,15 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 pObjectInfo = &pVolumeCB->ObjectInformation;
 
-                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
+                              pVolumeCB,
+                              lCount);
             }
             else
             {
@@ -8065,7 +8309,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
+                              "AFSGetObjectStatus Decrement2 count on volume %08lX Cnt %d\n",
                               pVolumeCB,
                               lCount);
 
@@ -8082,7 +8326,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     // Reference the node so it won't be torn down
                     //
 
-                    lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -8162,11 +8406,11 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
+                          "AFSGetObjectStatus Increment2 count on volume %08lX Cnt %d\n",
                           pVolumeCB,
                           lCount);
 
-            lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -8206,7 +8450,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
+                                      "AFSGetObjectStatus Decrement3 count on volume %08lX Cnt %d\n",
                                       pVolumeCB,
                                       lCount);
                     }
@@ -8214,7 +8458,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     if( pDirectoryEntry != NULL)
                     {
 
-                        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -8223,11 +8467,13 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       pDirectoryEntry,
                                       NULL,
                                       lCount);
+
+                        ASSERT( lCount >= 0);
                     }
                     else
                     {
 
-                        lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -8236,6 +8482,8 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       pParentDirEntry,
                                       NULL,
                                       lCount);
+
+                        ASSERT( lCount >= 0);
                     }
                 }
 
@@ -8248,11 +8496,21 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             // Remove the reference made above
             //
 
-            lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
 
             pObjectInfo = pDirectoryEntry->ObjectInformation;
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             if( pVolumeCB != NULL)
             {
@@ -8261,9 +8519,9 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
+                              "AFSGetObjectStatus Decrement4 count on volume %08lX Cnt %d\n",
                               pVolumeCB,
-                              pVolumeCB->VolumeReferenceCount);
+                              lCount);
             }
         }
 
@@ -8312,7 +8570,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
         }
 
         if( pNameArray != NULL)
@@ -8405,7 +8663,17 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         if( pDirEntry != NULL)
         {
-            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -8433,7 +8701,17 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
-        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                      &pDirEntry->NameInformation.FileName,
+                      pDirEntry,
+                      NULL,
+                      lCount);
+
+        ASSERT( lCount >= 0);
 
 try_exit:
 
@@ -8941,6 +9219,8 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                     AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
                                     TRUE);
 
+                    ObjectInfo->Links = 0;
+
                     ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
 
                     KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
@@ -9016,12 +9296,12 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                         if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
                         {
 
-                            if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
-                            {
+                            AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
 
-                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+                            bExtentsLocked = FALSE;
 
-                                bExtentsLocked = FALSE;
+                            if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+                            {
 
                                 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
 
@@ -9033,14 +9313,24 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                             else
                             {
 
-                                __try
-                                {
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                              &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                              PsGetCurrentThread());
 
-                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+                                AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                                TRUE);
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                bLocked = FALSE;
 
-                                    bExtentsLocked = FALSE;
+                                __try
+                                {
 
-                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                    if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                        !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
                                                               NULL,
                                                               0,
                                                               FALSE))
@@ -9078,11 +9368,36 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
                                     SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                                 }
+
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                              &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                              PsGetCurrentThread());
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
                             }
                         }
                         else
                         {
 
+                            AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                            bExtentsLocked = FALSE;
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                          &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                          PsGetCurrentThread());
+
+                            AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                            TRUE);
+
+                            AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                            bLocked = FALSE;
+
                             //
                             // Must build a list of non-dirty ranges from the beginning of the file
                             // to the end.  There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
@@ -9107,10 +9422,6 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                      ulByteRangeCount == 0)
                                 {
 
-                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
-                                    bExtentsLocked = FALSE;
-
                                     for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
                                     {
 
@@ -9120,7 +9431,8 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
                                             ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
 
-                                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                            if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                                !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
                                                                       &ByteRangeList[ulIndex].FileOffset,
                                                                       ulSize,
                                                                       FALSE))
@@ -9158,6 +9470,10 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                     // This could deadlock but we do not have much choice.
                                     //
 
+                                    AFSAcquireExcl(  &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                                    TRUE);
+                                    bExtentsLocked = TRUE;
+
                                     le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
 
                                     ulProcessCount = 0;
@@ -9292,6 +9608,14 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                               ObjectInfo->FileId.Unique,
                                               ntStatus);
                             }
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
+                                          &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                          PsGetCurrentThread());
+
+                            AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
                         }
                     }
 
@@ -9321,7 +9645,8 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
         if( ObjectInfo != NULL)
         {
-            InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+
+            AFSObjectInfoDecrement( ObjectInfo);
         }
     }