Windows: Fcb sectionObjectResource
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index dc26549..15af3e2 100644 (file)
@@ -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))
@@ -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,
@@ -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;
@@ -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))
-                        {
-                            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
+                        if ( bSafeToPurge)
                         {
 
-                            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);
+
+                                    ntStatus = stIoStatus.Status;
+                                }
+
+                                if ( bPurgeExtents &&
+                                     pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                                {
+
+                                    if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                               NULL,
+                                                               0,
+                                                               FALSE))
+                                    {
 
-                                    SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                        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;
@@ -4598,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,
@@ -4778,7 +4908,8 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
 
     BOOLEAN bIsRelative = FALSE;
 
-    if( Name->Buffer[ 0] != L'\\')
+    if( Name->Length > 0 &&
+        Name->Buffer[ 0] != L'\\')
     {
 
         bIsRelative = TRUE;
@@ -4787,6 +4918,53 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
     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;
+    }
+
+    uniTempName.Length = AFSMountRootName.Length;
+    uniTempName.MaximumLength = AFSMountRootName.Length;
+
+    uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                            uniTempName.MaximumLength,
+                                                            AFS_NAME_BUFFER_TWO_TAG);
+
+    if( uniTempName.Buffer == NULL)
+    {
+
+        return FALSE;
+    }
+
+    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)
 {
@@ -4923,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,
@@ -5010,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,
@@ -5128,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,
@@ -5195,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,
@@ -5203,6 +5381,8 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
                           &pCurrentElement->DirectoryCB->NameInformation.FileName,
                           pCurrentElement->DirectoryCB,
                           lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
@@ -5278,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,
@@ -5287,6 +5467,8 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
                       DirectoryCB,
                       lCount);
 
+        ASSERT( lCount >= 2);
+
         pCurrentElement->DirectoryCB = DirectoryCB;
 
         pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
@@ -5350,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,
@@ -5359,6 +5541,8 @@ AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
                       NameArray->CurrentEntry->DirectoryCB,
                       lCount);
 
+        ASSERT( lCount >= 0);
+
         NameArray->CurrentEntry->DirectoryCB = NULL;
 
         lCount = InterlockedDecrement( &NameArray->Count);
@@ -5506,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,
@@ -5514,6 +5698,8 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
                           &pCurrentElement->DirectoryCB->NameInformation.FileName,
                           pCurrentElement->DirectoryCB,
                           lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         RtlZeroMemory( NameArray,
@@ -5533,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,
@@ -6127,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,
@@ -6174,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,
@@ -6183,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,
@@ -6196,6 +6384,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   pParentDirEntry,
                                   NULL,
                                   lCount);
+
+                    ASSERT( lCount >= 0);
                 }
             }
 
@@ -6251,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,
@@ -6261,6 +6451,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       NULL,
                       lCount);
 
+        ASSERT( lCount >= 0);
+
 try_exit:
 
         if( pDirEntry != NULL)
@@ -6502,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))
     {
 
@@ -6772,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,
@@ -6819,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,
@@ -6828,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);
                 }
             }
 
@@ -6870,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);
         }
@@ -6930,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
                     {
 
@@ -6960,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)
@@ -6993,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);
 
                 //
@@ -7075,7 +7317,13 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                                         (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
         {
 
-            if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush))
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCleanupFcb Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
+                          &Fcb->NPFcb->SectionObjectResource,
+                          PsGetCurrentThread());
+
+            if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
             {
 
                 __try
@@ -7102,7 +7350,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                         ntStatus = stIoStatus.Status;
                     }
 
-                    if( ForceFlush)
+                    if( ForceFlush &&
+                        Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                     {
 
                         if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
@@ -7138,7 +7387,13 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                                   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());
+
+                AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
 
                 if( Fcb->OpenReferenceCount <= 0)
                 {
@@ -7735,6 +7990,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSServerName = LibraryInit->AFSServerName;
 
+        AFSMountRootName = LibraryInit->AFSMountRootName;
+
         AFSDebugFlags = LibraryInit->AFSDebugFlags;
 
         //
@@ -7813,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);
@@ -7841,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);
@@ -8023,6 +8292,12 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                 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
             {
@@ -8034,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);
 
@@ -8131,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,
@@ -8175,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);
                     }
@@ -8183,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,
@@ -8192,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,
@@ -8205,6 +8482,8 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       pParentDirEntry,
                                       NULL,
                                       lCount);
+
+                        ASSERT( lCount >= 0);
                     }
                 }
 
@@ -8217,7 +8496,17 @@ 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;
 
@@ -8230,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);
             }
         }
 
@@ -8374,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);
@@ -8402,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:
 
@@ -8910,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,
@@ -8985,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);
 
@@ -9002,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);
 
-                                    bExtentsLocked = FALSE;
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                bLocked = FALSE;
+
+                                __try
+                                {
 
-                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                    if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                        !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
                                                               NULL,
                                                               0,
                                                               FALSE))
@@ -9047,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)
@@ -9076,10 +9422,6 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                      ulByteRangeCount == 0)
                                 {
 
-                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
-                                    bExtentsLocked = FALSE;
-
                                     for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
                                     {
 
@@ -9089,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))
@@ -9127,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;
@@ -9261,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);
                         }
                     }