Windows: AFSInitDirEntry allocated ObjInfoCBs valid
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index c7c90d7..3acfa8e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * - Redistributions of source code must retain the above copyright notice,
  *   this list of conditions and the following disclaimer.
  * - Redistributions in binary form must reproduce the above copyright
- *   notice,
- *   this list of conditions and the following disclaimer in the
- *   documentation
- *   and/or other materials provided with the distribution.
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
  *   nor the names of their contributors may be used to endorse or promote
  *   products derived from this software without specific prior written
 //
 
 ULONG
-AFSExceptionFilter( IN ULONG Code,
+AFSExceptionFilter( IN CHAR *FunctionString,
+                    IN ULONG Code,
                     IN PEXCEPTION_POINTERS ExceptPtrs)
 {
 
+    UNREFERENCED_PARAMETER(Code);
     PEXCEPTION_RECORD ExceptRec;
     PCONTEXT Context;
 
@@ -65,14 +65,15 @@ AFSExceptionFilter( IN ULONG Code,
 
         Context = ExceptPtrs->ContextRecord;
 
-        AFSDbgLogMsg( 0,
+        AFSDbgTrace(( 0,
                       0,
-                      "AFSExceptionFilter (Library) - EXR %p CXR %p Code %08lX Address %p Routine %p\n",
+                      "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
                       ExceptRec,
                       Context,
+                      FunctionString,
                       ExceptRec->ExceptionCode,
                       ExceptRec->ExceptionAddress,
-                      (void *)AFSExceptionFilter);
+                      (void *)AFSExceptionFilter));
 
         DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
 
@@ -145,13 +146,13 @@ AFSLibExAllocatePoolWithTag( IN POOL_TYPE  PoolType,
         else
         {
 
-            AFSDbgLogMsg( 0,
+            AFSDbgTrace(( 0,
                           0,
                           "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
                           PoolType,
                           NumberOfBytes,
                           Tag,
-                          PsGetCurrentThread());
+                          PsGetCurrentThread()));
 
             AFSBreakPoint();
         }
@@ -270,11 +271,11 @@ void
 AFSReleaseResource( IN PERESOURCE Resource)
 {
 
-    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
+                  "AFSReleaseResource Releasing lock %p Thread %08lX\n",
                   Resource,
-                  PsGetCurrentThread());
+                  PsGetCurrentThread()));
 
     ExReleaseResourceLite( Resource);
 
@@ -287,11 +288,11 @@ void
 AFSConvertToShared( IN PERESOURCE Resource)
 {
 
-    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
+                  "AFSConvertToShared Converting lock %p Thread %08lX\n",
                   Resource,
-                  PsGetCurrentThread());
+                  PsGetCurrentThread()));
 
     ExConvertExclusiveToSharedLite( Resource);
 
@@ -361,7 +362,6 @@ AFSLockSystemBuffer( IN PIRP Irp,
                      IN ULONG Length)
 {
 
-    NTSTATUS Status = STATUS_SUCCESS;
     void *pAddress = NULL;
 
     if( Irp->MdlAddress != NULL)
@@ -403,9 +403,11 @@ AFSLockSystemBuffer( IN PIRP Irp,
                 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
 
             }
-            __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+            __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
             {
 
+                AFSDumpTraceFilesFnc();
+
                 IoFreeMdl( Irp->MdlAddress );
                 Irp->MdlAddress = NULL;
                 pAddress = NULL;
@@ -419,15 +421,15 @@ AFSLockSystemBuffer( IN PIRP Irp,
 void *
 AFSLockUserBuffer( IN void *UserBuffer,
                    IN ULONG BufferLength,
-                                  OUT MDL ** Mdl)
+                   OUT MDL ** Mdl)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     void *pAddress = NULL;
-       MDL *pMdl = NULL;
+    MDL *pMdl = NULL;
 
-       __Enter
-       {
+    __Enter
+    {
 
         pMdl = IoAllocateMdl( UserBuffer,
                               BufferLength,
@@ -435,11 +437,11 @@ AFSLockUserBuffer( IN void *UserBuffer,
                               FALSE,
                               NULL);
 
-               if( pMdl == NULL)
-               {
+            if( pMdl == NULL)
+            {
 
-                       try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-               }
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
 
         //
         //  Lock the new Mdl in memory.
@@ -449,25 +451,27 @@ AFSLockUserBuffer( IN void *UserBuffer,
         {
 
             MmProbeAndLockPages( pMdl,
-                                                                KernelMode,
+                                 KernelMode,
                                  IoWriteAccess);
 
             pAddress = MmGetSystemAddressForMdlSafe( pMdl,
-                                                                                                        NormalPagePriority);
+                                                     NormalPagePriority);
         }
-        __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+        __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
         {
 
+            AFSDumpTraceFilesFnc();
+
             IoFreeMdl( pMdl);
             pMdl = NULL;
             pAddress = NULL;
         }
 
-               if( pMdl != NULL)
-               {
+        if( pMdl != NULL)
+        {
 
-                       *Mdl = pMdl;
-               }
+            *Mdl = pMdl;
+        }
 
 try_exit:
 
@@ -537,7 +541,6 @@ AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    void *pMappedBuffer = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
     KAPC stApcState;
 
@@ -624,8 +627,8 @@ AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
 {
 
+    UNREFERENCED_PARAMETER(DeviceObject);
     NTSTATUS            ntStatus = STATUS_INVALID_DEVICE_REQUEST;
-    PIO_STACK_LOCATION  pIrpSp = IoGetCurrentIrpStackLocation( Irp);
 
     AFSCompleteRequest( Irp,
                         ntStatus);
@@ -640,7 +643,6 @@ AFSInitializeGlobalDirectoryEntries()
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDirectoryCB *pDirNode = NULL;
     ULONG ulEntryLength = 0;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfoCB = NULL;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
     LONG lCount;
@@ -658,21 +660,22 @@ AFSInitializeGlobalDirectoryEntries()
         if( pObjectInfoCB == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_GLOBAL);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
+                      "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
                       pObjectInfoCB,
-                      lCount);
+                      lCount));
 
         ntStatus = STATUS_SUCCESS;
 
@@ -686,15 +689,33 @@ AFSInitializeGlobalDirectoryEntries()
         if( pDirNode == NULL)
         {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
+                          "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
                                                                                    sizeof( AFSNonPagedDirectoryCB),
                                                                                    AFS_DIR_ENTRY_NP_TAG);
@@ -704,11 +725,24 @@ AFSInitializeGlobalDirectoryEntries()
 
             ExFreePool( pDirNode);
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
+                          "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -765,21 +799,22 @@ AFSInitializeGlobalDirectoryEntries()
         if( pObjectInfoCB == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_GLOBAL);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
+                      "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
                       pObjectInfoCB,
-                      lCount);
+                      lCount));
 
         ntStatus = STATUS_SUCCESS;
 
@@ -793,11 +828,33 @@ AFSInitializeGlobalDirectoryEntries()
         if( pDirNode == NULL)
         {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
+
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
                                                                                    sizeof( AFSNonPagedDirectoryCB),
                                                                                    AFS_DIR_ENTRY_NP_TAG);
@@ -807,7 +864,20 @@ AFSInitializeGlobalDirectoryEntries()
 
             ExFreePool( pDirNode);
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -864,7 +934,20 @@ try_exit:
             if( AFSGlobalDotDirEntry != NULL)
             {
 
-                AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
+                lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
+                                                 AFS_OBJECT_REFERENCE_GLOBAL);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                              AFSGlobalDotDirEntry->ObjectInformation,
+                              lCount));
+
+                if ( lCount == 0)
+                {
+
+                    AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
+                }
 
                 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
 
@@ -878,7 +961,20 @@ try_exit:
             if( AFSGlobalDotDotDirEntry != NULL)
             {
 
-                AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
+                lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
+                                                 AFS_OBJECT_REFERENCE_GLOBAL);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
+                              AFSGlobalDotDotDirEntry->ObjectInformation,
+                              lCount));
+
+                if ( lCount == 0)
+                {
+
+                    AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
+                }
 
                 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
 
@@ -905,12 +1001,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
     AFSDirectoryCB *pDirNode = NULL;
     NTSTATUS ntStatus = STATUS_SUCCESS;
     ULONG ulEntryLength = 0;
-    AFSDirEnumEntry *pDirEnumCB = NULL;
-    AFSFileID stTargetFileID;
-    AFSFcb *pVcb = NULL;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfoCB = NULL;
-    BOOLEAN bAllocatedObjectCB = FALSE;
     ULONGLONG ullIndex = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
     LONG lCount;
@@ -918,14 +1009,14 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
                       FileName,
                       ParentObjectInfo->FileId.Cell,
                       ParentObjectInfo->FileId.Volume,
                       ParentObjectInfo->FileId.Vnode,
-                      ParentObjectInfo->FileId.Unique);
+                      ParentObjectInfo->FileId.Unique));
 
         //
         // First thing is to locate/create our object information block
@@ -941,8 +1032,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                                        ullIndex,
                                        (AFSBTreeEntry **)&pObjectInfoCB);
 
-        if( !NT_SUCCESS( ntStatus) ||
-            pObjectInfoCB == NULL)
+        if( !NT_SUCCESS( ntStatus))
         {
 
             //
@@ -960,23 +1050,114 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
             }
 
-            bAllocatedObjectCB = TRUE;
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
+                          "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
                           pObjectInfoCB,
                           ParentObjectInfo,
-                          FileName);
+                          FileName));
+
+            //
+            // If we allocated the object information cb then set the information
+            //
+
+            pObjectInfoCB->FileId = DirEnumEntry->FileId;
+
+            pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
+
+            pObjectInfoCB->FileType = DirEnumEntry->FileType;
+
+            pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
+
+            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+                pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
+            {
+
+                pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            }
+
+            if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
+            {
+
+                if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                {
+
+                    pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+                }
+                else
+                {
+
+                    pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+                }
+            }
+
+            //
+            // 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
+            //
+
+            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
+                pObjectInfoCB->TargetFileId.Vnode == 0 &&
+                pObjectInfoCB->TargetFileId.Unique == 0 &&
+                (TargetName == NULL || TargetName->Length == 0))
+            {
+
+                //
+                // This will ensure we perform a validation on the node
+                //
+
+                pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
+            }
+
+            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
+            {
+
+                SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
+            }
+
+            SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+        }
+
+        if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
+
+            pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
+
+            pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
+
+            pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
+
+            pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
+
+            pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
+
+            pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
+
+            pObjectInfoCB->Links = DirEnumEntry->Links;
+
+            pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
+
+            pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
+
+            ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
         }
 
-        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        //
+        // This reference count is either stored into the return DirectoryCB
+        // or released before function exit.
+        //
+
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_DIRENTRY);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
+                      "AFSInitDirEntry Increment count on object %p Cnt %d\n",
                       pObjectInfoCB,
-                      lCount);
+                      lCount));
 
         AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
 
@@ -1001,6 +1182,11 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                                 sizeof( AFSNonPagedDirectoryCB),
                                                                                 AFS_DIR_ENTRY_NP_TAG);
@@ -1059,7 +1245,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                                                                            TRUE);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
                       pDirNode,
@@ -1067,7 +1253,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                       ParentObjectInfo->FileId.Cell,
                       ParentObjectInfo->FileId.Volume,
                       ParentObjectInfo->FileId.Vnode,
-                      ParentObjectInfo->FileId.Unique);
+                      ParentObjectInfo->FileId.Unique));
 
         if( TargetName != NULL &&
             TargetName->Length > 0)
@@ -1086,87 +1272,6 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                            pDirNode->NameInformation.TargetName.Length);
         }
 
-        //
-        // If we allocated the object information cb then update the information
-        //
-
-        if( bAllocatedObjectCB)
-        {
-
-            //
-            // Populate the rest of the data
-            //
-
-            pObjectInfoCB->FileId = DirEnumEntry->FileId;
-
-            pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
-
-            pObjectInfoCB->FileType = DirEnumEntry->FileType;
-
-            pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
-
-            pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
-
-            pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
-
-            pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
-
-            pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
-
-            pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
-
-            pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
-
-            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
-            {
-
-                pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
-            }
-
-            if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
-                pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
-            {
-
-                pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
-            }
-
-            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
-            //
-
-            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
-                pObjectInfoCB->TargetFileId.Vnode == 0 &&
-                pObjectInfoCB->TargetFileId.Unique == 0 &&
-                pDirNode->NameInformation.TargetName.Length == 0)
-            {
-
-                //
-                // This will ensure we perform a validation on the node
-                //
-
-                pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
-            }
-
-            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
-            {
-
-                SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
-            }
-        }
 
 try_exit:
 
@@ -1178,13 +1283,18 @@ try_exit:
 
                 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
 
-                AFSExFreePool( pNonPagedDirEntry);
+                AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
             }
 
             if( pDirNode != NULL)
             {
 
-                AFSExFreePool( pDirNode);
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
+                              pDirNode));
+
+                AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
 
                 pDirNode = NULL;
             }
@@ -1196,21 +1306,19 @@ try_exit:
             if( pObjectInfoCB != NULL)
             {
 
-                lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
+                AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
+                                  TRUE);
+
+                lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                                 AFS_OBJECT_REFERENCE_DIRENTRY);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
+                              "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
                               pObjectInfoCB,
-                              lCount);
+                              lCount));
 
-                if( bAllocatedObjectCB)
-                {
-
-                    ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
-
-                    AFSDeleteObjectInfo( pObjectInfoCB);
-                }
+                AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
             }
         }
     }
@@ -1297,7 +1405,6 @@ AFSEvaluateNode( IN GUID *AuthGroup,
                  IN AFSDirectoryCB *DirEntry)
 {
 
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDirEnumEntry *pDirEntry = NULL;
     UNICODE_STRING uniTargetName;
@@ -1338,17 +1445,26 @@ AFSEvaluateNode( IN GUID *AuthGroup,
 
         DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+            pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
         }
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
-            pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
+        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
         }
 
         DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
@@ -1407,7 +1523,7 @@ try_exit:
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -1419,7 +1535,6 @@ AFSValidateSymLink( IN GUID *AuthGroup,
                     IN AFSDirectoryCB *DirEntry)
 {
 
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDirEnumEntry *pDirEntry = NULL;
     UNICODE_STRING uniTargetName;
@@ -1442,6 +1557,11 @@ AFSValidateSymLink( IN GUID *AuthGroup,
             pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
         {
 
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE_2,
+                          "AFSValidateSymLink Invalid type Status %08lX\n",
+                          STATUS_OBJECT_NAME_NOT_FOUND));
+
             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
         }
 
@@ -1523,17 +1643,26 @@ AFSValidateSymLink( IN GUID *AuthGroup,
 
         DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+            pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
         }
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
-            pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
+        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
         }
 
         DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
@@ -1545,7 +1674,7 @@ try_exit:
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -1560,8 +1689,9 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     IO_STATUS_BLOCK stIoStatus;
     ULONG ulFilter = 0;
+    AFSObjectInfoCB * pParentObjectInfo = NULL;
 
-    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
                   (*ppObjectInfo)->FileType,
@@ -1569,7 +1699,14 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                   (*ppObjectInfo)->FileId.Volume,
                   (*ppObjectInfo)->FileId.Vnode,
                   (*ppObjectInfo)->FileId.Unique,
-                  Reason);
+                  Reason));
+
+    if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+    {
+
+        pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
+                                               &(*ppObjectInfo)->ParentFileId);
+    }
 
     if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
         (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
@@ -1602,39 +1739,42 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
 
             (*ppObjectInfo)->TargetFileId.Unique = 0;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
                           (*ppObjectInfo)->FileId.Cell,
                           (*ppObjectInfo)->FileId.Volume,
                           (*ppObjectInfo)->FileId.Vnode,
-                          (*ppObjectInfo)->FileId.Unique);
+                          (*ppObjectInfo)->FileId.Unique));
 
             SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
         }
 
-        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-
-        if( Reason == AFS_INVALIDATE_CREDS)
+        if ( pParentObjectInfo != NULL)
         {
-            ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-        }
 
-        if( Reason == AFS_INVALIDATE_DATA_VERSION ||
-            Reason == AFS_INVALIDATE_FLUSHED)
-        {
-            ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
-        }
-        else
-        {
-            ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-        }
+            ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
+
+            if( Reason == AFS_INVALIDATE_CREDS)
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
+            }
+
+            if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+                Reason == AFS_INVALIDATE_FLUSHED)
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
+            }
+            else
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+            }
 
-        AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
-                                        NULL,
-                                        FILE_NOTIFY_CHANGE_FILE_NAME |
-                                        FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                                        FILE_ACTION_MODIFIED);
+            AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+                                            NULL,
+                                            ulFilter,
+                                            FILE_ACTION_MODIFIED);
+        }
 
         try_return( ntStatus);
     }
@@ -1653,47 +1793,49 @@ 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,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
                           (*ppObjectInfo)->FileId.Cell,
                           (*ppObjectInfo)->FileId.Volume,
                           (*ppObjectInfo)->FileId.Vnode,
-                          (*ppObjectInfo)->FileId.Unique);
+                          (*ppObjectInfo)->FileId.Unique));
 
-            if( (*ppObjectInfo)->ParentObjectInformation != NULL)
+            if( pParentObjectInfo != NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
-                              (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
-                              (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
-                              (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
-                              (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
+                              pParentObjectInfo->FileId.Cell,
+                              pParentObjectInfo->FileId.Volume,
+                              pParentObjectInfo->FileId.Vnode,
+                              pParentObjectInfo->FileId.Unique));
 
-                SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+                SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-                (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+                pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
 
-                (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
-            }
+                pParentObjectInfo->Expiration.QuadPart = 0;
 
-            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
-            {
-                ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-            }
-            else
-            {
-                ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-            }
+                if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
+                {
+                    ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
+                }
+                else
+                {
+                    ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
+                }
 
-            AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
-                                            NULL,
-                                            ulFilter,
-                                            FILE_ACTION_REMOVED);
+                AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+                                                NULL,
+                                                ulFilter,
+                                                FILE_ACTION_REMOVED);
+            }
 
             if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
                                                       Reason)))
@@ -1711,15 +1853,15 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                 (*ppObjectInfo)->Fcb != NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
                               (*ppObjectInfo)->FileId.Cell,
                               (*ppObjectInfo)->FileId.Volume,
                               (*ppObjectInfo)->FileId.Vnode,
-                              (*ppObjectInfo)->FileId.Unique);
+                              (*ppObjectInfo)->FileId.Unique));
 
-                AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
+                AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
                                 TRUE);
 
                 __try
@@ -1733,7 +1875,7 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                     if( !NT_SUCCESS( stIoStatus.Status))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                       (*ppObjectInfo)->FileId.Cell,
@@ -1741,23 +1883,51 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                                       (*ppObjectInfo)->FileId.Vnode,
                                       (*ppObjectInfo)->FileId.Unique,
                                       stIoStatus.Status,
-                                      stIoStatus.Information);
+                                      stIoStatus.Information));
 
                         ntStatus = stIoStatus.Status;
                     }
 
-                    CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
-                                         NULL,
-                                         0,
-                                         FALSE);
+
+                    if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                    {
+
+                        if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgTrace(( 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);
+                        }
+                    }
                 }
                 __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
                     ntStatus = GetExceptionCode();
+
+                    AFSDbgTrace(( 0,
+                                  0,
+                                  "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                  (*ppObjectInfo)->FileId.Cell,
+                                  (*ppObjectInfo)->FileId.Volume,
+                                  (*ppObjectInfo)->FileId.Vnode,
+                                  (*ppObjectInfo)->FileId.Unique,
+                                  ntStatus));
+
+                    SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                 }
 
-                AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
+                AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
 
                 //
                 // Clear out the extents
@@ -1765,8 +1935,8 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                 // for any writes or reads to the cache to complete)
                 //
 
-                (VOID) AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
-                                              NULL);
+                AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
+                                       NULL);
             }
 
             (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
@@ -1775,13 +1945,13 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
             if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
                               (*ppObjectInfo)->FileId.Cell,
                               (*ppObjectInfo)->FileId.Volume,
                               (*ppObjectInfo)->FileId.Vnode,
-                              (*ppObjectInfo)->FileId.Unique);
+                              (*ppObjectInfo)->FileId.Unique));
 
                 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
             }
@@ -1815,10 +1985,22 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
             }
 
-            AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
-                                            NULL,
-                                            ulFilter,
-                                            FILE_ACTION_MODIFIED);
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
+            {
+
+                AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
+                                                NULL,
+                                                ulFilter,
+                                                FILE_ACTION_MODIFIED);
+            }
+            else if ( pParentObjectInfo != NULL)
+            {
+
+                AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+                                                NULL,
+                                                ulFilter,
+                                                FILE_ACTION_MODIFIED);
+            }
 
             //
             // Indicate this node requires re-evaluation for the remaining reasons
@@ -1826,13 +2008,13 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
 
             (*ppObjectInfo)->Expiration.QuadPart = 0;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
                           (*ppObjectInfo)->FileId.Cell,
                           (*ppObjectInfo)->FileId.Volume,
                           (*ppObjectInfo)->FileId.Vnode,
-                          (*ppObjectInfo)->FileId.Unique);
+                          (*ppObjectInfo)->FileId.Unique));
 
             SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
@@ -1855,6 +2037,12 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
 
   try_exit:
 
+    if ( pParentObjectInfo != NULL)
+    {
+
+        AFSReleaseObjectInfo( &pParentObjectInfo);
+    }
+
     return ntStatus;
 }
 
@@ -1863,12 +2051,8 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSFcb      *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
-    AFSFcb      *pTargetDcb = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
-    BOOLEAN     bIsChild = FALSE;
     ULONGLONG   ullIndex = 0;
     AFSObjectInfoCB *pObjectInfo = NULL;
     LONG lCount;
@@ -1876,7 +2060,7 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
                       InvalidateCB->FileID.Cell,
@@ -1885,17 +2069,17 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                       InvalidateCB->FileID.Unique,
                       InvalidateCB->FileType,
                       InvalidateCB->WholeVolume,
-                      InvalidateCB->Reason);
+                      InvalidateCB->Reason));
 
         //
         // Need to locate the Fcb for the directory to purge
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
+                      "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
                       &pDevExt->Specific.RDR.VolumeTreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         //
         // Starve any exclusive waiters on this paticular call
@@ -1916,13 +2100,14 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
+                          "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          lCount));
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -1931,14 +2116,14 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             pVolumeCB == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_WARNING,
                           "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                           InvalidateCB->FileID.Cell,
                           InvalidateCB->FileID.Volume,
                           InvalidateCB->FileID.Vnode,
                           InvalidateCB->FileID.Unique,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus = STATUS_SUCCESS);
         }
@@ -1953,11 +2138,12 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             ntStatus = AFSInvalidateVolume( pVolumeCB,
                                             InvalidateCB->Reason);
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
             try_return( ntStatus);
         }
 
+        AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+                          TRUE);
+
         if ( AFSIsVolumeFID( &InvalidateCB->FileID))
         {
 
@@ -1966,25 +2152,11 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         else
         {
 
-            AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
-                              TRUE);
-
-            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,
                                            ullIndex,
                                            (AFSBTreeEntry **)&pObjectInfo);
-
-            AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
-
         }
 
         if( pObjectInfo != NULL)
@@ -1994,27 +2166,30 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo,
+                                             AFS_OBJECT_REFERENCE_INVALIDATION);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
+                          "AFSInvalidateCache Increment count on object %p Cnt %d\n",
                           pObjectInfo,
-                          lCount);
+                          lCount));
         }
 
+        AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+
         if( !NT_SUCCESS( ntStatus) ||
             pObjectInfo == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_WARNING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                           InvalidateCB->FileID.Cell,
                           InvalidateCB->FileID.Volume,
                           InvalidateCB->FileID.Vnode,
                           InvalidateCB->FileID.Unique,
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus = STATUS_SUCCESS);
         }
@@ -2027,13 +2202,27 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo,
+                                             AFS_OBJECT_REFERENCE_INVALIDATION);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
+                          "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
                           pObjectInfo,
-                          lCount);
+                          lCount));
+        }
+
+        if ( pVolumeCB != NULL)
+        {
+
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
+                          pVolumeCB,
+                          lCount));
         }
     }
 
@@ -2047,11 +2236,13 @@ AFSIsChildOfParent( IN AFSFcb *Dcb,
 
     BOOLEAN bIsChild = FALSE;
     AFSFcb *pCurrentFcb = Fcb;
+    AFSObjectInfoCB * pParentObjectInfo = NULL;
 
     while( pCurrentFcb != NULL)
     {
 
-        if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
+        if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
+            AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
         {
 
             bIsChild = TRUE;
@@ -2059,7 +2250,21 @@ AFSIsChildOfParent( IN AFSFcb *Dcb,
             break;
         }
 
-        pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
+        pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
+                                               &pCurrentFcb->ObjectInformation->ParentFileId);
+
+        if ( pParentObjectInfo != NULL)
+        {
+
+            pCurrentFcb = pParentObjectInfo->Fcb;
+
+            AFSReleaseObjectInfo( &pParentObjectInfo);
+        }
+        else
+        {
+
+            pCurrentFcb = NULL;
+        }
     }
 
     return bIsChild;
@@ -2191,11 +2396,11 @@ AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
 
 #endif
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
+                      "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
                       pSysNameLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireShared( pSysNameLock,
                           TRUE);
@@ -2216,6 +2421,12 @@ AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
         if( pSysName == NULL)
         {
 
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE_2,
+                          "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
+                          &ComponentName,
+                          STATUS_OBJECT_NAME_NOT_FOUND));
+
             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
         }
 
@@ -2403,7 +2614,7 @@ AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
 
         if( FreePathName)
         {
-            AFSExFreePool( FullPathName->Buffer);
+            AFSExFreePoolWithTag( FullPathName->Buffer, 0);
         }
 
         *FullPathName = uniPathName;
@@ -2425,20 +2636,18 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
     AFSObjectInfoCB *pCurrentObject = NULL;
     AFSObjectInfoCB *pNextObject = NULL;
     LONG lCount;
-    AFSFcb *pFcb = NULL;
-    ULONG ulFilter = 0;
 
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
                       VolumeCB->ObjectInformation.FileId.Cell,
                       VolumeCB->ObjectInformation.FileId.Volume,
                       VolumeCB->ObjectInformation.FileId.Vnode,
                       VolumeCB->ObjectInformation.FileId.Unique,
-                      Reason);
+                      Reason));
 
         //
         // Depending on the reason for invalidation then perform work on the node
@@ -2471,24 +2680,30 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
         if ( pCurrentObject )
         {
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject,
+                                             AFS_OBJECT_REFERENCE_INVALIDATION);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                          "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
                           pCurrentObject,
-                          lCount);
+                          lCount));
 
             AFSInvalidateObject( &pCurrentObject,
                                  Reason);
 
-            lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+            if ( pCurrentObject)
+            {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
-                          pCurrentObject,
-                          lCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject,
+                                                 AFS_OBJECT_REFERENCE_INVALIDATION);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
+                              pCurrentObject,
+                              lCount));
+            }
         }
 
         //
@@ -2507,13 +2722,14 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pCurrentObject,
+                                             AFS_OBJECT_REFERENCE_INVALIDATION);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                          "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
                           pCurrentObject,
-                          lCount);
+                          lCount));
         }
 
         while( pCurrentObject != NULL)
@@ -2528,13 +2744,14 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                 // Reference the node so it won't be torn down
                 //
 
-                lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pNextObject,
+                                                 AFS_OBJECT_REFERENCE_INVALIDATION);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                              "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
                               pNextObject,
-                              lCount);
+                              lCount));
             }
 
             AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
@@ -2545,13 +2762,14 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
             if ( pCurrentObject )
             {
 
-                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pCurrentObject,
+                                                 AFS_OBJECT_REFERENCE_INVALIDATION);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                              "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
                               pCurrentObject,
-                              lCount);
+                              lCount));
             }
 
             AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
@@ -2576,11 +2794,11 @@ AFSInvalidateAllVolumes( VOID)
 
     pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
-    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
+                  "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
                   &pRDRDeviceExt->Specific.RDR.VolumeListLock,
-                  PsGetCurrentThread());
+                  PsGetCurrentThread()));
 
     AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
                       TRUE);
@@ -2590,13 +2808,20 @@ AFSInvalidateAllVolumes( VOID)
     if ( pVolumeCB)
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
+                      "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
                       pVolumeCB->ObjectInfoTree.TreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_INVALIDATE);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
+                      pVolumeCB,
+                      lCount));
     }
 
     while( pVolumeCB != NULL)
@@ -2607,7 +2832,14 @@ AFSInvalidateAllVolumes( VOID)
         if ( pNextVolumeCB)
         {
 
-            lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pNextVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
+                          pVolumeCB,
+                          lCount));
         }
 
         AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
@@ -2619,7 +2851,14 @@ AFSInvalidateAllVolumes( VOID)
         AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
                           TRUE);
 
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeDecrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_INVALIDATE);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
+                      pVolumeCB,
+                      lCount));
 
         pVolumeCB = pNextVolumeCB;
     }
@@ -2640,14 +2879,14 @@ AFSVerifyEntry( IN GUID *AuthGroup,
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                       &DirEntry->NameInformation.FileName,
                       pObjectInfo->FileId.Cell,
                       pObjectInfo->FileId.Volume,
                       pObjectInfo->FileId.Vnode,
-                      pObjectInfo->FileId.Unique);
+                      pObjectInfo->FileId.Unique));
 
         ntStatus = AFSEvaluateTargetByID( pObjectInfo,
                                           AuthGroup,
@@ -2657,15 +2896,15 @@ AFSVerifyEntry( IN GUID *AuthGroup,
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                          "AFSVerifyEntry Evaluate Target 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));
 
             try_return( ntStatus);
         }
@@ -2674,27 +2913,29 @@ AFSVerifyEntry( IN GUID *AuthGroup,
         // Check the data version of the file
         //
 
-        if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
-            !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+        if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
         {
+            if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+            {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                          pObjectInfo->DataVersion.QuadPart,
-                          &DirEntry->NameInformation.FileName,
-                          pObjectInfo->FileId.Cell,
-                          pObjectInfo->FileId.Volume,
-                          pObjectInfo->FileId.Vnode,
-                          pObjectInfo->FileId.Unique);
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                              pObjectInfo->DataVersion.QuadPart,
+                              &DirEntry->NameInformation.FileName,
+                              pObjectInfo->FileId.Cell,
+                              pObjectInfo->FileId.Volume,
+                              pObjectInfo->FileId.Vnode,
+                              pObjectInfo->FileId.Unique));
 
-            //
-            // We are ok, just get out
-            //
+                //
+                // We are ok, just get out
+                //
 
-            ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-            try_return( ntStatus = STATUS_SUCCESS);
+                try_return( ntStatus = STATUS_SUCCESS);
+            }
         }
 
         //
@@ -2736,8 +2977,6 @@ AFSVerifyEntry( IN GUID *AuthGroup,
             case AFS_FILE_TYPE_SYMLINK:
             {
 
-                ASSERT( pDirEnumEntry->TargetNameLength > 0);
-
                 //
                 // Update the metadata for the entry
                 //
@@ -2759,58 +2998,53 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                 FILE_OBJECT * pCCFileObject = NULL;
                 BOOLEAN bPurgeExtents = FALSE;
 
-                if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+                if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
                 {
-                    bPurgeExtents = TRUE;
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                  "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
                                   &DirEntry->NameInformation.FileName,
                                   pObjectInfo->FileId.Cell,
                                   pObjectInfo->FileId.Volume,
                                   pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
+                                  pObjectInfo->FileId.Unique,
+                                  pObjectInfo->DataVersion.LowPart,
+                                  pDirEnumEntry->DataVersion.LowPart));
 
-                    ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                    bPurgeExtents = TRUE;
                 }
 
-                //
-                // Update the metadata for the entry
-                //
-
-                ntStatus = AFSUpdateMetaData( DirEntry,
-                                              pDirEnumEntry);
-
-                if( !NT_SUCCESS( ntStatus))
+                if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
+                    bPurgeExtents = TRUE;
+
+                    AFSDbgTrace(( 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,
-                                  ntStatus);
+                                  pObjectInfo->FileId.Unique));
 
-                    break;
+                    ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
                 }
 
                 if( pObjectInfo->Fcb != NULL)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                   &DirEntry->NameInformation.FileName,
                                   pObjectInfo->FileId.Cell,
                                   pObjectInfo->FileId.Volume,
                                   pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
+                                  pObjectInfo->FileId.Unique));
 
-                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
                                     TRUE);
 
                     __try
@@ -2824,7 +3058,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                         if( !NT_SUCCESS( stIoStatus.Status))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                           &DirEntry->NameInformation.FileName,
@@ -2833,36 +3067,52 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                                           pObjectInfo->FileId.Vnode,
                                           pObjectInfo->FileId.Unique,
                                           stIoStatus.Status,
-                                          stIoStatus.Information);
+                                          stIoStatus.Information));
 
                             ntStatus = stIoStatus.Status;
                         }
 
-                        if ( bPurgeExtents)
+                        if ( bPurgeExtents &&
+                             pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
                         {
 
-                            CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                 NULL,
-                                                 0,
-                                                 FALSE);
+                            if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                       NULL,
+                                                       0,
+                                                       FALSE))
+                            {
+
+                                AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                              AFS_TRACE_LEVEL_WARNING,
+                                              "AFSVerifyEntry 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( AFS_SUBSYSTEM_IO_PROCESSING,
-                                      AFS_TRACE_LEVEL_ERROR,
-                                      "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                        AFSDbgTrace(( 0,
+                                      0,
+                                      "EXCEPTION - AFSVerifyEntry 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);
+                                      ntStatus));
+
+                        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                     }
 
-                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
+                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
 
                     if ( bPurgeExtents)
                     {
@@ -2874,16 +3124,39 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                     // Reacquire the Fcb to purge the cache
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
+                                  "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
                                   &pObjectInfo->Fcb->NPFcb->Resource,
-                                  PsGetCurrentThread());
+                                  PsGetCurrentThread()));
 
                     AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
                                     TRUE);
 
                     //
+                    // Update the metadata for the entry
+                    //
+
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
+
+                    if( !NT_SUCCESS( ntStatus))
+                    {
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
+                                      &DirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      ntStatus));
+
+                        break;
+                    }
+
+                    //
                     // Update file sizes
                     //
 
@@ -2891,6 +3164,15 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                     pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
                     pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
 
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                  &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread()));
+
+                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                    TRUE);
+
                     pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
 
                     if ( pCCFileObject != NULL)
@@ -2899,18 +3181,50 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
                     }
 
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                  &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread()));
+
+                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
+
                     AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
                 }
                 else
                 {
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+
+                    //
+                    // Update the metadata for the entry
+                    //
+
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
+
+                    if( !NT_SUCCESS( ntStatus))
+                    {
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
+                                      &DirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      ntStatus));
+
+                        break;
+                    }
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_WARNING,
-                                  "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                  "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                   &DirEntry->NameInformation.FileName,
                                   pObjectInfo->FileId.Cell,
                                   pObjectInfo->FileId.Volume,
                                   pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
+                                  pObjectInfo->FileId.Unique));
                 }
 
                 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
@@ -2921,9 +3235,6 @@ AFSVerifyEntry( IN GUID *AuthGroup,
             case AFS_FILE_TYPE_DIRECTORY:
             {
 
-                AFSFcb *pCurrentFcb = NULL;
-                AFSDirectoryCB *pCurrentDirEntry = NULL;
-
                 //
                 // For a directory or root entry flush the content of
                 // the directory enumeration.
@@ -2932,14 +3243,14 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE_2,
                                   "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                   &DirEntry->NameInformation.FileName,
                                   pObjectInfo->FileId.Cell,
                                   pObjectInfo->FileId.Volume,
                                   pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
+                                  pObjectInfo->FileId.Unique));
 
                     AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                     TRUE);
@@ -3034,7 +3345,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
 
             default:
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
                               "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               pObjectInfo->FileType,
@@ -3042,7 +3353,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                               pObjectInfo->FileId.Cell,
                               pObjectInfo->FileId.Volume,
                               pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
+                              pObjectInfo->FileId.Unique));
 
                 break;
         }
@@ -3052,7 +3363,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
         if( pDirEnumEntry != NULL)
         {
 
-            AFSExFreePool( pDirEnumEntry);
+            AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -3067,29 +3378,27 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
     ULONGLONG   ullIndex = 0;
     AFSVolumeCB *pVolumeCB = NULL;
-    AFSFcb *pFcb = NULL;
-    AFSObjectInfoCB *pCurrentObject = NULL;
     LONG lCount;
 
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
                       VolumeStatus->Online,
                       VolumeStatus->FileID.Cell,
-                      VolumeStatus->FileID.Volume);
+                      VolumeStatus->FileID.Volume));
 
         //
         // Need to locate the Fcb for the directory to purge
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
+                      "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
                       &pDevExt->Specific.RDR.VolumeTreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
 
@@ -3106,7 +3415,14 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
+                          pVolumeCB,
+                          lCount));
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
@@ -3124,135 +3440,51 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
 
                 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
             }
+        }
+    }
 
-            AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
-                              TRUE);
+    return ntStatus;
+}
 
-            pCurrentObject = pVolumeCB->ObjectInfoListHead;;
+NTSTATUS
+AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
+{
 
-            while( pCurrentObject != NULL)
-            {
+    NTSTATUS ntStatus = STATUS_SUCCESS;
 
-                if( VolumeStatus->Online)
-                {
+    __Enter
+    {
 
-                    ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
+        if( AFSGlobalRoot == NULL)
+        {
 
-                    SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
+            try_return( ntStatus);
+        }
 
-                    pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
-                }
-                else
-                {
+        AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
+                        TRUE);
 
-                    SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
-                }
+        //
+        // Set the network state according to the information
+        //
 
-                pFcb = pCurrentObject->Fcb;
+        if( NetworkStatus->Online)
+        {
 
-                if( pFcb != NULL &&
-                    !(VolumeStatus->Online) &&
-                    pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
-                {
+            ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
+        }
+        else
+        {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
-                                  VolumeStatus->FileID.Cell,
-                                  VolumeStatus->FileID.Volume);
+            SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
+        }
 
-                    //
-                    // Clear out the extents
-                    //
+        AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
-                                  &pFcb->NPFcb->Specific.File.ExtentsResource,
-                                  PsGetCurrentThread());
+try_exit:
 
-                    AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
-                                    TRUE);
-
-                    pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
-
-                    KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
-                                0,
-                                FALSE);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
-                                  &pFcb->NPFcb->Specific.File.ExtentsResource,
-                                  PsGetCurrentThread());
-
-                    AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
-
-                    //
-                    // And get rid of them (note this involves waiting
-                    // for any writes or reads to the cache to complete)
-                    //
-
-                    (VOID) AFSTearDownFcbExtents( pFcb,
-                                                  NULL);
-                }
-
-                pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
-            }
-
-            AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
-
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-        }
-        else
-        {
-
-            AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
-        }
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-
-    __Enter
-    {
-
-        if( AFSGlobalRoot == NULL)
-        {
-
-            try_return( ntStatus);
-        }
-
-        AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
-                        TRUE);
-
-        //
-        // Set the network state according to the information
-        //
-
-        if( NetworkStatus->Online)
-        {
-
-            ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
-        }
-        else
-        {
-
-            SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
-        }
-
-        AFSReleaseResource( AFSGlobalRoot->VolumeLock);
-
-try_exit:
-
-        NOTHING;
-    }
+        NOTHING;
+    }
 
     return ntStatus;
 }
@@ -3263,29 +3495,29 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     BOOLEAN  bAcquiredLock = FALSE;
     AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
-    AFSFcb *pFcb = NULL;
 
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
                       ObjectInfo->FileId.Cell,
                       ObjectInfo->FileId.Volume,
                       ObjectInfo->FileId.Vnode,
-                      ObjectInfo->FileId.Unique);
+                      ObjectInfo->FileId.Unique));
 
         if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
+                          "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
                           ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                          PsGetCurrentThread());
+                          PsGetCurrentThread()));
 
             AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                             TRUE);
@@ -3301,14 +3533,14 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
              ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
+                          "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
                           ObjectInfo->Specific.Directory.DirectoryNodeCount,
                           ObjectInfo->FileId.Cell,
                           ObjectInfo->FileId.Volume,
                           ObjectInfo->FileId.Vnode,
-                          ObjectInfo->FileId.Unique);
+                          ObjectInfo->FileId.Unique));
         }
 
         //
@@ -3330,28 +3562,29 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                 //
 
                 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
-                    pCurrentDirEntry->OpenReferenceCount == 0)
+                    pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
+                    pCurrentDirEntry->NameArrayReferenceCount <= 0)
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
                                   pCurrentDirEntry,
-                                  &pCurrentDirEntry->NameInformation.FileName);
+                                  &pCurrentDirEntry->NameInformation.FileName));
 
                     AFSDeleteDirEntry( ObjectInfo,
-                                       pCurrentDirEntry);
+                                       &pCurrentDirEntry);
                 }
                 else
                 {
 
                     ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
+                                  "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
                                   pCurrentDirEntry,
-                                  pCurrentDirEntry->OpenReferenceCount);
+                                  pCurrentDirEntry->DirOpenReferenceCount));
 
                     //
                     // We pull the short name from the parent tree since it could change below
@@ -3360,12 +3593,12 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                     if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
                                       pCurrentDirEntry,
                                       pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
-                                      &pCurrentDirEntry->NameInformation.FileName);
+                                      &pCurrentDirEntry->NameInformation.FileName));
 
                         AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
                                                     pCurrentDirEntry);
@@ -3404,7 +3637,8 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
             if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
             {
 
-                if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
+                if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+                    !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
                     pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
                 {
 
@@ -3413,11 +3647,11 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
 
                         ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
                                       pCurrentDirEntry,
-                                      &pCurrentDirEntry->NameInformation.FileName);
+                                      &pCurrentDirEntry->NameInformation.FileName));
 
                         SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
                     }
@@ -3427,22 +3661,22 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                         if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
                                                                      pCurrentDirEntry)))
                         {
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
                                           pCurrentDirEntry,
                                           pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
-                                          &pCurrentDirEntry->NameInformation.FileName);
+                                          &pCurrentDirEntry->NameInformation.FileName));
                         }
                         else
                         {
                             SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                           AFS_TRACE_LEVEL_VERBOSE,
                                           "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
                                           pCurrentDirEntry,
-                                          &pCurrentDirEntry->NameInformation.FileName);
+                                          &pCurrentDirEntry->NameInformation.FileName));
                         }
                     }
                 }
@@ -3452,31 +3686,32 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                 continue;
             }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
+                          "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
                           pCurrentDirEntry,
-                          pCurrentDirEntry->OpenReferenceCount);
+                          pCurrentDirEntry->DirOpenReferenceCount));
 
-            if( pCurrentDirEntry->OpenReferenceCount == 0)
+            if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
+                pCurrentDirEntry->NameArrayReferenceCount <= 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
                               &pCurrentDirEntry->NameInformation.FileName,
                               ObjectInfo->FileId.Cell,
                               ObjectInfo->FileId.Volume,
                               ObjectInfo->FileId.Vnode,
-                              ObjectInfo->FileId.Unique);
+                              ObjectInfo->FileId.Unique));
 
                 AFSDeleteDirEntry( ObjectInfo,
-                                   pCurrentDirEntry);
+                                   &pCurrentDirEntry);
             }
             else
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
                               pCurrentDirEntry,
@@ -3484,7 +3719,7 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
                               ObjectInfo->FileId.Cell,
                               ObjectInfo->FileId.Volume,
                               ObjectInfo->FileId.Vnode,
-                              ObjectInfo->FileId.Unique);
+                              ObjectInfo->FileId.Unique));
 
                 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
@@ -3590,24 +3825,35 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
 
         pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
 
-        if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+            pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
         }
 
-        if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
+        if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
         {
 
-            pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
         }
 
         pObjectInfo->EaSize = DirEnumEntry->EaSize;
 
         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))
         {
 
             //
@@ -3649,7 +3895,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,
@@ -3658,7 +3905,7 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
             if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
                 DirEntry->NameInformation.TargetName.Buffer != NULL)
             {
-                AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
+                AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
             }
 
             ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
@@ -3681,8 +3928,8 @@ try_exit:
 NTSTATUS
 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                   IN GUID *AuthGroup,
-                  IN BOOLEAN PurgeContent,
-                  IN BOOLEAN FastCall)
+                  IN BOOLEAN FastCall,
+                  IN BOOLEAN bSafeToPurge)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
@@ -3700,14 +3947,15 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
         // correct order
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
-                      "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                      "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
                       &DirEntry->NameInformation.FileName,
                       pObjectInfo->FileId.Cell,
                       pObjectInfo->FileId.Volume,
                       pObjectInfo->FileId.Vnode,
-                      pObjectInfo->FileId.Unique);
+                      pObjectInfo->FileId.Unique,
+                      FastCall));
 
         //
         // If this is a fake node then bail since the service knows nothing about it
@@ -3719,28 +3967,6 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
             try_return( ntStatus);
         }
 
-        if( PurgeContent &&
-            pObjectInfo->Fcb != NULL)
-        {
-
-            pCurrentFcb = pObjectInfo->Fcb;
-
-            if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
-            {
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
-                              &pCurrentFcb->NPFcb->Resource,
-                              PsGetCurrentThread());
-
-                AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
-                                TRUE);
-
-                bReleaseFcb = TRUE;
-            }
-        }
-
         //
         // This routine ensures that the current entry is valid by:
         //
@@ -3756,14 +3982,14 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
             pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
                           &DirEntry->NameInformation.FileName,
                           pObjectInfo->FileId.Cell,
                           pObjectInfo->FileId.Volume,
                           pObjectInfo->FileId.Vnode,
-                          pObjectInfo->FileId.Unique);
+                          pObjectInfo->FileId.Unique));
 
             try_return( ntStatus);
         }
@@ -3780,7 +4006,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                           FastCall,
@@ -3789,7 +4015,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                           pObjectInfo->FileId.Volume,
                           pObjectInfo->FileId.Vnode,
                           pObjectInfo->FileId.Unique,
-                          ntStatus);
+                          ntStatus));
 
             //
             // Failed validation of node so return access-denied
@@ -3798,7 +4024,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
             try_return( ntStatus);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
                       FastCall,
@@ -3809,7 +4035,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                       pObjectInfo->FileId.Unique,
                       pObjectInfo->DataVersion.QuadPart,
                       pDirEnumEntry->DataVersion.QuadPart,
-                      pDirEnumEntry->FileType);
+                      pDirEnumEntry->FileType));
 
 
         //
@@ -3861,171 +4087,279 @@ 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
                 // Can't hold the Fcb resource while doing this
                 //
 
-                if( pCurrentFcb != NULL &&
+                if( pObjectInfo->Fcb != NULL &&
                     (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
-                    BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
+                      BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
                 {
 
-                    IO_STATUS_BLOCK stIoStatus;
-                    BOOLEAN bPurgeExtents = FALSE;
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE_2,
-                                  "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
-                                  &DirEntry->NameInformation.FileName,
-                                  pObjectInfo->FileId.Cell,
-                                  pObjectInfo->FileId.Volume,
-                                  pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
+                    pCurrentFcb = pObjectInfo->Fcb;
 
-                    if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+                    if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
                     {
-                        bPurgeExtents = TRUE;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_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);
+                                      "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
+                                      &pCurrentFcb->NPFcb->Resource,
+                                      PsGetCurrentThread()));
 
-                        ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                        AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
+                                        TRUE);
+
+                        bReleaseFcb = TRUE;
                     }
 
-                    __try
+                    if( pCurrentFcb != NULL)
                     {
 
-                        CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
-                                      NULL,
-                                      0,
-                                      &stIoStatus);
+                        IO_STATUS_BLOCK stIoStatus;
 
-                        if( !NT_SUCCESS( stIoStatus.Status))
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE_2,
+                                      "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                      &DirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique));
+
+                        if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
                         {
 
-                            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",
+                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%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->DataVersion.LowPart,
+                                          pDirEnumEntry->DataVersion.LowPart));
 
-                            ntStatus = stIoStatus.Status;
+                            bPurgeExtents = TRUE;
                         }
 
-                        if ( bPurgeExtents)
+                        if ( bSafeToPurge)
                         {
 
-                            CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                 NULL,
-                                                 0,
-                                                 FALSE);
+                            if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+                            {
+                                bPurgeExtents = TRUE;
+
+                                AFSDbgTrace(( 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);
+                            }
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateEntry Acquiring Fcb SectionObject lock %p 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
+                            {
+
+                                CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
+                                              NULL,
+                                              0,
+                                              &stIoStatus);
+
+                                if( !NT_SUCCESS( stIoStatus.Status))
+                                {
+
+                                    AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                  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,
+                                                  stIoStatus.Status,
+                                                  stIoStatus.Information));
+
+                                    ntStatus = stIoStatus.Status;
+                                }
+
+                                if ( bPurgeExtents &&
+                                     pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                                {
+
+                                    if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                               NULL,
+                                                               0,
+                                                               FALSE))
+                                    {
+
+                                        AFSDbgTrace(( 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();
+
+                                AFSDbgTrace(( 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);
+                            }
+
+                            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                          &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                          PsGetCurrentThread()));
+
+                            AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
+
+                            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                                            TRUE);
+                        }
+                        else
+                        {
+
+                            if ( bPurgeExtents)
+                            {
+
+                                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                            }
+                        }
+
+
+                        AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
+
+                        bReleaseFcb = FALSE;
+
+                        if ( bPurgeExtents &&
+                             bSafeToPurge)
+                        {
+                            AFSFlushExtents( pCurrentFcb,
+                                             AuthGroup);
                         }
                     }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
+                }
+
+                //
+                // 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.
+                //
+
+                if ( !(bPurgeExtents && bSafeToPurge))
+                {
+
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
+
+                    if( !NT_SUCCESS( ntStatus))
                     {
-                        ntStatus = GetExceptionCode();
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
-                                      "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                      "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));
 
+                        break;
                     }
 
-                    AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
-
-                    if ( bPurgeExtents)
-                    {
-                        AFSFlushExtents( pCurrentFcb,
-                                         AuthGroup);
-                    }
+                    ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
 
                     //
-                    // Reacquire the Fcb to purge the cache
+                    // Update file sizes
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
-                                  &pCurrentFcb->NPFcb->Resource,
-                                  PsGetCurrentThread());
-
-                    AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
-                                    TRUE);
-                }
-
-                //
-                // Update the metadata for the entry
-                //
-
-                ntStatus = AFSUpdateMetaData( DirEntry,
-                                              pDirEnumEntry);
-
-                if( !NT_SUCCESS( ntStatus))
-                {
+                    if( pObjectInfo->Fcb != NULL)
+                    {
+                        FILE_OBJECT *pCCFileObject;
 
-                    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);
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                      &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread()));
 
-                    break;
-                }
+                        AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                        TRUE);
 
-                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
+                        pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
 
-                //
-                // Update file sizes
-                //
+                        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( pObjectInfo->Fcb != NULL)
-                {
-                    FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
+                        if ( pCCFileObject != NULL)
+                        {
+                            CcSetFileSizes( pCCFileObject,
+                                            (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        }
 
-                    pObjectInfo->Fcb->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
-                    pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
-                    pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                      &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread()));
 
-                    if ( pCCFileObject != NULL)
-                    {
-                        CcSetFileSizes( pCCFileObject,
-                                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
                     }
                 }
-
                 break;
             }
 
             case AFS_FILE_TYPE_DIRECTORY:
             {
 
-                AFSDirectoryCB *pCurrentDirEntry = NULL;
-
-                if( pCurrentFcb != NULL &&
-                    pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
+                if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
                 {
 
                     //
@@ -4033,29 +4367,29 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                     // the directory enumeration.
                     //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
+                                  "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
                                   pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                                  PsGetCurrentThread());
+                                  PsGetCurrentThread()));
 
                     if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_VERBOSE_2,
                                       "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                       &DirEntry->NameInformation.FileName,
                                       pObjectInfo->FileId.Cell,
                                       pObjectInfo->FileId.Volume,
                                       pObjectInfo->FileId.Vnode,
-                                      pObjectInfo->FileId.Unique);
+                                      pObjectInfo->FileId.Unique));
 
                         AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                         TRUE);
 
-                        AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
-                                                   AuthGroup);
+                        ntStatus = AFSValidateDirectoryCache( pObjectInfo,
+                                                              AuthGroup);
 
                         AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
                     }
@@ -4063,7 +4397,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                     if( !NT_SUCCESS( ntStatus))
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                       AFS_TRACE_LEVEL_ERROR,
                                       "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                       &DirEntry->NameInformation.FileName,
@@ -4071,7 +4405,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                                       pObjectInfo->FileId.Volume,
                                       pObjectInfo->FileId.Vnode,
                                       pObjectInfo->FileId.Unique,
-                                      ntStatus);
+                                      ntStatus));
 
                         break;
                     }
@@ -4095,7 +4429,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
             default:
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
                               "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                               pObjectInfo->FileType,
@@ -4104,7 +4438,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                               pObjectInfo->FileId.Cell,
                               pObjectInfo->FileId.Volume,
                               pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
+                              pObjectInfo->FileId.Unique));
 
                 break;
         }
@@ -4120,7 +4454,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
         if( pDirEnumEntry != NULL)
         {
 
-            AFSExFreePool( pDirEnumEntry);
+            AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -4137,12 +4471,13 @@ AFSInitializeSpecialShareNameList()
     UNICODE_STRING uniShareName;
     ULONG ulEntryLength = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
 
         RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\srvsvc");
+                              L"PIPE");
 
         pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
                                                0);
@@ -4153,14 +4488,16 @@ AFSInitializeSpecialShareNameList()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
-                      pObjectInfoCB);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_GLOBAL);
 
-        pObjectInfoCB->ObjectReferenceCount = 1;
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
+                      pObjectInfoCB,
+                      lCount));
 
-        pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
+        pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
 
         ulEntryLength = sizeof( AFSDirectoryCB) +
                                      uniShareName.Length;
@@ -4172,11 +4509,29 @@ AFSInitializeSpecialShareNameList()
         if( pDirNode == NULL)
         {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
                                                                                    sizeof( AFSNonPagedDirectoryCB),
                                                                                    AFS_DIR_ENTRY_NP_TAG);
@@ -4186,7 +4541,20 @@ AFSInitializeSpecialShareNameList()
 
             ExFreePool( pDirNode);
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -4207,7 +4575,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;
 
@@ -4226,8 +4594,9 @@ AFSInitializeSpecialShareNameList()
 
         pLastDirNode = pDirNode;
 
+
         RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\wkssvc");
+                              L"IPC$");
 
         pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
                                                0);
@@ -4238,14 +4607,16 @@ AFSInitializeSpecialShareNameList()
             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);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_GLOBAL);
 
-        pObjectInfoCB->ObjectReferenceCount = 1;
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
+                      pObjectInfoCB,
+                      lCount));
 
-        pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
+        pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
 
         ulEntryLength = sizeof( AFSDirectoryCB) +
                                      uniShareName.Length;
@@ -4257,11 +4628,29 @@ AFSInitializeSpecialShareNameList()
         if( pDirNode == NULL)
         {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
                                                                                    sizeof( AFSNonPagedDirectoryCB),
                                                                                    AFS_DIR_ENTRY_NP_TAG);
@@ -4271,94 +4660,20 @@ AFSInitializeSpecialShareNameList()
 
             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;
+            lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
 
-        RtlInitUnicodeString( &uniShareName,
-                              L"IPC$");
-
-        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 (ipc$) 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)
-        {
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
+                          pObjectInfoCB,
+                          lCount));
 
-            ExFreePool( pDirNode);
+            if ( lCount == 0)
+            {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
+                AFSDeleteObjectInfo( &pObjectInfoCB);
+            }
 
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
@@ -4413,7 +4728,20 @@ try_exit:
 
                     pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
 
-                    AFSDeleteObjectInfo( pDirNode->ObjectInformation);
+                    lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
+                                                     AFS_OBJECT_REFERENCE_GLOBAL);
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
+                                  pDirNode->ObjectInformation,
+                                  lCount));
+
+                    if ( lCount == 0)
+                    {
+
+                        AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
+                    }
 
                     ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
 
@@ -4444,38 +4772,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
-        {
+        AFSDbgTrace(( 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
@@ -4549,7 +4853,8 @@ AFSIsEqualFID( IN AFSFileID *FileId1,
 
     BOOLEAN bIsEqual = FALSE;
 
-    if( FileId1->Unique == FileId2->Unique &&
+    if( FileId1->Hash == FileId2->Hash &&
+        FileId1->Unique == FileId2->Unique &&
         FileId1->Vnode == FileId2->Vnode &&
         FileId1->Volume == FileId2->Volume &&
         FileId1->Cell == FileId2->Cell)
@@ -4584,26 +4889,27 @@ AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
 
             pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
 
-            if( pCurrentDirEntry->OpenReferenceCount == 0)
+            if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
+                pCurrentDirEntry->NameArrayReferenceCount <= 0)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
                               pCurrentDirEntry,
-                              &pCurrentDirEntry->NameInformation.FileName);
+                              &pCurrentDirEntry->NameInformation.FileName));
 
                 AFSDeleteDirEntry( ObjectInfoCB,
-                                   pCurrentDirEntry);
+                                   &pCurrentDirEntry);
             }
             else
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
                               pCurrentDirEntry,
-                              &pCurrentDirEntry->NameInformation.FileName);
+                              &pCurrentDirEntry->NameInformation.FileName));
 
                 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
@@ -4626,13 +4932,13 @@ AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
 
         ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
                       ObjectInfoCB->FileId.Cell,
                       ObjectInfoCB->FileId.Volume,
                       ObjectInfoCB->FileId.Vnode,
-                      ObjectInfoCB->FileId.Unique);
+                      ObjectInfoCB->FileId.Unique));
     }
 
     return ntStatus;
@@ -4649,11 +4955,11 @@ AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
+                      "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
                       AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
-                      PsGetCurrentThread());
+                      PsGetCurrentThread()));
 
         AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
                         TRUE);
@@ -4686,12 +4992,6 @@ AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
 
         pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
 
-        //
-        // Indicate the node is initialized
-        //
-
-        SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
-
         uniFullName.MaximumLength = PAGE_SIZE;
         uniFullName.Length = 0;
 
@@ -4748,7 +5048,7 @@ AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
             pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
         }
 
-        AFSExFreePool( uniFullName.Buffer);
+        AFSExFreePoolWithTag( uniFullName.Buffer, 0);
 
 try_exit:
 
@@ -4764,7 +5064,8 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
 
     BOOLEAN bIsRelative = FALSE;
 
-    if( Name->Buffer[ 0] != L'\\')
+    if( Name->Length > 0 &&
+        Name->Buffer[ 0] != L'\\')
     {
 
         bIsRelative = TRUE;
@@ -4773,616 +5074,136 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
     return bIsRelative;
 }
 
-void
-AFSUpdateName( IN UNICODE_STRING *Name)
-{
-
-    USHORT usIndex = 0;
-
-    while( usIndex < Name->Length/sizeof( WCHAR))
-    {
-
-        if( Name->Buffer[ usIndex] == L'/')
-        {
-
-            Name->Buffer[ usIndex] = L'\\';
-        }
-
-        usIndex++;
-    }
-
-    return;
-}
-
-NTSTATUS
-AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
-                     IN OUT ULONG *Flags,
-                     IN WCHAR *NameBuffer,
-                     IN USHORT NameLength)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    WCHAR *pTmpBuffer = NULL;
-
-    __Enter
-    {
-
-        //
-        // If we have enough space then just move in the name otherwise
-        // allocate a new buffer
-        //
-
-        if( TargetName->Length < NameLength)
-        {
-
-            pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
-                                                            NameLength,
-                                                            AFS_NAME_BUFFER_FIVE_TAG);
-
-            if( pTmpBuffer == NULL)
-            {
-
-                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-            }
-
-            if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
-            {
-
-                AFSExFreePool( TargetName->Buffer);
-            }
-
-            TargetName->MaximumLength = NameLength;
-
-            TargetName->Buffer = pTmpBuffer;
-
-            SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
-        }
-
-        TargetName->Length = NameLength;
-
-        RtlCopyMemory( TargetName->Buffer,
-                       NameBuffer,
-                       TargetName->Length);
-
-        //
-        // Update the name in the buffer
-        //
-
-        AFSUpdateName( TargetName);
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-AFSNameArrayHdr *
-AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
-                  IN ULONG InitialElementCount)
-{
-
-    AFSNameArrayHdr *pNameArray = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    LONG lCount;
-
-    __Enter
-    {
-
-        if( InitialElementCount == 0)
-        {
-
-            InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
-        }
-
-        pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
-                                                                  sizeof( AFSNameArrayHdr) +
-                                                                    (InitialElementCount * sizeof( AFSNameArrayCB)),
-                                                                  AFS_NAME_ARRAY_TAG);
-
-        if( pNameArray == NULL)
-        {
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSInitNameArray Failed to allocate name array\n");
-
-            try_return( pNameArray);
-        }
-
-        RtlZeroMemory( pNameArray,
-                       sizeof( AFSNameArrayHdr) +
-                          (InitialElementCount * sizeof( AFSNameArrayCB)));
-
-        pNameArray->MaxElementCount = InitialElementCount;
-
-        if( DirectoryCB != NULL)
-        {
-
-            pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
-
-            lCount = InterlockedIncrement( &pNameArray->Count);
-
-            lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
-                          &DirectoryCB->NameInformation.FileName,
-                          DirectoryCB,
-                          lCount);
-
-            pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
-
-            pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
-
-            pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
-        }
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return pNameArray;
-}
-
-NTSTATUS
-AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
-                      IN UNICODE_STRING *Path,
-                      IN AFSDirectoryCB *DirectoryCB)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    UNICODE_STRING uniComponentName, uniRemainingPath;
-    AFSObjectInfoCB *pCurrentObject = NULL;
-    ULONG  ulTotalCount = 0;
-    ULONG ulIndex = 0;
-    USHORT usLength = 0;
-    LONG lCount;
-
-    __Enter
-    {
-
-        //
-        // Init some info in the header
-        //
-
-        pCurrentElement = &NameArray->ElementArray[ 0];
-
-        NameArray->CurrentEntry = pCurrentElement;
-
-        //
-        // The first entry points at the root
-        //
-
-        pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
-
-        lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
-                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                      pCurrentElement->DirectoryCB,
-                      lCount);
-
-        pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
-
-        pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
-
-        NameArray->Count = 1;
-
-        NameArray->LinkCount = 0;
-
-        //
-        // If the root is the parent then we are done ...
-        //
-
-        if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
-        {
-            try_return( ntStatus);
-        }
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
-                                      IN AFSNameArrayHdr *RelatedNameArray,
-                                      IN AFSDirectoryCB *DirectoryCB)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
-    UNICODE_STRING uniComponentName, uniRemainingPath;
-    AFSObjectInfoCB *pObjectInfo = NULL;
-    ULONG  ulTotalCount = 0;
-    ULONG ulIndex = 0;
-    USHORT usLength = 0;
-    LONG lCount;
-
-    __Enter
-    {
-
-        //
-        // Init some info in the header
-        //
-
-        pCurrentElement = &NameArray->ElementArray[ 0];
-
-        pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
-
-        NameArray->Count = 0;
-
-        NameArray->LinkCount = RelatedNameArray->LinkCount;
-
-        //
-        // Populate the name array with the data from the related array
-        //
-
-        while( TRUE)
-        {
-
-            pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
-
-            pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
-
-            pCurrentElement->FileId    = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
-
-            lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount);
-
-            lCount = InterlockedIncrement( &NameArray->Count);
-
-            if( pCurrentElement->DirectoryCB == DirectoryCB ||
-                NameArray->Count == RelatedNameArray->Count)
-            {
-
-                //
-                // Done ...
-                //
-
-                break;
-            }
-
-            pCurrentElement++;
-
-            pCurrentRelatedElement++;
-        }
-
-        if( NameArray->Count > 0)
-        {
-            NameArray->CurrentEntry = pCurrentElement;
-        }
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSNameArrayCB *pCurrentElement = NULL;
-    LONG lCount;
-
-    __Enter
-    {
-
-        pCurrentElement = &NameArray->ElementArray[ 0];
-
-        while( TRUE)
-        {
-
-            if( pCurrentElement->DirectoryCB == NULL)
-            {
-
-                break;
-            }
-
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount);
-
-            pCurrentElement++;
-        }
-
-        AFSExFreePool( NameArray);
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
-                      IN AFSDirectoryCB *DirEntry)
+BOOLEAN
+AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
 {
+    UNICODE_STRING uniTempName;
+    BOOLEAN        bIsAbsolute = FALSE;
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    LONG lCount;
+    //
+    // An absolute AFS path must begin with \afs\... or equivalent
+    //
 
-    __Enter
+    if ( Name->Length == 0 ||
+         Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
+         Name->Buffer[ 0] != L'\\' ||
+         Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
     {
 
-        if( NameArray->Count == NameArray->MaxElementCount)
-        {
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        if( NameArray->CurrentEntry != NULL &&
-            NameArray->CurrentEntry->DirectoryCB == DirEntry)
-        {
-
-            try_return( ntStatus);
-        }
-
-        if( NameArray->Count > 0)
-        {
-
-            NameArray->CurrentEntry++;
-        }
-        else
-        {
-            NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
-        }
-
-        lCount = InterlockedIncrement( &NameArray->Count);
-
-        lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
-                      &DirEntry->NameInformation.FileName,
-                      DirEntry,
-                      lCount);
-
-        NameArray->CurrentEntry->DirectoryCB = DirEntry;
-
-        NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
-
-        NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
-
-try_exit:
-
-        NOTHING;
+        return FALSE;
     }
 
-    return ntStatus;
-}
-
-void
-AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
-                          IN AFSDirectoryCB *DirectoryCB)
-{
-    LONG lCount;
-
-    ASSERT( NameArray->CurrentEntry != NULL);
-
-    lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
-
-    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                  AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
-                  &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
-                  NameArray->CurrentEntry->DirectoryCB,
-                  lCount);
-
-    lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
-
-    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                  AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
-                  &DirectoryCB->NameInformation.FileName,
-                  DirectoryCB,
-                  lCount);
+    uniTempName.Length = AFSMountRootName.Length;
+    uniTempName.MaximumLength = AFSMountRootName.Length;
 
-    NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
+    uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                            uniTempName.MaximumLength,
+                                                            AFS_NAME_BUFFER_TWO_TAG);
 
-    NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
-
-    NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
-
-    if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
+    if( uniTempName.Buffer == NULL)
     {
 
-        SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        return FALSE;
     }
 
-    return;
-}
-
-AFSDirectoryCB *
-AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
-{
-
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
-    LONG lCount;
-
-    __Enter
-    {
-
-        if( NameArray->Count == 0)
-        {
-            try_return( pCurrentDirEntry);
-        }
-
-        lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
-                      &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
-                      NameArray->CurrentEntry->DirectoryCB,
-                      lCount);
-
-        NameArray->CurrentEntry->DirectoryCB = NULL;
-
-        lCount = InterlockedDecrement( &NameArray->Count);
-
-        if( lCount == 0)
-        {
-            NameArray->CurrentEntry = NULL;
-        }
-        else
-        {
-            NameArray->CurrentEntry--;
-            pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
-        }
+    RtlCopyMemory( uniTempName.Buffer,
+                   Name->Buffer,
+                   AFSMountRootName.Length);
 
-try_exit:
+    bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
+                                                 &AFSMountRootName,
+                                                 TRUE));
 
-        NOTHING;
-    }
+    AFSExFreePoolWithTag( uniTempName.Buffer,
+                          AFS_NAME_BUFFER_TWO_TAG);
 
-    return pCurrentDirEntry;
+    return bIsAbsolute;
 }
 
-AFSDirectoryCB *
-AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
+
+void
+AFSUpdateName( IN UNICODE_STRING *Name)
 {
 
-    AFSDirectoryCB *pDirEntry = NULL;
-    AFSNameArrayCB *pElement = NULL;
+    USHORT usIndex = 0;
 
-    __Enter
+    while( usIndex < Name->Length/sizeof( WCHAR))
     {
 
-        if( NameArray->Count == 0 ||
-            NameArray->Count == 1)
+        if( Name->Buffer[ usIndex] == L'/')
         {
 
-            try_return( pDirEntry = NULL);
+            Name->Buffer[ usIndex] = L'\\';
         }
 
-        pElement = &NameArray->ElementArray[ NameArray->Count - 2];
-
-        pDirEntry = pElement->DirectoryCB;
-
-try_exit:
-
-        NOTHING;
+        usIndex++;
     }
 
-    return pDirEntry;
+    return;
 }
 
-void
-AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
-                   IN AFSDirectoryCB *DirEntry)
+NTSTATUS
+AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
+                     IN OUT ULONG *Flags,
+                     IN WCHAR *NameBuffer,
+                     IN USHORT NameLength)
 {
 
-    AFSNameArrayCB *pCurrentElement = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    LONG lCount;
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    WCHAR *pTmpBuffer = NULL;
 
     __Enter
     {
 
-        pCurrentElement = &NameArray->ElementArray[ 0];
+        //
+        // If we have enough space then just move in the name otherwise
+        // allocate a new buffer
+        //
 
-        while( TRUE)
+        if( TargetName->Length < NameLength)
         {
 
-            if( pCurrentElement->DirectoryCB == NULL)
+            pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                            NameLength,
+                                                            AFS_NAME_BUFFER_FIVE_TAG);
+
+            if( pTmpBuffer == NULL)
             {
 
-                break;
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
             }
 
-            lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
-                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
-                          pCurrentElement->DirectoryCB,
-                          lCount);
-
-            pCurrentElement++;
-        }
-
-        RtlZeroMemory( NameArray,
-                       sizeof( AFSNameArrayHdr) +
-                          ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
-
-        NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
-
-        if( DirEntry != NULL)
-        {
-
-            NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
-
-            lCount = InterlockedIncrement( &NameArray->Count);
-
-            lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
+            if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
+            {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
-                          &DirEntry->NameInformation.FileName,
-                          DirEntry,
-                          lCount);
+                AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
+            }
 
-            NameArray->CurrentEntry->DirectoryCB = DirEntry;
+            TargetName->MaximumLength = NameLength;
 
-            NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
+            TargetName->Buffer = pTmpBuffer;
 
-            NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
+            SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
         }
-    }
-
-    return;
-}
-
-void
-AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
-{
 
-    AFSNameArrayCB *pCurrentElement = NULL;
+        TargetName->Length = NameLength;
 
-    pCurrentElement = &NameArray->ElementArray[ 0];
+        RtlCopyMemory( TargetName->Buffer,
+                       NameBuffer,
+                       TargetName->Length);
 
-    AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
+        //
+        // Update the name in the buffer
+        //
 
-    while( pCurrentElement->DirectoryCB != NULL)
-    {
+        AFSUpdateName( TargetName);
 
-        AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
-                  pCurrentElement->FileId.Cell,
-                  pCurrentElement->FileId.Volume,
-                  pCurrentElement->FileId.Vnode,
-                  pCurrentElement->FileId.Unique,
-                  &pCurrentElement->DirectoryCB->NameInformation.FileName);
+try_exit:
 
-        pCurrentElement++;
+        NOTHING;
     }
 
-    AFSPrint("AFSDumpNameArray End\n\n");
-
-    return;
+    return ntStatus;
 }
 
 void
@@ -5486,6 +5307,8 @@ AFSVerifyVolume( IN ULONGLONG ProcessId,
                  IN AFSVolumeCB *VolumeCB)
 {
 
+    UNREFERENCED_PARAMETER(ProcessId);
+    UNREFERENCED_PARAMETER(VolumeCB);
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
 
@@ -5493,7 +5316,7 @@ AFSVerifyVolume( IN ULONGLONG ProcessId,
 }
 
 NTSTATUS
-AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
+AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
@@ -5506,23 +5329,32 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
     __Enter
     {
 
-        pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
+        AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+                        TRUE);
+
+        pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
                                                0);
 
         if( pObjectInfoCB == NULL)
         {
 
+            AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
+
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB,
+                                         AFS_OBJECT_REFERENCE_PIOCTL);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
-                      pObjectInfoCB);
+                      "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
+                      pObjectInfoCB,
+                      lCount));
 
-        pObjectInfoCB->ObjectReferenceCount = 1;
+        AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
 
-        pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
+        pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
 
         pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
 
@@ -5535,11 +5367,14 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
         if( pDirNode == NULL)
         {
 
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
+                      pDirNode));
+
         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                                 sizeof( AFSNonPagedDirectoryCB),
                                                                                 AFS_DIR_ENTRY_NP_TAG);
@@ -5583,26 +5418,14 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
         pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
                                                                        TRUE);
 
-        if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
+        if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_WARNING,
-                          "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
-                          ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
-                          pDirNode);
-
-            //
-            // Increment the open reference and handle on the node
-            //
-
-            lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
-                          pDirNode->ObjectInformation,
-                          lCount);
+                          "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
+                          ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
+                          pDirNode));
 
             try_return( ntStatus = STATUS_REPARSE);
         }
@@ -5615,13 +5438,39 @@ try_exit:
             if ( pDirNode != NULL)
             {
 
-                AFSExFreePool( pDirNode);
+                AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
+                              pDirNode));
+
+                AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
+            }
+
+            if( pNonPagedDirEntry != NULL)
+            {
+
+                ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
+
+                AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
             }
 
             if ( pObjectInfoCB != NULL)
             {
 
-                AFSDeleteObjectInfo( pObjectInfoCB);
+                lCount = AFSObjectInfoDecrement( pObjectInfoCB,
+                                                 AFS_OBJECT_REFERENCE_PIOCTL);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
+                              pObjectInfoCB,
+                              lCount));
+
+                if ( lCount == 0)
+                {
+
+                    AFSDeleteObjectInfo( &pObjectInfoCB);
+                }
             }
         }
     }
@@ -5639,11 +5488,15 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
-    UNICODE_STRING uniFullPathName;
+    AFSDirEnumEntry *pDirEntry = NULL;
+    UNICODE_STRING uniFullPathName = {0};
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+    AFSVolumeCB *pNewVolumeCB = NULL;
+    LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
@@ -5857,10 +5710,10 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
                 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
-                              &uniFullPathName);
+                              &uniFullPathName));
 
                 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
             }
@@ -5895,23 +5748,27 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Increment the ref count on the volume and dir entry for correct processing below
         //
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     VolumeReferenceReason);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
+                      "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
                       pVolumeCB,
-                      lCount);
+                      VolumeReferenceReason,
+                      lCount));
 
-        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      lCount);
+                      lCount));
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -5919,63 +5776,65 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                        &uniParsedName,
                                        pNameArray,
                                        AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
-                                       &pVolumeCB,
-                                       &pParentDirEntry,
+                                       pVolumeCB,
+                                       pParentDirEntry,
+                                       &pNewVolumeCB,
+                                       &NewVolumeReferenceReason,
+                                       &pNewParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
 
-        if( !NT_SUCCESS( ntStatus))
+        if ( pNewVolumeCB != NULL)
         {
-
             //
-            // The volume lock was released on failure above
-            // Except for STATUS_OBJECT_NAME_NOT_FOUND
+            // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+            // even if pVolumeCB == pNewVolumeCB.  It is always safe to release
+            // the reference on pVolumeCB that was held prior to the call.
+            // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+            // will be released second.
             //
 
-            if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-            {
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
-                if( pVolumeCB != NULL)
-                {
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
+                          pVolumeCB,
+                          VolumeReferenceReason,
+                          lCount));
 
-                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            pVolumeCB = pNewVolumeCB;
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
-                                  pVolumeCB,
-                                  lCount);
-                }
+            pNewVolumeCB = NULL;
 
-                if( pDirectoryEntry != NULL)
-                {
+            VolumeReferenceReason = NewVolumeReferenceReason;
 
-                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+        }
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryEntry->NameInformation.FileName,
-                                  pDirectoryEntry,
-                                  NULL,
-                                  lCount);
-                }
-                else
-                {
+        //
+        // AFSLocateNameEntry does not alter the reference count of
+        // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+        // a reference held.
+        //
 
-                    lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pParentDirEntry->NameInformation.FileName,
-                                  pParentDirEntry,
-                                  NULL,
-                                  lCount);
-                }
-            }
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
+                      &pParentDirEntry->NameInformation.FileName,
+                      pParentDirEntry,
+                      lCount));
 
-            pVolumeCB = NULL;
+        pParentDirEntry = pNewParentDirEntry;
+
+        pNewParentDirEntry = NULL;
+
+        if( !NT_SUCCESS( ntStatus) ||
+            ntStatus == STATUS_REPARSE)
+        {
 
             try_return( ntStatus);
         }
@@ -5990,13 +5849,13 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Check for the mount point being returned
         //
 
-        if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+            pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
         }
-        else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
-                 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
+        else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
         {
 
             if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
@@ -6023,38 +5882,58 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
         FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
 
-        //
-        // Remove the reference made above
-        //
+try_exit:
 
-        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+        if( pDirEntry != NULL)
+        {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                      &pDirectoryEntry->NameInformation.FileName,
-                      pDirectoryEntry,
-                      NULL,
-                      lCount);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
+        }
 
-try_exit:
+        if( pDirectoryEntry != NULL)
+        {
 
-        if( pDirEntry != NULL)
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
         }
 
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
+                          "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          VolumeReferenceReason,
+                          lCount));
         }
 
         if( pNameArray != NULL)
@@ -6078,10 +5957,10 @@ try_exit:
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
-                AFSExFreePool( uniFullPathName.Buffer);
+                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
             }
 
-            AFSExFreePool( pwchBuffer);
+            AFSExFreePoolWithTag( pwchBuffer, 0);
         }
     }
 
@@ -6120,22 +5999,34 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
         if( pObjectInfo->NonPagedInfo == NULL)
         {
 
-            AFSExFreePool( pObjectInfo);
+            AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
 
             try_return( pObjectInfo = NULL);
         }
 
         ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
-        pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
-
-        pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
+        ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
 
-        pObjectInfo->ParentObjectInformation = ParentObjectInfo;
+        pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
 
         if( ParentObjectInfo != NULL)
         {
-            lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
+
+            pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
+
+            pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
+
+            SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+
+            lCount = AFSObjectInfoIncrement( ParentObjectInfo,
+                                             AFS_OBJECT_REFERENCE_CHILD);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
+                          ParentObjectInfo,
+                          lCount));
         }
 
         //
@@ -6147,6 +6038,8 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
         if( HashIndex != 0)
         {
 
+            ASSERT( ParentObjectInfo);
+
             //
             // Insert the entry into the object tree and list
             //
@@ -6174,127 +6067,335 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
             if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
             {
 
-                ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
-            }
-            else
-            {
+                ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
+            }
+            else
+            {
+
+                ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
+
+                pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
+            }
+
+            ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
+
+            //
+            // Indicate the object is in the hash tree and linked list in the volume
+            //
+
+            SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
+        }
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return pObjectInfo;
+}
+
+LONG
+AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
+                        IN LONG Reason)
+{
+
+    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);
+        }
+    }
+
+    InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+LONG
+AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
+                        IN LONG Reason)
+{
+
+    LONG lCount, lCount2;
+
+    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);
+    }
+
+    lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
+
+    ASSERT( lCount2 >= 0);
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+AFSObjectInfoCB *
+AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
+                   IN AFSFileID   *FileId)
+{
+    DWORD            ntStatus = STATUS_SUCCESS;
+    ULONGLONG        ullIndex;
+    AFSObjectInfoCB *pObjectInfo = NULL;
+    LONG             lCount;
+
+    ullIndex = AFSCreateLowIndex( FileId);
 
-                ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
+    AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+                      TRUE);
 
-                pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
-            }
+    if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
+    {
 
-            ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
+        pObjectInfo = &VolumeCB->ObjectInformation;
+    }
+    else
+    {
 
-            //
-            // Indicate the object is in the hash tree and linked list in the volume
-            //
+        ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
+                                       ullIndex,
+                                       (AFSBTreeEntry **)&pObjectInfo);
+    }
 
-            SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
-        }
+    if ( NT_SUCCESS( ntStatus)) {
 
-try_exit:
+        lCount = AFSObjectInfoIncrement( pObjectInfo,
+                                         AFS_OBJECT_REFERENCE_FIND);
 
-        NOTHING;
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
+                      pObjectInfo,
+                      lCount));
     }
 
+    AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+
     return pObjectInfo;
 }
 
 void
-AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
+AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
 {
+    LONG lCount;
+
+    lCount = AFSObjectInfoDecrement( *ppObjectInfo,
+                                     AFS_OBJECT_REFERENCE_FIND);
+
+    AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                  AFS_TRACE_LEVEL_VERBOSE,
+                  "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
+                  *ppObjectInfo,
+                  lCount));
 
+    *ppObjectInfo = NULL;
+}
+
+void
+AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
+{
     BOOLEAN bAcquiredTreeLock = FALSE;
+    AFSObjectInfoCB *pObjectInfo = NULL;
+    AFSVolumeCB * pVolume = NULL;
+    BOOLEAN bHeldInService;
+    AFSObjectInfoCB * pParentObjectInfo = NULL;
+    AFSFileID FileId;
     LONG lCount;
 
-    if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
+    __Enter
     {
+        if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
+        {
 
-        ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
+            //
+            // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
+            // embedded in the VolumeCB.
+            //
 
-        AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
-                        TRUE);
+            ASSERT( FALSE);
 
-        bAcquiredTreeLock = TRUE;
-    }
+            return;
+        }
 
-    //
-    // Remove it from the tree and list if it was inserted
-    //
+        pVolume = (*ppObjectInfo)->VolumeCB;
 
-    if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
-    {
+        if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
+        {
 
-        AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
-                            &ObjectInfo->TreeEntry);
-    }
+            ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
 
-    if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
-    {
+            AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
+                            TRUE);
+
+            bAcquiredTreeLock = TRUE;
+        }
+
+        for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
+        {
+
+            ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
+        }
+
+        ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
 
-        if( ObjectInfo->ListEntry.fLink == NULL)
+        pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
+                                                                             NULL,
+                                                                             *ppObjectInfo);
+
+        if ( pObjectInfo == NULL)
         {
 
-            ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
+            try_return( NOTHING);
+        }
+
+        ASSERT( *ppObjectInfo == NULL);
+
+        if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
+        {
 
-            if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
+            pParentObjectInfo = AFSFindObjectInfo( pVolume,
+                                                   &pObjectInfo->ParentFileId);
+            if( pParentObjectInfo != NULL)
             {
 
-                ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
+                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+
+                lCount = AFSObjectInfoDecrement( pParentObjectInfo,
+                                                 AFS_OBJECT_REFERENCE_CHILD);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
+                              pParentObjectInfo,
+                              lCount));
+
+                AFSReleaseObjectInfo( &pParentObjectInfo);
             }
         }
-        else
+
+        //
+        // Remove it from the tree and list if it was inserted
+        //
+
+        if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
         {
 
-            ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
+            AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
+                                &pObjectInfo->TreeEntry);
         }
 
-        if( ObjectInfo->ListEntry.bLink == NULL)
+        if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
         {
 
-            ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
+            if( pObjectInfo->ListEntry.fLink == NULL)
+            {
+
+                pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
+
+                if( pVolume->ObjectInfoListTail != NULL)
+                {
+
+                    pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
+                }
+            }
+            else
+            {
+
+                ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
+            }
+
+            if( pObjectInfo->ListEntry.bLink == NULL)
+            {
+
+                pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
+
+                if( pVolume->ObjectInfoListHead != NULL)
+                {
 
-            if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
+                    pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
+                }
+            }
+            else
             {
 
-                ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
+                ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
             }
         }
-        else
+
+        bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
+
+        if( bHeldInService)
         {
 
-            ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
+            FileId = pObjectInfo->FileId;
         }
-    }
 
-    if( ObjectInfo->ParentObjectInformation != NULL)
-    {
+        ASSERT( pObjectInfo->ObjectReferenceCount == 0);
 
-        lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
-    }
+        ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
 
-    if( bAcquiredTreeLock)
-    {
+        ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
-        AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
-    }
+        AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
 
-    //
-    // Release the fid in the service
-    //
+        AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
 
-    if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
-    {
+try_exit:
 
-        AFSReleaseFid( &ObjectInfo->FileId);
-    }
+        if( bAcquiredTreeLock)
+        {
+
+            AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
+        }
 
-    ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
+        //
+        // Release the fid in the service
+        //
 
-    AFSExFreePool( ObjectInfo->NonPagedInfo);
+        if( bHeldInService)
+        {
 
-    AFSExFreePool( ObjectInfo);
+            AFSReleaseFid( &FileId);
+        }
+    }
 
     return;
 }
@@ -6305,11 +6406,15 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
-    UNICODE_STRING uniFullPathName;
+    AFSDirEnumEntry *pDirEntry = NULL;
+    UNICODE_STRING uniFullPathName = {0};
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+    AFSVolumeCB *pNewVolumeCB = NULL;
+    LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
@@ -6468,23 +6573,27 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         pParentDirEntry = AFSGlobalRoot->DirectoryCB;
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
+
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     VolumeReferenceReason);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
+                      "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
                       pVolumeCB,
-                      lCount);
+                      VolumeReferenceReason,
+                      lCount));
 
-        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      lCount);
+                      lCount));
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -6492,61 +6601,65 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                        &uniParsedName,
                                        pNameArray,
                                        0,
-                                       &pVolumeCB,
-                                       &pParentDirEntry,
+                                       pVolumeCB,
+                                       pParentDirEntry,
+                                       &pNewVolumeCB,
+                                       &VolumeReferenceReason,
+                                       &pNewParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
 
-        if( !NT_SUCCESS( ntStatus))
+        if ( pNewVolumeCB != NULL)
         {
-
             //
-            // The volume lock was released on failure above
-            // Except for STATUS_OBJECT_NAME_NOT_FOUND
+            // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+            // even if pVolumeCB == pNewVolumeCB.  It is always safe to release
+            // the reference on pVolumeCB that was held prior to the call.
+            // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+            // will be released second.
             //
 
-            if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-            {
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
-                if( pVolumeCB != NULL)
-                {
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
+                          pVolumeCB,
+                          VolumeReferenceReason,
+                          lCount));
 
-                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            pVolumeCB = pNewVolumeCB;
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
-                                  pVolumeCB,
-                                  lCount);
-                }
+            pNewVolumeCB = NULL;
 
-                if( pDirectoryEntry != NULL)
-                {
+            VolumeReferenceReason = NewVolumeReferenceReason;
 
-                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+        }
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryEntry->NameInformation.FileName,
-                                  pDirectoryEntry,
-                                  NULL,
-                                  lCount);
-                }
-                else
-                {
+        //
+        // AFSLocateNameEntry does not alter the reference count of
+        // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+        // a reference held.
+        //
 
-                    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",
-                                  &pParentDirEntry->NameInformation.FileName,
-                                  pParentDirEntry,
-                                  NULL,
-                                  lCount);
-                }
-            }
+        AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
+                      &pParentDirEntry->NameInformation.FileName,
+                      pParentDirEntry,
+                      lCount));
+
+        pParentDirEntry = pNewParentDirEntry;
+
+        pNewParentDirEntry = NULL;
+
+        if( !NT_SUCCESS( ntStatus) ||
+            ntStatus == STATUS_REPARSE)
+        {
 
             pVolumeCB = NULL;
 
@@ -6555,28 +6668,65 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         //
         // Pass back the target dir entry for this request
+        // The caller must release the DirOpenReferenceCount
         //
 
         *TargetDirEntry = pDirectoryEntry;
 
+        pDirectoryEntry = NULL;
+
 try_exit:
 
+        if( pDirectoryEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
 
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
+                          "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          VolumeReferenceReason,
+                          lCount));
         }
 
         if( pNameArray != NULL)
@@ -6600,10 +6750,10 @@ try_exit:
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
-                AFSExFreePool( uniFullPathName.Buffer);
+                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
             }
 
-            AFSExFreePool( pwchBuffer);
+            AFSExFreePoolWithTag( pwchBuffer, 0);
         }
     }
 
@@ -6634,12 +6784,27 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
             {
 
-                AFSAcquireExcl( &Fcb->NPFcb->Resource,
-                                TRUE);
+                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
+                              &Fcb->NPFcb->Resource,
+                              PsGetCurrentThread()));
+
+                AFSAcquireShared( &Fcb->NPFcb->Resource,
+                                  TRUE);
 
                 if( Fcb->OpenReferenceCount > 0)
                 {
 
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                  &Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread()));
+
+                    AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
+                                    TRUE);
+
                     __try
                     {
 
@@ -6651,7 +6816,7 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                         if( !NT_SUCCESS( stIoStatus.Status))
                         {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                            AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
                                           AFS_TRACE_LEVEL_ERROR,
                                           "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                           Fcb->ObjectInformation->FileId.Cell,
@@ -6659,22 +6824,64 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                                           Fcb->ObjectInformation->FileId.Vnode,
                                           Fcb->ObjectInformation->FileId.Unique,
                                           stIoStatus.Status,
-                                          stIoStatus.Information);
+                                          stIoStatus.Information));
 
                             ntStatus = stIoStatus.Status;
                         }
 
-                        CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                             NULL,
-                                             0,
-                                             FALSE);
+                        if (  Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                        {
+
+                            if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                       NULL,
+                                                       0,
+                                                       FALSE))
+                            {
+
+                                AFSDbgTrace(( 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)
                     {
+
                         ntStatus = GetExceptionCode();
+
+                        AFSDbgTrace(( 0,
+                                      0,
+                                      "EXCEPTION - AFSCleanupFcb Cc [1] 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));
+
+                        SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                     }
+
+                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                  &Fcb->NPFcb->SectionObjectResource,
+                                  PsGetCurrentThread()));
+
+                    AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
                 }
 
+                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
+                              &Fcb->NPFcb->Resource,
+                              PsGetCurrentThread()));
+
                 AFSReleaseResource( &Fcb->NPFcb->Resource);
 
                 //
@@ -6692,7 +6899,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 {
 
                     AFSReleaseExtentsWithFlush( Fcb,
-                                                NULL);
+                                                NULL,
+                                                TRUE);
                 }
             }
 
@@ -6714,10 +6922,19 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
         // First up are there dirty extents in the cache to flush?
         //
 
-        if( ForceFlush ||
-            ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
-              !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
-              ( Fcb->Specific.File.ExtentsDirtyCount ||
+        if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
+            BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
+        {
+
+            //
+            // The file has been marked as invalid.  Dump it
+            //
+
+            AFSTearDownFcbExtents( Fcb,
+                                   NULL);
+        }
+        else if( ForceFlush ||
+            ( ( Fcb->Specific.File.ExtentsDirtyCount ||
                 Fcb->Specific.File.ExtentCount) &&
               (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
                                                     >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
@@ -6728,20 +6945,10 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
             {
 
                 AFSReleaseExtentsWithFlush( Fcb,
-                                            NULL);
+                                            NULL,
+                                            TRUE);
             }
         }
-        else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
-                 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
-        {
-
-            //
-            // The file has been marked as invalid.  Dump it
-            //
-
-            AFSTearDownFcbExtents( Fcb,
-                                   NULL);
-        }
 
         //
         // If there are extents and they haven't been used recently *and*
@@ -6752,60 +6959,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
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                          &Fcb->NPFcb->SectionObjectResource,
+                          PsGetCurrentThread()));
+
+            if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
             {
 
-                CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
-                              NULL,
-                              0,
-                              &stIoStatus);
+                __try
+                {
+
+                    CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
+                                  NULL,
+                                  0,
+                                  &stIoStatus);
+
+                    if( !NT_SUCCESS( stIoStatus.Status))
+                    {
+
+                        AFSDbgTrace(( 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 &&
+                        Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                    {
+
+                        if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgTrace(( 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));
 
-                if( !NT_SUCCESS( stIoStatus.Status))
+                            SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
+                    }
+                }
+                __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
-                    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",
+                    ntStatus = GetExceptionCode();
+
+                    AFSDbgTrace(( 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,
-                                  stIoStatus.Status,
-                                  stIoStatus.Information);
-
-                    ntStatus = stIoStatus.Status;
+                                  ntStatus));
                 }
 
-                if( ForceFlush)
+                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                              &Fcb->NPFcb->SectionObjectResource,
+                              PsGetCurrentThread()));
+
+                AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
+
+                if( Fcb->OpenReferenceCount <= 0)
                 {
 
-                    CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                         NULL,
-                                         0,
-                                         FALSE);
+                    //
+                    // Tear em down we'll not be needing them again
+                    //
+
+                    AFSTearDownFcbExtents( Fcb,
+                                           NULL);
                 }
             }
-            __except( EXCEPTION_EXECUTE_HANDLER)
-            {
-                ntStatus = GetExceptionCode();
-            }
-
-            AFSReleaseResource( &Fcb->NPFcb->Resource);
-
-            if( Fcb->OpenReferenceCount == 0)
+            else
             {
 
-                //
-                // Tear em down we'll not be needing them again
-                //
-
-                AFSTearDownFcbExtents( Fcb,
-                                       NULL);
+                ntStatus = STATUS_RETRY;
             }
         }
 
@@ -6834,7 +7083,7 @@ AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
             if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
             {
 
-                AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
+                AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
 
                 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
 
@@ -6887,7 +7136,6 @@ AFSReadCacheFile( IN void *ReadBuffer,
     PIRP                pIrp = NULL;
     KEVENT              kEvent;
     PIO_STACK_LOCATION  pIoStackLocation = NULL;
-    AFSDeviceExt       *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     DEVICE_OBJECT      *pTargetDeviceObject = NULL;
     FILE_OBJECT        *pCacheFileObject = NULL;
 
@@ -7028,6 +7276,8 @@ AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
                 IN PVOID          Context)
 {
 
+    UNREFERENCED_PARAMETER(Irp);
+    UNREFERENCED_PARAMETER(DeviceObject);
     KEVENT *pEvent = (KEVENT *)Context;
 
     KeSetEvent( pEvent,
@@ -7047,6 +7297,8 @@ AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
     __Enter
     {
 
+        ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
+
         AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
                           TRUE);
 
@@ -7093,11 +7345,11 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
 
             try_return( ntStatus);
         }
@@ -7108,20 +7360,20 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         // Remove the entry from the parent tree
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
                       DirEntry,
-                      &DirEntry->NameInformation.FileName);
+                      &DirEntry->NameInformation.FileName));
 
         AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                         DirEntry);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
                       DirEntry,
-                      &DirEntry->NameInformation.FileName);
+                      &DirEntry->NameInformation.FileName));
 
         AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
                                           DirEntry);
@@ -7133,11 +7385,11 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             // From the short name tree
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
                           DirEntry,
-                          &DirEntry->NameInformation.FileName);
+                          &DirEntry->NameInformation.FileName));
 
             AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
                                         DirEntry);
@@ -7145,11 +7397,11 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
                       DirEntry,
-                      &DirEntry->NameInformation.FileName);
+                      &DirEntry->NameInformation.FileName));
 
         SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
 
@@ -7192,9 +7444,9 @@ AFSGetAuthenticationId()
             if( hToken == NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+                AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
+                              "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
 
                 try_return( ntStatus);
             }
@@ -7209,9 +7461,10 @@ AFSGetAuthenticationId()
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+            AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
+                          "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -7219,10 +7472,10 @@ AFSGetAuthenticationId()
         liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
         liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
+        AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
-                      liAuthId.QuadPart);
+                      liAuthId.QuadPart));
 
 try_exit:
 
@@ -7244,7 +7497,7 @@ try_exit:
         if( pTokenInfo != NULL)
         {
 
-            AFSExFreePool( pTokenInfo);
+            ExFreePool( pTokenInfo);    // Allocated by SeQueryInformationToken
         }
     }
 
@@ -7256,29 +7509,30 @@ AFSUnwindFileInfo( IN AFSFcb *Fcb,
                    IN AFSCcb *Ccb)
 {
 
+    UNREFERENCED_PARAMETER(Fcb);
     if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
     {
-        Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
+        Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
     }
 
     if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
     {
-        Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
+        Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
     }
 
     if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
     {
-        Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
+        Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
     }
 
     if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
     {
-        Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
+        Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
     }
 
     if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
     {
-        Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
+        Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
     }
 
     return;
@@ -7320,7 +7574,7 @@ AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
         pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
     }
 
-    if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
+    if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
     {
 
         AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
@@ -7375,6 +7629,7 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pControlDevExt = NULL;
     ULONG ulTimeIncrement = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -7385,6 +7640,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSServerName = LibraryInit->AFSServerName;
 
+        AFSMountRootName = LibraryInit->AFSMountRootName;
+
         AFSDebugFlags = LibraryInit->AFSDebugFlags;
 
         //
@@ -7395,11 +7652,13 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
 
+        AFSDebugTraceFnc = AFSDbgLogMsg;
+
         AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
 
         AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
 
-        AFSExFreePool = LibraryInit->AFSExFreePool;
+        AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
 
         AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
 
@@ -7437,15 +7696,16 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         ntStatus = AFSInitVolume( NULL,
                                   &LibraryInit->GlobalRootFid,
+                                  AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
                                   &AFSGlobalRoot);
 
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
-                          ntStatus);
+                          ntStatus));
 
             try_return( ntStatus);
         }
@@ -7456,10 +7716,19 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
         if( !NT_SUCCESS( ntStatus))
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
-                          ntStatus);
+                          ntStatus));
+
+            lCount = AFSVolumeDecrement( AFSGlobalRoot,
+                                         AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
+                          AFSGlobalRoot,
+                          lCount));
 
             AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
@@ -7487,6 +7756,15 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSInitVolumeWorker( AFSGlobalRoot);
 
+        lCount = AFSVolumeDecrement( AFSGlobalRoot,
+                                     AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
+
+        AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
+                      AFSGlobalRoot,
+                      lCount));
+
         AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
         AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
@@ -7505,6 +7783,7 @@ AFSCloseLibrary()
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -7512,7 +7791,20 @@ AFSCloseLibrary()
         if( AFSGlobalDotDirEntry != NULL)
         {
 
-            AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
+            lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
+                          AFSGlobalDotDirEntry->ObjectInformation,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
+            }
 
             ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
 
@@ -7526,7 +7818,20 @@ AFSCloseLibrary()
         if( AFSGlobalDotDotDirEntry != NULL)
         {
 
-            AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
+            lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
+                                             AFS_OBJECT_REFERENCE_GLOBAL);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
+                          AFSGlobalDotDotDirEntry->ObjectInformation,
+                          lCount));
+
+            if ( lCount == 0)
+            {
+
+                AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
+            }
 
             ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
 
@@ -7547,7 +7852,20 @@ AFSCloseLibrary()
 
                 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
 
-                AFSDeleteObjectInfo( pDirNode->ObjectInformation);
+                lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
+                                                 AFS_OBJECT_REFERENCE_GLOBAL);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
+                              pDirNode->ObjectInformation,
+                              lCount));
+
+                if ( lCount == 0)
+                {
+
+                    AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
+                }
 
                 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
 
@@ -7572,6 +7890,8 @@ AFSDefaultLogMsg( IN ULONG Subsystem,
                   ...)
 {
 
+    UNREFERENCED_PARAMETER(Subsystem);
+    UNREFERENCED_PARAMETER(Level);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     va_list va_args;
     char chDebugBuffer[ 256];
@@ -7605,14 +7925,17 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSFcb   *pFcb = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+    AFSVolumeCB *pNewVolumeCB = NULL;
+    LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfo = NULL;
     ULONGLONG   ullIndex = 0;
     UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
     AFSNameArrayHdr *pNameArray = NULL;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     LONG lCount;
 
     __Enter
@@ -7644,13 +7967,17 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             if( pVolumeCB != NULL)
             {
 
-                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                lCount = AFSVolumeIncrement( pVolumeCB,
+                                             VolumeReferenceReason);
+
+                AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
+                              "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
                               pVolumeCB,
-                              lCount);
+                              VolumeReferenceReason,
+                              lCount));
             }
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -7666,9 +7993,14 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 pObjectInfo = &pVolumeCB->ObjectInformation;
 
-                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo,
+                                                 AFS_OBJECT_REFERENCE_STATUS);
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
+                              pObjectInfo,
+                              lCount));
             }
             else
             {
@@ -7676,14 +8008,6 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                                   TRUE);
 
-                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);
-
                 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
 
                 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
@@ -7697,13 +8021,14 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     // Reference the node so it won't be torn down
                     //
 
-                    lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    lCount = AFSObjectInfoIncrement( pObjectInfo,
+                                                     AFS_OBJECT_REFERENCE_STATUS);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
+                                  "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
                                   pObjectInfo,
-                                  lCount);
+                                  lCount));
                 }
 
                 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -7741,10 +8066,10 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                          &AFSServerName,
                                          TRUE) != 0)
             {
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSGetObjectStatus Name %wZ contains invalid server name\n",
-                              &uniFullPathName);
+                              &uniFullPathName));
 
                 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
             }
@@ -7773,23 +8098,27 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             // Increment the ref count on the volume and dir entry for correct processing below
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         VolumeReferenceReason);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
+                          "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
-                          lCount);
+                          VolumeReferenceReason,
+                          lCount));
 
-            lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
                           &pParentDirEntry->NameInformation.FileName,
                           pParentDirEntry,
                           NULL,
-                          lCount);
+                          lCount));
 
             ntStatus = AFSLocateNameEntry( NULL,
                                            NULL,
@@ -7797,89 +8126,83 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            &uniParsedName,
                                            pNameArray,
                                            AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
-                                                        AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
-                                           &pVolumeCB,
-                                           &pParentDirEntry,
+                                               AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
+                                           pVolumeCB,
+                                           pParentDirEntry,
+                                           &pNewVolumeCB,
+                                           &NewVolumeReferenceReason,
+                                           &pNewParentDirEntry,
                                            &pDirectoryEntry,
                                            NULL);
 
-            if( !NT_SUCCESS( ntStatus))
+            if ( pNewVolumeCB != NULL)
             {
 
                 //
-                // The volume lock was released on failure above
-                // Except for STATUS_OBJECT_NAME_NOT_FOUND
+                // AFSLocateNameEntry returns pNewVolumeCB with a reference held
+                // even if pVolumeCB == pNewVolumeCB.  It is always safe to release
+                // the reference on pVolumeCB that was held prior to the call.
+                // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
+                // will be released second.
                 //
 
-                if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-                {
-
-                    if( pVolumeCB != NULL)
-                    {
-
-                        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pVolumeCB,
+                                             VolumeReferenceReason);
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
-                                      pVolumeCB,
-                                      lCount);
-                    }
-
-                    if( pDirectoryEntry != NULL)
-                    {
-
-                        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
-
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pDirectoryEntry->NameInformation.FileName,
-                                      pDirectoryEntry,
-                                      NULL,
-                                      lCount);
-                    }
-                    else
-                    {
+                AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
+                              pVolumeCB,
+                              VolumeReferenceReason,
+                              lCount));
 
-                        lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                pVolumeCB = pNewVolumeCB;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pParentDirEntry->NameInformation.FileName,
-                                      pParentDirEntry,
-                                      NULL,
-                                      lCount);
-                    }
-                }
+                pNewVolumeCB = NULL;
 
-                pVolumeCB = NULL;
+                VolumeReferenceReason = NewVolumeReferenceReason;
 
-                try_return( ntStatus);
+                NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
             }
 
             //
-            // Remove the reference made above
+            // AFSLocateNameEntry does not alter the reference count of
+            // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+            // a reference held.
             //
 
-            lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
-            pObjectInfo = pDirectoryEntry->ObjectInformation;
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          lCount));
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            pParentDirEntry = pNewParentDirEntry;
 
-            if( pVolumeCB != NULL)
+            pNewParentDirEntry = NULL;
+
+            if( !NT_SUCCESS( ntStatus) ||
+                ntStatus == STATUS_REPARSE)
             {
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                pVolumeCB = NULL;
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
-                              pVolumeCB,
-                              pVolumeCB->VolumeReferenceCount);
+                try_return( ntStatus);
             }
+
+            pObjectInfo = pDirectoryEntry->ObjectInformation;
+
+            lCount = AFSObjectInfoIncrement( pObjectInfo,
+                                             AFS_OBJECT_REFERENCE_STATUS);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
+                          pObjectInfo,
+                          lCount));
         }
 
         //
@@ -7924,10 +8247,63 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
 try_exit:
 
+        if( pDirectoryEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount));
+
+            ASSERT( lCount >= 0);
+        }
+
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo,
+                                             AFS_OBJECT_REFERENCE_STATUS);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
+                          pObjectInfo,
+                          lCount));
+        }
+
+        if( pVolumeCB != NULL)
+        {
+
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
+
+            AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
+                          pVolumeCB,
+                          VolumeReferenceReason,
+                          lCount));
         }
 
         if( pNameArray != NULL)
@@ -7946,6 +8322,7 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSDirectoryCB *pDirEntry = NULL;
     ULONG ulCRC = 0;
     LONG lCount;
@@ -7957,10 +8334,10 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
         // Search for the entry in the parent
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
-                      ComponentName);
+                      ComponentName));
 
         ulCRC = AFSGenerateCRC( ComponentName,
                                 FALSE);
@@ -7979,10 +8356,10 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
             // Missed so perform a case insensitive lookup
             //
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
-                          ComponentName);
+                          ComponentName));
 
             ulCRC = AFSGenerateCRC( ComponentName,
                                     TRUE);
@@ -7999,15 +8376,16 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
                 // a lookup in the short name tree
                 //
 
-                if( RtlIsNameLegalDOS8Dot3( ComponentName,
+                if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+                    RtlIsNameLegalDOS8Dot3( ComponentName,
                                             NULL,
                                             NULL))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_VERBOSE_2,
                                   "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
-                                  ComponentName);
+                                  ComponentName));
 
                     AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
                                                 ulCRC,
@@ -8018,7 +8396,17 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         if( pDirEntry != NULL)
         {
-            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgTrace(( 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);
@@ -8026,10 +8414,11 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
         if( pDirEntry == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
-                          "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
-                          ComponentName);
+                          "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
+                          ComponentName,
+                          STATUS_OBJECT_NAME_NOT_FOUND));
 
             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
         }
@@ -8039,14 +8428,24 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
         // denied.
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
                       "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
-                      ComponentName);
+                      ComponentName));
 
         ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
-        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+        AFSDbgTrace(( 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:
 
@@ -8154,6 +8553,7 @@ AFSCreateDefaultSecurityDescriptor()
         if( pWorldSID == NULL)
         {
             AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
+
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
@@ -8396,8 +8796,6 @@ AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
                        OUT UNICODE_STRING *ParentPath)
 {
 
-    USHORT usIndex = 0;
-
     *ParentPath = *FullFileName;
 
     //
@@ -8531,12 +8929,13 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                             IN ULONG InvalidateReason)
 {
 
+    AFSDeviceExt       *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     NTSTATUS            ntStatus = STATUS_SUCCESS;
-    IO_STATUS_BLOCK     stIoStatus;
     LIST_ENTRY         *le;
     AFSExtent          *pEntry;
     ULONG               ulProcessCount = 0;
     ULONG               ulCount = 0;
+    LONG                lCount;
 
     __Enter
     {
@@ -8551,6 +8950,16 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                     ObjectInfo->Fcb != NULL)
                 {
 
+                    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,
+                                0,
+                                FALSE);
 
                     //
                     // Clear out the extents
@@ -8558,8 +8967,10 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                     // for any writes or reads to the cache to complete)
                     //
 
-                    (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
-                                                  NULL);
+                    AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                           NULL);
+
+                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
                 }
 
                 break;
@@ -8571,6 +8982,9 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                 LARGE_INTEGER liCurrentOffset = {0,0};
                 LARGE_INTEGER liFlushLength = {0,0};
                 ULONG ulFlushLength = 0;
+                BOOLEAN bLocked = FALSE;
+                BOOLEAN bExtentsLocked = FALSE;
+                BOOLEAN bCleanExtents = FALSE;
 
                 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
                     ObjectInfo->Fcb != NULL)
@@ -8579,117 +8993,474 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                     AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
                                     TRUE);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX EXCL %08lX\n",
-                                  &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
-                                  PsGetCurrentThread());
-
-                    AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
-                                      TRUE);
+                    bLocked = TRUE;
 
-                    __try
+                    if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
                     {
 
-                        le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                      &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread()));
+
+                        AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                        TRUE);
+
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                        bLocked = FALSE;
+
+                        __try
+                        {
+
+                            if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                      NULL,
+                                                      0,
+                                                      FALSE))
+                            {
+
+                                AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                              AFS_TRACE_LEVEL_WARNING,
+                                              "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                              ObjectInfo->FileId.Cell,
+                                              ObjectInfo->FileId.Volume,
+                                              ObjectInfo->FileId.Vnode,
+                                              ObjectInfo->FileId.Unique));
+
+                                SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                            }
+                            else
+                            {
+
+                                bCleanExtents = TRUE;
+                            }
+                        }
+                        __except( EXCEPTION_EXECUTE_HANDLER)
+                        {
+
+                            ntStatus = GetExceptionCode();
+
+                            AFSDbgTrace(( 0,
+                                          0,
+                                          "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                          ObjectInfo->FileId.Cell,
+                                          ObjectInfo->FileId.Volume,
+                                          ObjectInfo->FileId.Vnode,
+                                          ObjectInfo->FileId.Unique,
+                                          ntStatus));
+
+                            SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
+
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                      &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                      PsGetCurrentThread()));
+
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
+                    }
+                    else
+                    {
 
-                        ulProcessCount = 0;
+                        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
+                                      &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                      PsGetCurrentThread()));
 
-                        ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+                        AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                          TRUE);
 
-                        if( ulCount > 0)
+                        bExtentsLocked = TRUE;
+
+                        //
+                        // There are several possibilities here:
+                        //
+                        // 0. If there are no extents or all of the extents are dirty, do nothing.
+                        //
+                        // 1. There could be nothing dirty and an open reference count of zero
+                        //    in which case we can just tear down all of the extents without
+                        //    holding any resources.
+                        //
+                        // 2. There could be nothing dirty and a non-zero open reference count
+                        //    in which case we can issue a CcPurge against the entire file
+                        //    while holding just the Fcb Resource.
+                        //
+                        // 3. There can be dirty extents in which case we need to identify
+                        //    the non-dirty ranges and then perform a CcPurge on just the
+                        //    non-dirty ranges while holding just the Fcb Resource.
+                        //
+
+                        if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
                         {
-                            pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                            while( ulProcessCount < ulCount)
+                            if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
                             {
-                                pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                                if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                bExtentsLocked = FALSE;
+
+                                if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+                                {
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                    bLocked = FALSE;
+
+                                    AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                                           NULL);
+                                }
+                                else
                                 {
-                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                              &pEntry->FileOffset,
-                                                              pEntry->Size,
-                                                              FALSE))
+
+                                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                                  AFS_TRACE_LEVEL_VERBOSE,
+                                                  "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                                  &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                                  PsGetCurrentThread()));
+
+                                    AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                                    TRUE);
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                    bLocked = FALSE;
+
+                                    __try
+                                    {
+
+                                        if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                            !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                  NULL,
+                                                                  0,
+                                                                  FALSE))
+                                        {
+
+                                            AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                          AFS_TRACE_LEVEL_WARNING,
+                                                          "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                          ObjectInfo->FileId.Cell,
+                                                          ObjectInfo->FileId.Volume,
+                                                          ObjectInfo->FileId.Vnode,
+                                                          ObjectInfo->FileId.Unique));
+
+                                            SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                        }
+                                        else
+                                        {
+
+                                            bCleanExtents = TRUE;
+                                        }
+                                    }
+                                    __except( EXCEPTION_EXECUTE_HANDLER)
                                     {
+
+                                        ntStatus = GetExceptionCode();
+
+                                        AFSDbgTrace(( 0,
+                                                      0,
+                                                      "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                                      ObjectInfo->FileId.Cell,
+                                                      ObjectInfo->FileId.Volume,
+                                                      ObjectInfo->FileId.Vnode,
+                                                      ObjectInfo->FileId.Unique,
+                                                      ntStatus));
+
                                         SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                                     }
+
+                                    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                                  AFS_TRACE_LEVEL_VERBOSE,
+                                                  "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                                  &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                                  PsGetCurrentThread()));
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
                                 }
+                            }
+                            else
+                            {
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                bExtentsLocked = FALSE;
+
+                                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+                                              &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                              PsGetCurrentThread()));
+
+                                AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                                TRUE);
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                bLocked = FALSE;
 
-                                if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+                                //
+                                // 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)
+                                // ranges.  In all but the most extreme random data write scenario there will
+                                // be significantly fewer.
+                                //
+                                // For each range we need offset and size.
+                                //
+
+                                AFSByteRange * ByteRangeList = NULL;
+                                ULONG          ulByteRangeCount = 0;
+                                ULONG          ulIndex;
+                                BOOLEAN        bPurgeOnClose = FALSE;
+
+                                __try
                                 {
 
-                                    liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+                                    ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
+                                                                                       &ByteRangeList);
+
+                                    if ( ByteRangeList != NULL ||
+                                         ulByteRangeCount == 0)
+                                    {
+
+                                        for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
+                                        {
+
+                                            ULONG ulSize;
+
+                                            do {
 
-                                    while( liFlushLength.QuadPart > 0)
+                                                ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
+
+                                                if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                                    !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                          &ByteRangeList[ulIndex].FileOffset,
+                                                                          ulSize,
+                                                                          FALSE))
+                                                {
+
+                                                    AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                  AFS_TRACE_LEVEL_WARNING,
+                                                                  "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                  ObjectInfo->FileId.Cell,
+                                                                  ObjectInfo->FileId.Volume,
+                                                                  ObjectInfo->FileId.Vnode,
+                                                                  ObjectInfo->FileId.Unique));
+
+                                                    bPurgeOnClose = TRUE;
+                                                }
+                                                else
+                                                {
+
+                                                    bCleanExtents = TRUE;
+                                                }
+
+                                                ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
+
+                                                ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
+
+                                            } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
+                                        }
+                                    }
+                                    else
                                     {
 
-                                        if( liFlushLength.QuadPart > 512 * 1024000)
+                                        //
+                                        // We couldn't allocate the memory to build the purge list
+                                        // so just walk the extent list while holding the ExtentsList Resource.
+                                        // 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;
+
+                                        ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+
+                                        if( ulCount > 0)
                                         {
-                                            ulFlushLength = 512 * 1024000;
+                                            pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                                            while( ulProcessCount < ulCount)
+                                            {
+                                                pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                                                if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                                                {
+                                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                              &pEntry->FileOffset,
+                                                                              pEntry->Size,
+                                                                              FALSE))
+                                                    {
+
+                                                        AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                      AFS_TRACE_LEVEL_WARNING,
+                                                                      "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                      ObjectInfo->FileId.Cell,
+                                                                      ObjectInfo->FileId.Volume,
+                                                                      ObjectInfo->FileId.Vnode,
+                                                                      ObjectInfo->FileId.Unique));
+
+                                                        bPurgeOnClose = TRUE;
+                                                    }
+                                                    else
+                                                    {
+
+                                                        bCleanExtents = TRUE;
+                                                    }
+                                                }
+
+                                                if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+                                                {
+
+                                                    liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+
+                                                    while( liFlushLength.QuadPart > 0)
+                                                    {
+
+                                                        if( liFlushLength.QuadPart > 512 * 1024000)
+                                                        {
+                                                            ulFlushLength = 512 * 1024000;
+                                                        }
+                                                        else
+                                                        {
+                                                            ulFlushLength = liFlushLength.LowPart;
+                                                        }
+
+                                                        if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                                  &liCurrentOffset,
+                                                                                  ulFlushLength,
+                                                                                  FALSE))
+                                                        {
+
+                                                            AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                          AFS_TRACE_LEVEL_WARNING,
+                                                                          "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                          ObjectInfo->FileId.Cell,
+                                                                          ObjectInfo->FileId.Volume,
+                                                                          ObjectInfo->FileId.Vnode,
+                                                                          ObjectInfo->FileId.Unique));
+
+                                                            bPurgeOnClose = TRUE;
+                                                        }
+                                                        else
+                                                        {
+
+                                                            bCleanExtents = TRUE;
+                                                        }
+
+                                                        liFlushLength.QuadPart -= ulFlushLength;
+                                                    }
+                                                }
+
+                                                liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+
+                                                ulProcessCount++;
+                                                le = le->Flink;
+                                            }
                                         }
                                         else
                                         {
-                                            ulFlushLength = liFlushLength.LowPart;
+                                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                      NULL,
+                                                                      0,
+                                                                      FALSE))
+                                            {
+
+                                                AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                              AFS_TRACE_LEVEL_WARNING,
+                                                              "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                              ObjectInfo->FileId.Cell,
+                                                              ObjectInfo->FileId.Volume,
+                                                              ObjectInfo->FileId.Vnode,
+                                                              ObjectInfo->FileId.Unique));
+
+                                                bPurgeOnClose = TRUE;
+                                            }
+                                            else
+                                            {
+
+                                                bCleanExtents = TRUE;
+                                            }
                                         }
 
-                                        if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                  &liCurrentOffset,
-                                                                  ulFlushLength,
-                                                                  FALSE))
+                                        if ( bPurgeOnClose)
                                         {
+
                                             SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                                         }
-
-                                        liFlushLength.QuadPart -= ulFlushLength;
                                     }
                                 }
+                                __except( EXCEPTION_EXECUTE_HANDLER)
+                                {
+
+                                    ntStatus = GetExceptionCode();
+
+                                    AFSDbgTrace(( 0,
+                                                  0,
+                                                  "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                                  ObjectInfo->FileId.Cell,
+                                                  ObjectInfo->FileId.Volume,
+                                                  ObjectInfo->FileId.Vnode,
+                                                  ObjectInfo->FileId.Unique,
+                                                  ntStatus));
+                                }
 
-                                liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+                                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+                                              &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+                                              PsGetCurrentThread()));
 
-                                ulProcessCount++;
-                                le = le->Flink;
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
                             }
                         }
-                        else
+
+                        if ( bExtentsLocked)
                         {
-                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                      NULL,
-                                                      0,
-                                                      FALSE))
-                            {
-                                SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
-                            }
+
+                            AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
                         }
                     }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
+
+                    if ( bLocked)
                     {
 
-                        ntStatus = GetExceptionCode();
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
                     }
 
-                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
-                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+                    if ( bCleanExtents)
+                    {
 
-                    AFSReleaseCleanExtents( ObjectInfo->Fcb,
-                                            NULL);
+                        AFSReleaseCleanExtents( ObjectInfo->Fcb,
+                                                NULL);
+                    }
                 }
 
                 break;
             }
+        }
 
-            default:
-            {
+        //
+        // Destroy the reference passed in by the caller to AFSInvalidateObject
+        // or AFSQueueInvalidateObject
+        //
 
-                break;
-            }
-        }
+        lCount = AFSObjectInfoDecrement( ObjectInfo,
+                                         AFS_OBJECT_REFERENCE_INVALIDATION);
 
-        if( ObjectInfo != NULL)
-        {
-            InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
-        }
+        AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
+                      ObjectInfo,
+                      lCount));
     }
 
     return ntStatus;