Windows: AFSValidateEntry Symlink TargetName
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index 797f3f2..3a0fde8 100644 (file)
@@ -51,7 +51,8 @@
 //
 
 ULONG
-AFSExceptionFilter( IN ULONG Code,
+AFSExceptionFilter( IN CHAR *FunctionString,
+                    IN ULONG Code,
                     IN PEXCEPTION_POINTERS ExceptPtrs)
 {
 
@@ -67,9 +68,10 @@ AFSExceptionFilter( IN ULONG Code,
 
         AFSDbgLogMsg( 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);
@@ -403,9 +405,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;
@@ -424,10 +428,10 @@ AFSLockUserBuffer( IN void *UserBuffer,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     void *pAddress = NULL;
-       MDL *pMdl = NULL;
+    MDL *pMdl = NULL;
 
-       __Enter
-       {
+    __Enter
+    {
 
         pMdl = IoAllocateMdl( UserBuffer,
                               BufferLength,
@@ -435,11 +439,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 +453,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:
 
@@ -643,6 +649,7 @@ AFSInitializeGlobalDirectoryEntries()
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfoCB = NULL;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -665,13 +672,13 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
                       pObjectInfoCB,
-                      pObjectInfoCB->ObjectReferenceCount);
+                      lCount);
 
         ntStatus = STATUS_SUCCESS;
 
@@ -772,13 +779,13 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
                       pObjectInfoCB,
-                      pObjectInfoCB->ObjectReferenceCount);
+                      lCount);
 
         ntStatus = STATUS_SUCCESS;
 
@@ -912,6 +919,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
     BOOLEAN bAllocatedObjectCB = FALSE;
     ULONGLONG ullIndex = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -968,13 +976,13 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                           FileName);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = AFSObjectInfoIncrement( pObjectInfoCB);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
                       pObjectInfoCB,
-                      pObjectInfoCB->ObjectReferenceCount);
+                      lCount);
 
         AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
 
@@ -1022,10 +1030,10 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         pDirNode->ObjectInformation = pObjectInfoCB;
 
         //
-        // Set valid entry
+        // Set valid entry and NOT_IN_PARENT flag
         //
 
-        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
 
         pDirNode->FileIndex = FileIndex;
 
@@ -1115,25 +1123,20 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
             pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
 
-            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
-                pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
-                pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
+            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
             {
 
-                pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+                pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
             }
 
-            pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
-
-            //
-            // Object specific information
-            //
-
-            pObjectInfoCB->Links = DirEnumEntry->Links;
+            if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
+                pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
+            {
 
-            pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
+                pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
 
-            pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
+            pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
 
             //
             // Check for the case where we have a filetype of SymLink but both the TargetFid and the
@@ -1161,6 +1164,16 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
             }
         }
 
+        //
+        // Object specific information
+        //
+
+        pObjectInfoCB->Links = DirEnumEntry->Links;
+
+        pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
+
+        pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
+
 try_exit:
 
         if( !NT_SUCCESS( ntStatus))
@@ -1171,13 +1184,13 @@ try_exit:
 
                 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
 
-                AFSExFreePool( pNonPagedDirEntry);
+                AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
             }
 
             if( pDirNode != NULL)
             {
 
-                AFSExFreePool( pDirNode);
+                AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
 
                 pDirNode = NULL;
             }
@@ -1189,13 +1202,13 @@ try_exit:
             if( pObjectInfoCB != NULL)
             {
 
-                InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
+                lCount = AFSObjectInfoDecrement( pObjectInfoCB);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
                               pObjectInfoCB,
-                              pObjectInfoCB->ObjectReferenceCount);
+                              lCount);
 
                 if( bAllocatedObjectCB)
                 {
@@ -1331,12 +1344,17 @@ AFSEvaluateNode( IN GUID *AuthGroup,
 
         DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
-            pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        {
+
+            DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+        }
+
+        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
             pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
         }
 
         DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
@@ -1395,7 +1413,7 @@ try_exit:
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -1511,12 +1529,17 @@ AFSValidateSymLink( IN GUID *AuthGroup,
 
         DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
 
-        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
-            pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+        if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        {
+
+            DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+        }
+
+        if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
             pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
         }
 
         DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
@@ -1528,10 +1551,357 @@ try_exit:
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
+        }
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
+                     IN     ULONG Reason)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    IO_STATUS_BLOCK stIoStatus;
+    ULONG ulFilter = 0;
+
+    AFSDbgLogMsg( 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,
+                  (*ppObjectInfo)->FileId.Cell,
+                  (*ppObjectInfo)->FileId.Volume,
+                  (*ppObjectInfo)->FileId.Vnode,
+                  (*ppObjectInfo)->FileId.Unique,
+                  Reason);
+
+    if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
+        (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
+        (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+    {
+        //
+        // We only act on the mount point itself, not the target. If the
+        // node has been deleted then mark it as such otherwise indicate
+        // it requires verification
+        //
+
+        if( Reason == AFS_INVALIDATE_DELETED)
+        {
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
+        }
+        else
+        {
+
+            if( Reason == AFS_INVALIDATE_FLUSHED)
+            {
+
+                (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+            }
+
+            (*ppObjectInfo)->Expiration.QuadPart = 0;
+
+            (*ppObjectInfo)->TargetFileId.Vnode = 0;
+
+            (*ppObjectInfo)->TargetFileId.Unique = 0;
+
+            AFSDbgLogMsg( 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);
+
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
+        }
+
+        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,
+                                        ulFilter,
+                                        FILE_ACTION_MODIFIED);
+
+        try_return( ntStatus);
+    }
+
+    //
+    // Depending on the reason for invalidation then perform work on the node
+    //
+
+    switch( Reason)
+    {
+
+    case AFS_INVALIDATE_DELETED:
+        {
+
+            //
+            // Mark this node as invalid
+            //
+
+            (*ppObjectInfo)->Links = 0;
+
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
+
+            AFSDbgLogMsg( 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);
+
+            if( (*ppObjectInfo)->ParentObjectInformation != NULL)
+            {
+
+                AFSDbgLogMsg( 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);
+
+                SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+                (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
+            }
+
+            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);
+
+            if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
+                                                      Reason)))
+            {
+                (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
+            }
+
+            break;
+        }
+
+    case AFS_INVALIDATE_FLUSHED:
+        {
+
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
+                (*ppObjectInfo)->Fcb != NULL)
+            {
+
+                AFSDbgLogMsg( 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);
+
+                AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
+                                TRUE);
+
+                __try
+                {
+
+                    CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
+                                  NULL,
+                                  0,
+                                  &stIoStatus);
+
+                    if( !NT_SUCCESS( stIoStatus.Status))
+                    {
+
+                        AFSDbgLogMsg( 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,
+                                      (*ppObjectInfo)->FileId.Volume,
+                                      (*ppObjectInfo)->FileId.Vnode,
+                                      (*ppObjectInfo)->FileId.Unique,
+                                      stIoStatus.Status,
+                                      stIoStatus.Information);
+
+                        ntStatus = stIoStatus.Status;
+                    }
+
+
+                    if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                    {
+
+                        if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                          AFS_TRACE_LEVEL_WARNING,
+                                          "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                          (*ppObjectInfo)->FileId.Cell,
+                                          (*ppObjectInfo)->FileId.Volume,
+                                          (*ppObjectInfo)->FileId.Vnode,
+                                          (*ppObjectInfo)->FileId.Unique);
+
+                            SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
+                    }
+                }
+                __except( EXCEPTION_EXECUTE_HANDLER)
+                {
+
+                    ntStatus = GetExceptionCode();
+
+                    AFSDbgLogMsg( 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);
+
+                //
+                // Clear out the extents
+                // Get rid of them (note this involves waiting
+                // for any writes or reads to the cache to complete)
+                //
+
+                AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
+                                       NULL);
+            }
+
+            (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
+
+
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
+            {
+
+                AFSDbgLogMsg( 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);
+
+                SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+            }
+
+            // Fall through to the default processing
+        }
+
+    default:
+        {
+
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
+            {
+                ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
+            }
+            else
+            {
+                ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
+            }
+
+            if( Reason == AFS_INVALIDATE_CREDS)
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
+            }
+
+            if( Reason == AFS_INVALIDATE_DATA_VERSION)
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
+            }
+            else
+            {
+                ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+            }
+
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
+            {
+
+                AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
+                                                NULL,
+                                                ulFilter,
+                                                FILE_ACTION_MODIFIED);
+            }
+            else
+            {
+
+                AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
+                                                NULL,
+                                                ulFilter,
+                                                FILE_ACTION_MODIFIED);
+            }
+
+            //
+            // Indicate this node requires re-evaluation for the remaining reasons
+            //
+
+            (*ppObjectInfo)->Expiration.QuadPart = 0;
+
+            AFSDbgLogMsg( 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);
+
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+            if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+                (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
+                ( Reason == AFS_INVALIDATE_CALLBACK ||
+                  Reason == AFS_INVALIDATE_EXPIRED))
+            {
+                if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
+                                                           AFS_INVALIDATE_DATA_VERSION)))
+                {
+
+                    (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
+                }
+            }
+
+            break;
         }
     }
 
+  try_exit:
+
     return ntStatus;
 }
 
@@ -1548,12 +1918,22 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
     BOOLEAN     bIsChild = FALSE;
     ULONGLONG   ullIndex = 0;
     AFSObjectInfoCB *pObjectInfo = NULL;
-    IO_STATUS_BLOCK stIoStatus;
-    ULONG ulFilter = 0;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSDbgLogMsg( 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,
+                      InvalidateCB->FileID.Volume,
+                      InvalidateCB->FileID.Vnode,
+                      InvalidateCB->FileID.Unique,
+                      InvalidateCB->FileType,
+                      InvalidateCB->WholeVolume,
+                      InvalidateCB->Reason);
+
         //
         // Need to locate the Fcb for the directory to purge
         //
@@ -1583,13 +1963,13 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         if( pVolumeCB != NULL)
         {
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
                           pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
+                          lCount);
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -1597,6 +1977,16 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         if( !NT_SUCCESS( ntStatus) ||
             pVolumeCB == NULL)
         {
+
+            AFSDbgLogMsg( 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);
+
             try_return( ntStatus = STATUS_SUCCESS);
         }
 
@@ -1604,23 +1994,13 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         // If this is a whole volume invalidation then go do it now
         //
 
-        if( InvalidateCB->WholeVolume ||
-            AFSIsVolumeFID( &InvalidateCB->FileID))
+        if( InvalidateCB->WholeVolume)
         {
 
             ntStatus = AFSInvalidateVolume( pVolumeCB,
                                             InvalidateCB->Reason);
 
-            AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
-                                            NULL,
-                                            FILE_NOTIFY_CHANGE_FILE_NAME |
-                                                FILE_NOTIFY_CHANGE_DIR_NAME |
-                                                FILE_NOTIFY_CHANGE_NAME |
-                                                FILE_NOTIFY_CHANGE_ATTRIBUTES |
-                                                FILE_NOTIFY_CHANGE_SIZE,
-                                            FILE_ACTION_MODIFIED);
-
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
             try_return( ntStatus);
         }
@@ -1628,19 +2008,28 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        if ( AFSIsVolumeFID( &InvalidateCB->FileID))
+        {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
-                      pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+            pObjectInfo = &pVolumeCB->ObjectInformation;
+        }
+        else
+        {
 
-        ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
-        ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
-                                       ullIndex,
-                                       (AFSBTreeEntry **)&pObjectInfo);
+            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);
+        }
 
         if( pObjectInfo != NULL)
         {
@@ -1649,13 +2038,13 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             // Reference the node so it won't be torn down
             //
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
 
         AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -1663,292 +2052,34 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         if( !NT_SUCCESS( ntStatus) ||
             pObjectInfo == NULL)
         {
-            try_return( ntStatus = STATUS_SUCCESS);
-        }
-
-        if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
-        {
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
-                          pObjectInfo->FileType,
-                          pObjectInfo->FileId.Cell,
-                          pObjectInfo->FileId.Volume,
-                          pObjectInfo->FileId.Vnode,
-                          pObjectInfo->FileId.Unique,
-                          InvalidateCB->Reason);
-
-            //
-            // We only act on the mount point itself, not the target. If the
-            // node has been deleted then mark it as such otherwise indicate
-            // it requires verification
-            //
-
-            if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
-            {
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
-            }
-            else
-            {
-
-                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
-                    InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
-                {
-                    pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
-                }
-
-                pObjectInfo->Expiration.QuadPart = 0;
-
-                pObjectInfo->TargetFileId.Vnode = 0;
-
-                pObjectInfo->TargetFileId.Unique = 0;
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                              pObjectInfo->FileId.Cell,
-                              pObjectInfo->FileId.Volume,
-                              pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
-
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
-            }
-
-            ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-
-            if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
-            {
-                ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-            }
-
-            if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
-            {
-                ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
-            }
-            else
-            {
-                ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-            }
-
-            AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                            NULL,
-                                            FILE_NOTIFY_CHANGE_FILE_NAME |
-                                            FILE_NOTIFY_CHANGE_ATTRIBUTES,
-                                            FILE_ACTION_MODIFIED);
+                          "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);
 
-            try_return( ntStatus);
+            try_return( ntStatus = STATUS_SUCCESS);
         }
 
-        //
-        // Depending on the reason for invalidation then perform work on the node
-        //
-
-        switch( InvalidateCB->Reason)
-        {
-
-            case AFS_INVALIDATE_DELETED:
-            {
-
-                //
-                // Mark this node as invalid
-                //
-
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                              pObjectInfo->FileId.Cell,
-                              pObjectInfo->FileId.Volume,
-                              pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
-
-                if( pObjectInfo->ParentObjectInformation != NULL)
-                {
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
-                                  pObjectInfo->ParentObjectInformation->FileId.Cell,
-                                  pObjectInfo->ParentObjectInformation->FileId.Volume,
-                                  pObjectInfo->ParentObjectInformation->FileId.Vnode,
-                                  pObjectInfo->ParentObjectInformation->FileId.Unique);
-
-                    SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
-                    pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
-                    pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
-                }
-
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                }
-                else
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                }
-
-                AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                NULL,
-                                                ulFilter,
-                                                FILE_ACTION_REMOVED);
-
-                break;
-            }
-
-            case AFS_INVALIDATE_FLUSHED:
-            {
-
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
-                    pObjectInfo->Fcb != NULL)
-                {
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
-                                  pObjectInfo->FileId.Cell,
-                                  pObjectInfo->FileId.Volume,
-                                  pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique);
-
-                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
-                                    TRUE);
-
-                    __try
-                    {
-
-                        CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                      NULL,
-                                      0,
-                                      &stIoStatus);
-
-                        if( !NT_SUCCESS( stIoStatus.Status))
-                        {
-
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                          AFS_TRACE_LEVEL_ERROR,
-                                          "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
-                                          pObjectInfo->FileId.Cell,
-                                          pObjectInfo->FileId.Volume,
-                                          pObjectInfo->FileId.Vnode,
-                                          pObjectInfo->FileId.Unique,
-                                          stIoStatus.Status,
-                                          stIoStatus.Information);
-
-                            ntStatus = stIoStatus.Status;
-                        }
-
-                        CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                             NULL,
-                                             0,
-                                             FALSE);
-                    }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
-                    {
-
-                        ntStatus = GetExceptionCode();
-                    }
-
-                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
-
-                    //
-                    // Clear out the extents
-                    // Get rid of them (note this involves waiting
-                    // for any writes or reads to the cache to complete)
-                    //
-
-                    (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
-                }
-
-                // Fall through to the default processing
-            }
-
-            default:
-            {
-
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                }
-                else
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                }
-
-                if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                }
-
-                if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
-                }
-                else
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-                }
-
-                AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                NULL,
-                                                ulFilter,
-                                                FILE_ACTION_MODIFIED);
-
-                //
-                // Indicate this node requires re-evaluation for the remaining reasons
-                //
-
-                pObjectInfo->Expiration.QuadPart = 0;
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                              pObjectInfo->FileId.Cell,
-                              pObjectInfo->FileId.Volume,
-                              pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
-
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
-
-                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
-                    InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
-                {
-                    pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
-
-                    if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
-                    {
-
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                                      pObjectInfo->FileId.Cell,
-                                      pObjectInfo->FileId.Volume,
-                                      pObjectInfo->FileId.Vnode,
-                                      pObjectInfo->FileId.Unique);
-
-                        SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                    }
-                }
-
-                break;
-            }
-        }
+        AFSInvalidateObject( &pObjectInfo,
+                             InvalidateCB->Reason);
 
 try_exit:
 
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
     }
 
@@ -2318,7 +2449,7 @@ AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
 
         if( FreePathName)
         {
-            AFSExFreePool( FullPathName->Buffer);
+            AFSExFreePoolWithTag( FullPathName->Buffer, 0);
         }
 
         *FullPathName = uniPathName;
@@ -2337,8 +2468,10 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSFcb *pFcb = NULL;
     AFSObjectInfoCB *pCurrentObject = NULL;
+    AFSObjectInfoCB *pNextObject = NULL;
+    LONG lCount;
+    AFSFcb *pFcb = NULL;
     ULONG ulFilter = 0;
 
     __Enter
@@ -2367,204 +2500,181 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                 // Mark this volume as invalid
                 //
 
-                VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
-
                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
 
                 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
 
-                AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
-                                                NULL,
-                                                FILE_NOTIFY_CHANGE_DIR_NAME,
-                                                FILE_ACTION_REMOVED);
+                break;
+            }
+        }
 
-                AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
-                                  TRUE);
+        //
+        // Invalidate the volume root directory
+        //
 
-                pCurrentObject = VolumeCB->ObjectInfoListHead;
+        pCurrentObject = &VolumeCB->ObjectInformation;
 
-                while( pCurrentObject != NULL)
-                {
+        if ( pCurrentObject )
+        {
 
-                    if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                    }
-                    else
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                    }
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
 
-                    AFSFsRtlNotifyFullReportChange( pCurrentObject,
-                                                    NULL,
-                                                    ulFilter,
-                                                    FILE_ACTION_REMOVED);
+            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                          pCurrentObject,
+                          lCount);
 
-                    SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
+            AFSInvalidateObject( &pCurrentObject,
+                                 Reason);
 
-                    pFcb = pCurrentObject->Fcb;
+            if ( pCurrentObject)
+            {
 
-                    if( pFcb != NULL &&
-                        pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
-                    {
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                              pCurrentObject,
+                              lCount);
+            }
+        }
 
-                        //
-                        // Clear out the extents
-                        // And get rid of them (note this involves waiting
-                        // for any writes or reads to the cache to complete)
-                        //
+        //
+        // Apply invalidation to all other volume objects
+        //
 
-                        (VOID) AFSTearDownFcbExtents( pFcb);
-                    }
+        AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+                          TRUE);
 
-                    pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
-                }
+        pCurrentObject = VolumeCB->ObjectInfoListHead;
 
-                AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+        if ( pCurrentObject)
+        {
 
-                break;
-            }
+            //
+            // Reference the node so it won't be torn down
+            //
 
-            default:
+            lCount = AFSObjectInfoIncrement( pCurrentObject);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                          pCurrentObject,
+                          lCount);
+        }
+
+        while( pCurrentObject != NULL)
+        {
+
+            pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
+
+            if ( pNextObject)
             {
 
                 //
-                // Indicate this node requires re-evaluation for the remaining reasons
+                // Reference the node so it won't be torn down
                 //
 
-                VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
+                lCount = AFSObjectInfoIncrement( pNextObject);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                              VolumeCB->ObjectInformation.FileId.Cell,
-                              VolumeCB->ObjectInformation.FileId.Volume,
-                              VolumeCB->ObjectInformation.FileId.Vnode,
-                              VolumeCB->ObjectInformation.FileId.Unique);
-
-                SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
-
-                if( Reason == AFS_INVALIDATE_FLUSHED ||
-                    Reason == AFS_INVALIDATE_DATA_VERSION)
-                {
+                              "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                              pNextObject,
+                              lCount);
+            }
 
-                    VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
-                }
+            AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
 
-                //
-                // Notify anyone that cares
-                //
+            AFSInvalidateObject( &pCurrentObject,
+                                 Reason);
 
-                ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
+            if ( pCurrentObject )
+            {
 
-                if( Reason == AFS_INVALIDATE_CREDS)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                }
+                lCount = AFSObjectInfoDecrement( pCurrentObject);
 
-                if( Reason == AFS_INVALIDATE_DATA_VERSION)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
-                }
-                else
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-                }
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                              pCurrentObject,
+                              lCount);
+            }
 
-                AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
-                                                NULL,
-                                                ulFilter,
-                                                FILE_ACTION_MODIFIED);
+            AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+                              TRUE);
 
-                //
-                // Volume invalidations require all objects in the volume be re-verified
-                //
+            pCurrentObject = pNextObject;
+        }
 
-                AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
-                                  TRUE);
+        AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+    }
 
-                pCurrentObject = VolumeCB->ObjectInfoListHead;
+    return ntStatus;
+}
 
-                while( pCurrentObject != NULL)
-                {
+VOID
+AFSInvalidateAllVolumes( VOID)
+{
+    AFSVolumeCB *pVolumeCB = NULL;
+    AFSVolumeCB *pNextVolumeCB = NULL;
+    AFSDeviceExt *pRDRDeviceExt = NULL;
+    LONG lCount;
 
-                    pCurrentObject->Expiration.QuadPart = 0;
+    pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
-                    pCurrentObject->TargetFileId.Vnode = 0;
+    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                  AFS_TRACE_LEVEL_VERBOSE,
+                  "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
+                  &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+                  PsGetCurrentThread());
 
-                    pCurrentObject->TargetFileId.Unique = 0;
+    AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+                      TRUE);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                                  pCurrentObject->FileId.Cell,
-                                  pCurrentObject->FileId.Volume,
-                                  pCurrentObject->FileId.Vnode,
-                                  pCurrentObject->FileId.Unique);
+    pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
 
-                    SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
+    if ( pVolumeCB)
+    {
 
-                    if( Reason == AFS_INVALIDATE_FLUSHED ||
-                        Reason == AFS_INVALIDATE_DATA_VERSION)
-                    {
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
+                      pVolumeCB->ObjectInfoTree.TreeLock,
+                      PsGetCurrentThread());
 
-                        pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+    }
 
-                        if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
-                        {
+    while( pVolumeCB != NULL)
+    {
 
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                          AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                                          pCurrentObject->FileId.Cell,
-                                          pCurrentObject->FileId.Volume,
-                                          pCurrentObject->FileId.Vnode,
-                                          pCurrentObject->FileId.Unique);
+        pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
 
-                            SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                        }
-                    }
+        if ( pNextVolumeCB)
+        {
 
-                    if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                    }
-                    else
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                    }
+            lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
+        }
 
-                    if( Reason == AFS_INVALIDATE_CREDS)
-                    {
-                        ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                    }
+        AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
 
-                    if( Reason == AFS_INVALIDATE_DATA_VERSION)
-                    {
-                        ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
-                    }
-                    else
-                    {
-                        ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
-                    }
+        // do I need to hold the volume lock here?
 
-                    AFSFsRtlNotifyFullReportChange( pCurrentObject,
-                                                    NULL,
-                                                    ulFilter,
-                                                    FILE_ACTION_MODIFIED);
+        AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
 
-                    pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
-                }
+        AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
+                          TRUE);
 
-                AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
-                break;
-            }
-        }
+        pVolumeCB = pNextVolumeCB;
     }
 
-    return ntStatus;
+    AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
 }
 
 NTSTATUS
@@ -2599,7 +2709,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
 
             AFSDbgLogMsg( 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,
@@ -2614,27 +2724,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);
+                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);
 
-            //
-            // 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);
+            }
         }
 
         //
@@ -2676,8 +2788,6 @@ AFSVerifyEntry( IN GUID *AuthGroup,
             case AFS_FILE_TYPE_SYMLINK:
             {
 
-                ASSERT( pDirEnumEntry->TargetNameLength > 0);
-
                 //
                 // Update the metadata for the entry
                 //
@@ -2699,43 +2809,39 @@ 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,
                                   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))
                 {
 
+                    bPurgeExtents = TRUE;
+
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
+                                  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)
@@ -2778,35 +2884,52 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                             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))
+                            {
+
+                                AFSDbgLogMsg( 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",
+                        AFSDbgLogMsg( 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);
+
+                        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                     }
 
                     AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
 
                     if ( bPurgeExtents)
                     {
-                        AFSFlushExtents( pObjectInfo->Fcb);
+                        AFSFlushExtents( pObjectInfo->Fcb,
+                                         AuthGroup);
                     }
 
                     //
@@ -2823,6 +2946,29 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                                     TRUE);
 
                     //
+                    // Update the metadata for the entry
+                    //
+
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
+
+                    if( !NT_SUCCESS( ntStatus))
+                    {
+
+                        AFSDbgLogMsg( 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
                     //
 
@@ -2842,9 +2988,33 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                 }
                 else
                 {
+
+                    //
+                    // Update the metadata for the entry
+                    //
+
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
+
+                    if( !NT_SUCCESS( ntStatus))
+                    {
+
+                        AFSDbgLogMsg( 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;
+                    }
+
                     AFSDbgLogMsg( 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,
@@ -2883,10 +3053,16 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                     AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                     TRUE);
 
-                    AFSValidateDirectoryCache( pObjectInfo,
-                                               AuthGroup);
+                    ntStatus = AFSValidateDirectoryCache( pObjectInfo,
+                                                          AuthGroup);
 
                     AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+                    if ( !NT_SUCCESS( ntStatus))
+                    {
+
+                        try_return( ntStatus);
+                    }
                 }
 
                 //
@@ -2969,8 +3145,13 @@ AFSVerifyEntry( IN GUID *AuthGroup,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSVerifyEntry Attempt to verify node of type %d\n",
-                              pObjectInfo->FileType);
+                              "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                              pObjectInfo->FileType,
+                              &DirEntry->NameInformation.FileName,
+                              pObjectInfo->FileId.Cell,
+                              pObjectInfo->FileId.Volume,
+                              pObjectInfo->FileId.Vnode,
+                              pObjectInfo->FileId.Unique);
 
                 break;
         }
@@ -2980,7 +3161,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
         if( pDirEnumEntry != NULL)
         {
 
-            AFSExFreePool( pDirEnumEntry);
+            AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -2997,6 +3178,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
     AFSVolumeCB *pVolumeCB = NULL;
     AFSFcb *pFcb = NULL;
     AFSObjectInfoCB *pCurrentObject = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -3033,7 +3215,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
         if( pVolumeCB != NULL)
         {
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
@@ -3120,7 +3302,8 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
                     // for any writes or reads to the cache to complete)
                     //
 
-                    (VOID) AFSTearDownFcbExtents( pFcb);
+                    AFSTearDownFcbExtents( pFcb,
+                                           NULL);
                 }
 
                 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
@@ -3128,7 +3311,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
 
             AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
         }
         else
         {
@@ -3189,6 +3372,7 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     BOOLEAN  bAcquiredLock = FALSE;
     AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
     AFSFcb *pFcb = NULL;
@@ -3246,21 +3430,75 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
         while( pCurrentDirEntry != NULL)
         {
 
+            pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+
             if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
             {
 
-                ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+                //
+                // If this entry has been deleted then process it here
+                //
+
+                if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
+                    pCurrentDirEntry->OpenReferenceCount == 0)
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
+                                  pCurrentDirEntry,
+                                  &pCurrentDirEntry->NameInformation.FileName);
+
+                    AFSDeleteDirEntry( ObjectInfo,
+                                       pCurrentDirEntry);
+                }
+                else
+                {
+
+                    ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
+                                  pCurrentDirEntry,
+                                  pCurrentDirEntry->OpenReferenceCount);
+
+                    //
+                    // We pull the short name from the parent tree since it could change below
+                    //
+
+                    if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
+                    {
+
+                        AFSDbgLogMsg( 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);
+
+                        AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
+                                                    pCurrentDirEntry);
+
+                        ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+                    }
+                }
             }
 
-            pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+            pCurrentDirEntry = pNextDirEntry;
         }
 
         //
         // Reget the directory contents
         //
 
-        AFSVerifyDirectoryContent( ObjectInfo,
-                                   AuthGroup);
+        ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
+                                              AuthGroup);
+
+        if ( !NT_SUCCESS( ntStatus))
+        {
+            try_return( ntStatus);
+        }
 
         //
         // Now start again and tear down any entries not valid
@@ -3276,11 +3514,61 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
             if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
             {
 
+                if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
+                    !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
+                    pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
+                {
+
+                    if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
+                    {
+
+                        ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
+                                      pCurrentDirEntry,
+                                      &pCurrentDirEntry->NameInformation.FileName);
+
+                        SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+                    }
+                    else
+                    {
+
+                        if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
+                                                                     pCurrentDirEntry)))
+                        {
+                            AFSDbgLogMsg( 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);
+                        }
+                        else
+                        {
+                            SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
+                                          pCurrentDirEntry,
+                                          &pCurrentDirEntry->NameInformation.FileName);
+                        }
+                    }
+                }
+
                 pCurrentDirEntry = pNextDirEntry;
 
                 continue;
             }
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
+                          pCurrentDirEntry,
+                          pCurrentDirEntry->OpenReferenceCount);
+
             if( pCurrentDirEntry->OpenReferenceCount == 0)
             {
 
@@ -3326,6 +3614,8 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
         }
 #endif
 
+try_exit:
+
         if( bAcquiredLock)
         {
 
@@ -3411,19 +3701,26 @@ AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
 
         pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
 
-        if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
+        if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+        {
+
+            pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+        }
+
+        if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
             pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
         {
 
-            pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            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))
         {
 
             //
@@ -3465,7 +3762,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,
@@ -3474,7 +3772,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);
@@ -3497,8 +3795,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;
@@ -3518,12 +3816,13 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
         AFSDbgLogMsg( 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
@@ -3535,28 +3834,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:
         //
@@ -3598,7 +3875,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                          "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                          FastCall,
                           &DirEntry->NameInformation.FileName,
                           pObjectInfo->FileId.Cell,
                           pObjectInfo->FileId.Volume,
@@ -3615,7 +3893,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
+                      "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
+                      FastCall,
                       &DirEntry->NameInformation.FileName,
                       pObjectInfo->FileId.Cell,
                       pObjectInfo->FileId.Volume,
@@ -3675,160 +3954,228 @@ 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;
+                    pCurrentFcb = pObjectInfo->Fcb;
 
-                    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);
+                    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;
+                    }
 
-                    if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
+                    if( pCurrentFcb != NULL)
                     {
-                        bPurgeExtents = TRUE;
+
+                        IO_STATUS_BLOCK stIoStatus;
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                      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);
 
-                        ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                    }
-
-                    __try
-                    {
-
-                        CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
-                                      NULL,
-                                      0,
-                                      &stIoStatus);
-
-                        if( !NT_SUCCESS( stIoStatus.Status))
+                        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",
+                            AFSDbgLogMsg( 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;
+
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                              AFS_TRACE_LEVEL_VERBOSE,
+                                              "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                              &DirEntry->NameInformation.FileName,
+                                              pObjectInfo->FileId.Cell,
+                                              pObjectInfo->FileId.Volume,
+                                              pObjectInfo->FileId.Vnode,
+                                              pObjectInfo->FileId.Unique);
+
+                                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                            }
+
+                            __try
+                            {
+
+                                CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
+                                              NULL,
+                                              0,
+                                              &stIoStatus);
+
+                                if( !NT_SUCCESS( stIoStatus.Status))
+                                {
+
+                                    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",
+                                                  &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))
+                                    {
+
+                                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                      AFS_TRACE_LEVEL_WARNING,
+                                                      "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                                                      &DirEntry->NameInformation.FileName,
+                                                      pObjectInfo->FileId.Cell,
+                                                      pObjectInfo->FileId.Volume,
+                                                      pObjectInfo->FileId.Vnode,
+                                                      pObjectInfo->FileId.Unique);
+
+                                        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    }
+                                }
+                            }
+                            __except( EXCEPTION_EXECUTE_HANDLER)
+                            {
+                                ntStatus = GetExceptionCode();
+
+                                AFSDbgLogMsg( 0,
+                                              0,
+                                              "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                              &DirEntry->NameInformation.FileName,
+                                              pObjectInfo->FileId.Cell,
+                                              pObjectInfo->FileId.Volume,
+                                              pObjectInfo->FileId.Vnode,
+                                              pObjectInfo->FileId.Unique,
+                                              ntStatus);
+
+                                SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                            }
                         }
-                    }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
-                    {
-                        ntStatus = GetExceptionCode();
-
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                      AFS_TRACE_LEVEL_ERROR,
-                                      "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %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);
+                        else
+                        {
 
-                    }
+                            if ( bPurgeExtents)
+                            {
 
-                    AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
+                                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                            }
+                        }
 
-                    if ( bPurgeExtents)
-                    {
-                        AFSFlushExtents( pCurrentFcb);
-                    }
 
-                    //
-                    // Reacquire the Fcb to purge the cache
-                    //
+                        AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
-                                  &pCurrentFcb->NPFcb->Resource,
-                                  PsGetCurrentThread());
+                        bReleaseFcb = FALSE;
 
-                    AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
-                                    TRUE);
+                        if ( bPurgeExtents &&
+                             bSafeToPurge)
+                        {
+                            AFSFlushExtents( pCurrentFcb,
+                                             AuthGroup);
+                        }
+                    }
                 }
 
                 //
-                // Update the metadata for the entry
+                // Update the metadata for the entry but only if it is safe to do so.
+                // If it was determined that a data version change has occurred or
+                // that a pending data verification was required, do not update the
+                // ObjectInfo meta data or the FileObject size information.  That
+                // way it is consistent for the next time that the data is verified
+                // or validated.
                 //
 
-                ntStatus = AFSUpdateMetaData( DirEntry,
-                                              pDirEnumEntry);
-
-                if( !NT_SUCCESS( ntStatus))
+                if ( !(bPurgeExtents && bSafeToPurge))
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
-                                  &DirEntry->NameInformation.FileName,
-                                  pObjectInfo->FileId.Cell,
-                                  pObjectInfo->FileId.Volume,
-                                  pObjectInfo->FileId.Vnode,
-                                  pObjectInfo->FileId.Unique,
-                                  ntStatus);
+                    ntStatus = AFSUpdateMetaData( DirEntry,
+                                                  pDirEnumEntry);
 
-                    break;
-                }
+                    if( !NT_SUCCESS( ntStatus))
+                    {
 
-                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                      &DirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      ntStatus);
 
-                //
-                // Update file sizes
-                //
+                        break;
+                    }
 
-                if( pObjectInfo->Fcb != NULL)
-                {
-                    FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
+                    ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
 
-                    pObjectInfo->Fcb->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
-                    pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
-                    pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
+                    //
+                    // Update file sizes
+                    //
 
-                    if ( pCCFileObject != NULL)
+                    if( pObjectInfo->Fcb != NULL)
                     {
-                        CcSetFileSizes( pCCFileObject,
-                                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
+
+                        pObjectInfo->Fcb->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
+                        pObjectInfo->Fcb->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
+                        pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
+
+                        if ( pCCFileObject != NULL)
+                        {
+                            CcSetFileSizes( pCCFileObject,
+                                            (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+                        }
                     }
                 }
-
                 break;
             }
 
@@ -3837,8 +4184,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
                 AFSDirectoryCB *pCurrentDirEntry = NULL;
 
-                if( pCurrentFcb != NULL &&
-                    pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
+                if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
                 {
 
                     //
@@ -3867,8 +4213,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                         AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                         TRUE);
 
-                        AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
-                                                   AuthGroup);
+                        ntStatus = AFSValidateDirectoryCache( pObjectInfo,
+                                                              AuthGroup);
 
                         AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
                     }
@@ -3910,8 +4256,14 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_WARNING,
-                              "AFSValidateEntry Attempt to verify node of type %d\n",
-                              pObjectInfo->FileType);
+                              "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                              pObjectInfo->FileType,
+                              FastCall,
+                              &DirEntry->NameInformation.FileName,
+                              pObjectInfo->FileId.Cell,
+                              pObjectInfo->FileId.Volume,
+                              pObjectInfo->FileId.Vnode,
+                              pObjectInfo->FileId.Unique);
 
                 break;
         }
@@ -3927,7 +4279,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
         if( pDirEnumEntry != NULL)
         {
 
-            AFSExFreePool( pDirEnumEntry);
+            AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
     }
 
@@ -3949,7 +4301,7 @@ AFSInitializeSpecialShareNameList()
     {
 
         RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\srvsvc");
+                              L"PIPE");
 
         pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
                                                0);
@@ -4014,7 +4366,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;
 
@@ -4033,92 +4385,6 @@ AFSInitializeSpecialShareNameList()
 
         pLastDirNode = pDirNode;
 
-        RtlInitUnicodeString( &uniShareName,
-                              L"PIPE\\wkssvc");
-
-        pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
-                                               0);
-
-        if( pObjectInfoCB == NULL)
-        {
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
-                      pObjectInfoCB);
-
-        pObjectInfoCB->ObjectReferenceCount = 1;
-
-        pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
-
-        ulEntryLength = sizeof( AFSDirectoryCB) +
-                                     uniShareName.Length;
-
-        pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
-                                                                  ulEntryLength,
-                                                                  AFS_DIR_ENTRY_TAG);
-
-        if( pDirNode == NULL)
-        {
-
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
-                                                                                   sizeof( AFSNonPagedDirectoryCB),
-                                                                                   AFS_DIR_ENTRY_NP_TAG);
-
-        if( pNonPagedDirEntry == NULL)
-        {
-
-            ExFreePool( pDirNode);
-
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
-            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-        }
-
-        RtlZeroMemory( pDirNode,
-                       ulEntryLength);
-
-        RtlZeroMemory( pNonPagedDirEntry,
-                       sizeof( AFSNonPagedDirectoryCB));
-
-        ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
-
-        pDirNode->NonPaged = pNonPagedDirEntry;
-
-        pDirNode->ObjectInformation = pObjectInfoCB;
-
-        //
-        // Set valid entry
-        //
-
-        SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
-
-        pDirNode->NameInformation.FileName.Length = uniShareName.Length;
-
-        pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
-
-        pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
-
-        RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
-                       uniShareName.Buffer,
-                       pDirNode->NameInformation.FileName.Length);
-
-        pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
-                                                                       TRUE);
-
-        pLastDirNode->ListEntry.fLink = pDirNode;
-
-        pDirNode->ListEntry.bLink = pLastDirNode;
-
-        pLastDirNode = pDirNode;
 
         RtlInitUnicodeString( &uniShareName,
                               L"IPC$");
@@ -4251,38 +4517,14 @@ AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
     __Enter
     {
 
-        //
-        // Build up the entire name here. We are guaranteed that if there is a
-        // secondary name, it is pointing to a portion of the share name buffer
-        //
-
-        if( SecondaryName->Length > 0 &&
-            SecondaryName->Buffer != NULL)
-        {
-
-            uniFullShareName = *SecondaryName;
-
-            //
-            // The calling routine strips off the leading slash so add it back in
-            //
-
-            uniFullShareName.Buffer--;
-            uniFullShareName.Length += sizeof( WCHAR);
-            uniFullShareName.MaximumLength += sizeof( WCHAR);
-
-            //
-            // And the share name
-            //
 
-            uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
-            uniFullShareName.Length += ShareName->Length;
-            uniFullShareName.MaximumLength += ShareName->Length;
-        }
-        else
-        {
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE_2,
+                      "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
+                      ShareName,
+                      SecondaryName);
 
-            uniFullShareName = *ShareName;
-        }
+        uniFullShareName = *ShareName;
 
         //
         // Generate our hash value
@@ -4356,7 +4598,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)
@@ -4555,7 +4798,7 @@ AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
             pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
         }
 
-        AFSExFreePool( uniFullName.Buffer);
+        AFSExFreePoolWithTag( uniFullName.Buffer, 0);
 
 try_exit:
 
@@ -4571,7 +4814,8 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
 
     BOOLEAN bIsRelative = FALSE;
 
-    if( Name->Buffer[ 0] != L'\\')
+    if( Name->Length > 0 &&
+        Name->Buffer[ 0] != L'\\')
     {
 
         bIsRelative = TRUE;
@@ -4580,6 +4824,53 @@ AFSIsRelativeName( IN UNICODE_STRING *Name)
     return bIsRelative;
 }
 
+BOOLEAN
+AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
+{
+    UNICODE_STRING uniTempName;
+    BOOLEAN        bIsAbsolute = FALSE;
+
+    //
+    // An absolute AFS path must begin with \afs\... or equivalent
+    //
+
+    if ( Name->Length == 0 ||
+         Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
+         Name->Buffer[ 0] != L'\\' ||
+         Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
+    {
+
+        return FALSE;
+    }
+
+    uniTempName.Length = AFSMountRootName.Length;
+    uniTempName.MaximumLength = AFSMountRootName.Length;
+
+    uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+                                                            uniTempName.MaximumLength,
+                                                            AFS_NAME_BUFFER_TWO_TAG);
+
+    if( uniTempName.Buffer == NULL)
+    {
+
+        return FALSE;
+    }
+
+    RtlCopyMemory( uniTempName.Buffer,
+                   Name->Buffer,
+                   AFSMountRootName.Length);
+
+    bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
+                                                 &AFSMountRootName,
+                                                 TRUE));
+
+    AFSExFreePoolWithTag( uniTempName.Buffer,
+                          AFS_NAME_BUFFER_TWO_TAG);
+
+    return bIsAbsolute;
+}
+
+
 void
 AFSUpdateName( IN UNICODE_STRING *Name)
 {
@@ -4635,7 +4926,7 @@ AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
             if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
             {
 
-                AFSExFreePool( TargetName->Buffer);
+                AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
             }
 
             TargetName->MaximumLength = NameLength;
@@ -4671,7 +4962,9 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
 {
 
     AFSNameArrayHdr *pNameArray = NULL;
+    AFSNameArrayCB *pCurrentElement = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount;
 
     __Enter
     {
@@ -4690,7 +4983,7 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
         if( pNameArray == NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSInitNameArray Failed to allocate name array\n");
 
@@ -4706,24 +4999,46 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
         if( DirectoryCB != NULL)
         {
 
-            pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
+            pCurrentElement = &pNameArray->ElementArray[ 0];
+
+            pNameArray->CurrentEntry = pCurrentElement;
+
+            pNameArray->Count = 1;
 
-            InterlockedIncrement( &pNameArray->Count);
+            pNameArray->LinkCount = 0;
 
-            InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
+            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,
-                          DirectoryCB->OpenReferenceCount);
+                          lCount);
 
-            pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
+            pCurrentElement->DirectoryCB = DirectoryCB;
 
-            pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
+            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
 
-            pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
+            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
+
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          pNameArray,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType);
         }
 
 try_exit:
@@ -4747,10 +5062,24 @@ AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
     ULONG  ulTotalCount = 0;
     ULONG ulIndex = 0;
     USHORT usLength = 0;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      &Path,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType);
+
         //
         // Init some info in the header
         //
@@ -4765,23 +5094,43 @@ AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
 
         pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
 
-        InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+        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,
-                      pCurrentElement->DirectoryCB->OpenReferenceCount);
+                      lCount);
 
         pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
 
         pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
 
+        pCurrentElement->Flags = 0;
+
+        if( pCurrentElement->FileId.Vnode == 1)
+        {
+
+            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        }
+
         NameArray->Count = 1;
 
         NameArray->LinkCount = 0;
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      pCurrentElement->DirectoryCB,
+                      pCurrentElement->FileId.Cell,
+                      pCurrentElement->FileId.Volume,
+                      pCurrentElement->FileId.Vnode,
+                      pCurrentElement->FileId.Unique,
+                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                      pCurrentElement->DirectoryCB->ObjectInformation->FileType);
+
         //
         // If the root is the parent then we are done ...
         //
@@ -4812,10 +5161,24 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
     ULONG  ulTotalCount = 0;
     ULONG ulIndex = 0;
     USHORT usLength = 0;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      RelatedNameArray,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType);
+
         //
         // Init some info in the header
         //
@@ -4841,16 +5204,37 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
 
             pCurrentElement->FileId    = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
 
-            InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            pCurrentElement->Flags = 0;
+
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
+
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
+
+            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,
-                          pCurrentElement->DirectoryCB->OpenReferenceCount);
+                          lCount);
 
-            InterlockedIncrement( &NameArray->Count);
+            lCount = InterlockedIncrement( &NameArray->Count);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          lCount - 1,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType);
 
             if( pCurrentElement->DirectoryCB == DirectoryCB ||
                 NameArray->Count == RelatedNameArray->Count)
@@ -4868,10 +5252,7 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
             pCurrentRelatedElement++;
         }
 
-        if( NameArray->Count > 0)
-        {
-            NameArray->CurrentEntry = pCurrentElement;
-        }
+        NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
     }
 
     return ntStatus;
@@ -4883,34 +5264,32 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount, lElement;
 
     __Enter
     {
 
-        pCurrentElement = &NameArray->ElementArray[ 0];
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFreeNameArray [NA:%p]\n",
+                      NameArray);
 
-        while( TRUE)
+        for ( lElement = 0; lElement < NameArray->Count; lElement++)
         {
 
-            if( pCurrentElement->DirectoryCB == NULL)
-            {
-
-                break;
-            }
+            pCurrentElement = &NameArray->ElementArray[ lElement];
 
-            InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            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,
-                          pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-            pCurrentElement++;
+                          lCount);
         }
 
-        AFSExFreePool( NameArray);
+        AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
     }
 
     return ntStatus;
@@ -4918,26 +5297,55 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
 
 NTSTATUS
 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
-                      IN AFSDirectoryCB *DirEntry)
+                      IN AFSDirectoryCB *DirectoryCB)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType);
+
         if( NameArray->Count == NameArray->MaxElementCount)
         {
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
+                          NameArray);
+
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        if( NameArray->CurrentEntry != NULL &&
-            NameArray->CurrentEntry->DirectoryCB == DirEntry)
+        for ( lCount = 0; lCount < NameArray->Count; lCount++)
         {
 
-            try_return( ntStatus);
+            if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
+                                &DirectoryCB->ObjectInformation->FileId) )
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                              AFS_TRACE_LEVEL_WARNING,
+                              "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
+                              NameArray,
+                              DirectoryCB,
+                              STATUS_ACCESS_DENIED);
+
+                try_return( ntStatus = STATUS_ACCESS_DENIED);
+            }
         }
 
         if( NameArray->Count > 0)
@@ -4950,112 +5358,152 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
             NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
         }
 
-        InterlockedIncrement( &NameArray->Count);
+        pCurrentElement = NameArray->CurrentEntry;
 
-        InterlockedIncrement( &DirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &NameArray->Count);
+
+        lCount = InterlockedIncrement( &DirectoryCB->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,
-                      DirEntry->OpenReferenceCount);
-
-        NameArray->CurrentEntry->DirectoryCB = DirEntry;
-
-        NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
-
-        NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
-
-try_exit:
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB,
+                      lCount);
 
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-void
-AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
-                          IN AFSDirectoryCB *DirectoryCB)
-{
+        pCurrentElement->DirectoryCB = DirectoryCB;
 
-    ASSERT( NameArray->CurrentEntry != NULL);
+        pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
 
-    InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+        pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
 
-    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,
-                  NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
-
-    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,
-                  DirectoryCB->OpenReferenceCount);
+        pCurrentElement->Flags = 0;
 
-    NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
+        if( pCurrentElement->FileId.Vnode == 1)
+        {
 
-    NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
+            SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        }
 
-    NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      NameArray->Count - 1,
+                      pCurrentElement->DirectoryCB,
+                      pCurrentElement->FileId.Cell,
+                      pCurrentElement->FileId.Volume,
+                      pCurrentElement->FileId.Vnode,
+                      pCurrentElement->FileId.Unique,
+                      &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                      pCurrentElement->DirectoryCB->ObjectInformation->FileType);
 
-    if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
-    {
+try_exit:
 
-        SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+        NOTHING;
     }
 
-    return;
+    return ntStatus;
 }
 
 AFSDirectoryCB *
 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
 {
 
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
+    AFSDirectoryCB *pDirectoryCB = NULL;
+    AFSNameArrayCB *pCurrentElement = NULL;
+    BOOLEAN         bVolumeRoot = FALSE;
+    LONG lCount;
 
     __Enter
     {
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSBackupEntry [NA:%p]\n",
+                      NameArray);
+
         if( NameArray->Count == 0)
         {
-            try_return( pCurrentDirEntry);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSBackupEntry [NA:%p] No more entries\n",
+                          NameArray);
+
+            try_return( pCurrentElement);
         }
 
-        InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+        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,
-                      NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+                      lCount);
 
         NameArray->CurrentEntry->DirectoryCB = NULL;
 
-        if( InterlockedDecrement( &NameArray->Count) == 0)
+        lCount = InterlockedDecrement( &NameArray->Count);
+
+        if( lCount == 0)
         {
             NameArray->CurrentEntry = NULL;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSBackupEntry [NA:%p] No more entries\n",
+                          NameArray);
         }
         else
         {
+
+            bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+
             NameArray->CurrentEntry--;
-            pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
+
+            pCurrentElement = NameArray->CurrentEntry;
+
+            pDirectoryCB = pCurrentElement->DirectoryCB;
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          NameArray->Count - 1,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType);
+
+            //
+            // If the entry we are removing is a volume root,
+            // we must remove the mount point entry as well.
+            // If the NameArray was constructed by checking the
+            // share name via the service, the name array can
+            // contain two volume roots in sequence without a
+            // mount point separating them.
+            //
+
+            if ( bVolumeRoot &&
+                 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
+            {
+
+                pDirectoryCB = AFSBackupEntry( NameArray);
+            }
         }
 
+
 try_exit:
 
         NOTHING;
     }
 
-    return pCurrentDirEntry;
+    return pDirectoryCB;
 }
 
 AFSDirectoryCB *
@@ -5068,10 +5516,20 @@ AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
     __Enter
     {
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSGetParentEntry [NA:%p]\n",
+                      NameArray);
+
         if( NameArray->Count == 0 ||
             NameArray->Count == 1)
         {
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSGetParentEntry [NA:%p] No more entries\n",
+                          NameArray);
+
             try_return( pDirEntry = NULL);
         }
 
@@ -5079,6 +5537,19 @@ AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
 
         pDirEntry = pElement->DirectoryCB;
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      NameArray->Count - 2,
+                      pElement->DirectoryCB,
+                      pElement->FileId.Cell,
+                      pElement->FileId.Volume,
+                      pElement->FileId.Vnode,
+                      pElement->FileId.Unique,
+                      &pElement->DirectoryCB->NameInformation.FileName,
+                      pElement->DirectoryCB->ObjectInformation->FileType);
+
 try_exit:
 
         NOTHING;
@@ -5089,36 +5560,44 @@ try_exit:
 
 void
 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
-                   IN AFSDirectoryCB *DirEntry)
+                   IN AFSDirectoryCB *DirectoryCB)
 {
 
     AFSNameArrayCB *pCurrentElement = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount, lElement;
 
     __Enter
     {
 
-        pCurrentElement = &NameArray->ElementArray[ 0];
+        AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                      NameArray,
+                      DirectoryCB,
+                      DirectoryCB->ObjectInformation->FileId.Cell,
+                      DirectoryCB->ObjectInformation->FileId.Volume,
+                      DirectoryCB->ObjectInformation->FileId.Vnode,
+                      DirectoryCB->ObjectInformation->FileId.Unique,
+                      &DirectoryCB->NameInformation.FileName,
+                      DirectoryCB->ObjectInformation->FileType);
+        //
+        // Dereference previous name array contents
+        //
 
-        while( TRUE)
+        for ( lElement = 0; lElement < NameArray->Count; lElement++)
         {
 
-            if( pCurrentElement->DirectoryCB == NULL)
-            {
-
-                break;
-            }
+            pCurrentElement = &NameArray->ElementArray[ lElement];
 
-            InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            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,
-                          pCurrentElement->DirectoryCB->OpenReferenceCount);
-
-            pCurrentElement++;
+                          lCount);
         }
 
         RtlZeroMemory( NameArray,
@@ -5127,27 +5606,51 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
 
         NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
 
-        if( DirEntry != NULL)
+        if( DirectoryCB != NULL)
         {
 
-            NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
+            pCurrentElement = &NameArray->ElementArray[ 0];
+
+            NameArray->CurrentEntry = pCurrentElement;
+
+            NameArray->Count = 1;
 
-            InterlockedIncrement( &NameArray->Count);
+            NameArray->LinkCount = 0;
 
-            InterlockedIncrement( &DirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
-                          &DirEntry->NameInformation.FileName,
-                          DirEntry,
-                          DirEntry->OpenReferenceCount);
+                          &DirectoryCB->NameInformation.FileName,
+                          DirectoryCB,
+                          lCount);
+
+            pCurrentElement->DirectoryCB = DirectoryCB;
+
+            pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+            pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+            pCurrentElement->Flags  = 0;
 
-            NameArray->CurrentEntry->DirectoryCB = DirEntry;
+            if( pCurrentElement->FileId.Vnode == 1)
+            {
 
-            NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
+                SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+            }
 
-            NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
+            AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+                          NameArray,
+                          pCurrentElement->DirectoryCB,
+                          pCurrentElement->FileId.Cell,
+                          pCurrentElement->FileId.Volume,
+                          pCurrentElement->FileId.Vnode,
+                          pCurrentElement->FileId.Unique,
+                          &pCurrentElement->DirectoryCB->NameInformation.FileName,
+                          pCurrentElement->DirectoryCB->ObjectInformation->FileType);
         }
     }
 
@@ -5185,6 +5688,7 @@ AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
 void
 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
 {
+    LONG lCount;
 
     //
     // Depending on the type of node, set the event
@@ -5194,26 +5698,11 @@ AFSSetEnumerationEvent( IN AFSFcb *Fcb)
     {
 
         case AFS_DIRECTORY_FCB:
-        {
-
-            KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                        0,
-                        FALSE);
-
-            InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
-
-            break;
-        }
-
         case AFS_ROOT_FCB:
         case AFS_ROOT_ALL:
         {
 
-            KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                        0,
-                        FALSE);
-
-            InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
+            lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
             break;
         }
@@ -5226,6 +5715,8 @@ void
 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
 {
 
+    LONG lCount;
+
     //
     // Depending on the type of node, set the event
     //
@@ -5234,30 +5725,13 @@ AFSClearEnumerationEvent( IN AFSFcb *Fcb)
     {
 
         case AFS_DIRECTORY_FCB:
-        {
-
-            ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
-
-            if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
-            {
-
-                KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
-            }
-
-            break;
-        }
-
         case AFS_ROOT_FCB:
         case AFS_ROOT_ALL:
         {
 
             ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
 
-            if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
-            {
-
-                KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
-            }
+            lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
             break;
         }
@@ -5281,30 +5755,15 @@ AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
             try_return( bIsInProcess);
         }
 
-        //
-        // Depending on the type of node, set the event
-        //
-
         switch( ObjectInfo->Fcb->Header.NodeTypeCode)
         {
 
             case AFS_DIRECTORY_FCB:
-            {
-
-                if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
-                {
-
-                    bIsInProcess = TRUE;
-                }
-
-                break;
-            }
-
             case AFS_ROOT_FCB:
             case AFS_ROOT_ALL:
             {
 
-                if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
+                if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
                 {
 
                     bIsInProcess = TRUE;
@@ -5342,6 +5801,7 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
     AFSDirectoryCB *pDirNode = NULL;
     ULONG ulEntryLength = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5423,17 +5883,47 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
         pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
                                                                        TRUE);
 
-        ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
+        if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
+        {
+
+            AFSDbgLogMsg( 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 = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
+                          pDirNode->ObjectInformation,
+                          lCount);
+
+            try_return( ntStatus = STATUS_REPARSE);
+        }
 
 try_exit:
 
-        if ( !NT_SUCCESS( ntStatus))
+        if ( ntStatus != STATUS_SUCCESS)
         {
 
             if ( pDirNode != NULL)
             {
 
-                AFSExFreePool( pDirNode);
+                AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
+            }
+
+            if( pNonPagedDirEntry != NULL)
+            {
+
+                ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
+
+                AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
             }
 
             if ( pObjectInfoCB != NULL)
@@ -5452,6 +5942,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                            IN AFSDirectoryCB *DirectoryCB,
                            IN UNICODE_STRING *ParentPathName,
                            IN AFSNameArrayHdr *RelatedNameArray,
+                           IN GUID           *AuthGroup,
                            OUT AFSFileInfoCB *FileInfo)
 {
 
@@ -5464,7 +5955,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
-    GUID *pAuthGroup = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5481,17 +5972,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
             AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
 
-            if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
-            {
-                pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
-            }
-            else if( DirectoryCB->ObjectInformation->Fcb != NULL)
-            {
-                pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-            }
-
             ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
-                                              pAuthGroup,
+                                              AuthGroup,
                                               FALSE,
                                               &pDirEntry);
 
@@ -5502,7 +5984,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                 if( pDirEntry != NULL)
                 {
 
-                    ntStatus = STATUS_ACCESS_DENIED;
+                    ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
                 }
 
                 try_return( ntStatus);
@@ -5637,9 +6119,6 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
             pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
-
             pParentDirEntry = ParentDirectoryCB;
         }
         else
@@ -5717,9 +6196,6 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
             pVolumeCB = AFSGlobalRoot;
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
-
             pParentDirEntry = AFSGlobalRoot->DirectoryCB;
         }
 
@@ -5727,15 +6203,15 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Increment the ref count on the volume and dir entry for correct processing below
         //
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
                       pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+                      lCount);
 
-        InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -5743,7 +6219,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      pParentDirEntry->OpenReferenceCount);
+                      lCount);
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -5770,21 +6246,19 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                 if( pVolumeCB != NULL)
                 {
 
-                    InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
                                   pVolumeCB,
-                                  pVolumeCB->VolumeReferenceCount);
-
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
+                                  lCount);
                 }
 
                 if( pDirectoryEntry != NULL)
                 {
 
-                    InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -5792,12 +6266,12 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   &pDirectoryEntry->NameInformation.FileName,
                                   pDirectoryEntry,
                                   NULL,
-                                  pDirectoryEntry->OpenReferenceCount);
+                                  lCount);
                 }
                 else
                 {
 
-                    InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -5805,7 +6279,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   &pParentDirEntry->NameInformation.FileName,
                                   pParentDirEntry,
                                   NULL,
-                                  pParentDirEntry->OpenReferenceCount);
+                                  lCount);
                 }
             }
 
@@ -5827,13 +6301,22 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
         {
 
-            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)
         {
 
-            FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+            {
+
+                FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+            }
+            else
+            {
+
+                FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+            }
         }
 
         FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
@@ -5852,7 +6335,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Remove the reference made above
         //
 
-        InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -5860,28 +6343,26 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       &pDirectoryEntry->NameInformation.FileName,
                       pDirectoryEntry,
                       NULL,
-                      pDirectoryEntry->OpenReferenceCount);
+                      lCount);
 
 try_exit:
 
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
 
         if( pVolumeCB != NULL)
         {
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
                           pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
-
-            AFSReleaseResource( pVolumeCB->VolumeLock);
+                          lCount);
         }
 
         if( pNameArray != NULL)
@@ -5905,10 +6386,10 @@ try_exit:
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
-                AFSExFreePool( uniFullPathName.Buffer);
+                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
             }
 
-            AFSExFreePool( pwchBuffer);
+            AFSExFreePoolWithTag( pwchBuffer, 0);
         }
     }
 
@@ -5922,6 +6403,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSObjectInfoCB *pObjectInfo = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5946,13 +6428,15 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
         if( pObjectInfo->NonPagedInfo == NULL)
         {
 
-            AFSExFreePool( pObjectInfo);
+            AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
 
             try_return( pObjectInfo = NULL);
         }
 
         ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
+        ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
         pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
 
         pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
@@ -5961,7 +6445,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         if( ParentObjectInfo != NULL)
         {
-            InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( ParentObjectInfo);
         }
 
         //
@@ -6027,11 +6511,80 @@ try_exit:
     return pObjectInfo;
 }
 
+LONG
+AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    if ( ObjectInfo->ObjectReferenceCount == 0)
+    {
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+    }
+    else
+    {
+
+        AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                          TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        if ( lCount == 1)
+        {
+
+            AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+            AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                            TRUE);
+        }
+    }
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+LONG
+AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
+{
+
+    LONG lCount;
+
+    AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                      TRUE);
+
+    lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+
+    if ( lCount == 0)
+    {
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+    }
+
+    AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+    return lCount;
+}
+
+
+
 void
 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 {
 
     BOOLEAN bAcquiredTreeLock = FALSE;
+    LONG lCount;
 
     if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
     {
@@ -6095,7 +6648,8 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 
     if( ObjectInfo->ParentObjectInformation != NULL)
     {
-        InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
+
+        lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
     }
 
     if( bAcquiredTreeLock)
@@ -6114,11 +6668,13 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
         AFSReleaseFid( &ObjectInfo->FileId);
     }
 
+    ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
     ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
 
-    AFSExFreePool( ObjectInfo->NonPagedInfo);
+    AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
 
-    AFSExFreePool( ObjectInfo);
+    AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG);
 
     return;
 }
@@ -6137,11 +6693,22 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
-    GUID *pAuthGroup = NULL;
+    GUID    stAuthGroup;
+    LONG lCount;
 
     __Enter
     {
 
+        ntStatus = AFSRetrieveValidAuthGroup( NULL,
+                                              DirectoryCB->ObjectInformation,
+                                              FALSE,
+                                              &stAuthGroup);
+
+        if( !NT_SUCCESS( ntStatus))
+        {
+            try_return( ntStatus);
+        }
+
         //
         // Retrieve a target name for the entry
         //
@@ -6154,13 +6721,8 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
             AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
 
-            if( DirectoryCB->ObjectInformation->Fcb != NULL)
-            {
-                pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
-            }
-
             ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
-                                              pAuthGroup,
+                                              &stAuthGroup,
                                               FALSE,
                                               &pDirEntry);
 
@@ -6171,7 +6733,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                 if( pDirEntry != NULL)
                 {
 
-                    ntStatus = STATUS_ACCESS_DENIED;
+                    ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
                 }
 
                 try_return( ntStatus);
@@ -6284,20 +6846,17 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         pVolumeCB = AFSGlobalRoot;
 
-        AFSAcquireShared( pVolumeCB->VolumeLock,
-                          TRUE);
-
         pParentDirEntry = AFSGlobalRoot->DirectoryCB;
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
                       pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+                      lCount);
 
-        InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -6305,7 +6864,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      pParentDirEntry->OpenReferenceCount);
+                      lCount);
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -6332,21 +6891,19 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                 if( pVolumeCB != NULL)
                 {
 
-                    InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
                                   pVolumeCB,
-                                  pVolumeCB->VolumeReferenceCount);
-
-                    AFSReleaseResource( pVolumeCB->VolumeLock);
+                                  lCount);
                 }
 
                 if( pDirectoryEntry != NULL)
                 {
 
-                    InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -6354,12 +6911,12 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                   &pDirectoryEntry->NameInformation.FileName,
                                   pDirectoryEntry,
                                   NULL,
-                                  pDirectoryEntry->OpenReferenceCount);
+                                  lCount);
                 }
                 else
                 {
 
-                    InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                    lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
@@ -6367,7 +6924,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                   &pParentDirEntry->NameInformation.FileName,
                                   pParentDirEntry,
                                   NULL,
-                                  pParentDirEntry->OpenReferenceCount);
+                                  lCount);
                 }
             }
 
@@ -6387,21 +6944,19 @@ try_exit:
         if( pDirEntry != NULL)
         {
 
-            AFSExFreePool( pDirEntry);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
         }
 
         if( pVolumeCB != NULL)
         {
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
                           pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
-
-            AFSReleaseResource( pVolumeCB->VolumeLock);
+                          lCount);
         }
 
         if( pNameArray != NULL)
@@ -6425,10 +6980,10 @@ try_exit:
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
-                AFSExFreePool( uniFullPathName.Buffer);
+                AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
             }
 
-            AFSExFreePool( pwchBuffer);
+            AFSExFreePoolWithTag( pwchBuffer, 0);
         }
     }
 
@@ -6489,14 +7044,42 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                             ntStatus = stIoStatus.Status;
                         }
 
-                        CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                             NULL,
-                                             0,
-                                             FALSE);
+                        if (  Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                        {
+
+                            if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                       NULL,
+                                                       0,
+                                                       FALSE))
+                            {
+
+                                AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                              AFS_TRACE_LEVEL_WARNING,
+                                              "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                              Fcb->ObjectInformation->FileId.Cell,
+                                              Fcb->ObjectInformation->FileId.Volume,
+                                              Fcb->ObjectInformation->FileId.Vnode,
+                                              Fcb->ObjectInformation->FileId.Unique);
+
+                                SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                            }
+                        }
                     }
                     __except( EXCEPTION_EXECUTE_HANDLER)
                     {
+
                         ntStatus = GetExceptionCode();
+
+                        AFSDbgLogMsg( 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);
                     }
                 }
 
@@ -6512,10 +7095,13 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 // Now perform another flush on the file
                 //
 
-                if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
+                if( !NT_SUCCESS( AFSFlushExtents( Fcb,
+                                                  NULL)))
                 {
 
-                    AFSReleaseExtentsWithFlush( Fcb);
+                    AFSReleaseExtentsWithFlush( Fcb,
+                                                NULL,
+                                                TRUE);
                 }
             }
 
@@ -6524,7 +7110,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
             {
 
-                AFSTearDownFcbExtents( Fcb);
+                AFSTearDownFcbExtents( Fcb,
+                                       NULL);
             }
 
             try_return( ntStatus);
@@ -6536,32 +7123,33 @@ 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))
         {
-
-            if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
+            if( !NT_SUCCESS( AFSFlushExtents( Fcb,
+                                              NULL)) &&
                 Fcb->OpenReferenceCount == 0)
             {
 
-                AFSReleaseExtentsWithFlush( Fcb);
+                AFSReleaseExtentsWithFlush( Fcb,
+                                            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);
-        }
 
         //
         // If there are extents and they haven't been used recently *and*
@@ -6572,59 +7160,90 @@ 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
+            if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush))
             {
 
-                CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
-                              NULL,
-                              0,
-                              &stIoStatus);
+                __try
+                {
+
+                    CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
+                                  NULL,
+                                  0,
+                                  &stIoStatus);
+
+                    if( !NT_SUCCESS( stIoStatus.Status))
+                    {
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
+                                      Fcb->ObjectInformation->FileId.Cell,
+                                      Fcb->ObjectInformation->FileId.Volume,
+                                      Fcb->ObjectInformation->FileId.Vnode,
+                                      Fcb->ObjectInformation->FileId.Unique,
+                                      stIoStatus.Status,
+                                      stIoStatus.Information);
+
+                        ntStatus = stIoStatus.Status;
+                    }
+
+                    if( ForceFlush &&
+                        Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
+                    {
+
+                        if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                          AFS_TRACE_LEVEL_WARNING,
+                                          "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                          Fcb->ObjectInformation->FileId.Cell,
+                                          Fcb->ObjectInformation->FileId.Volume,
+                                          Fcb->ObjectInformation->FileId.Vnode,
+                                          Fcb->ObjectInformation->FileId.Unique);
 
-                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();
+
+                    AFSDbgLogMsg( 0,
+                                  0,
+                                  "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
                                   Fcb->ObjectInformation->FileId.Cell,
                                   Fcb->ObjectInformation->FileId.Volume,
                                   Fcb->ObjectInformation->FileId.Vnode,
                                   Fcb->ObjectInformation->FileId.Unique,
-                                  stIoStatus.Status,
-                                  stIoStatus.Information);
-
-                    ntStatus = stIoStatus.Status;
+                                  ntStatus);
                 }
 
-                if( ForceFlush)
+                AFSReleaseResource( &Fcb->NPFcb->Resource);
+
+                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);
+                ntStatus = STATUS_RETRY;
             }
         }
 
@@ -6653,7 +7272,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);
 
@@ -6945,8 +7564,7 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
                                           DirEntry);
 
-        if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
-            DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
+        if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
         {
 
             //
@@ -6961,6 +7579,8 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
             AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
                                         DirEntry);
+
+            ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
         }
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -6971,6 +7591,8 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
         SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
 
+        ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
 try_exit:
 
         NOTHING;
@@ -7060,7 +7682,7 @@ try_exit:
         if( pTokenInfo != NULL)
         {
 
-            AFSExFreePool( pTokenInfo);
+            ExFreePool( pTokenInfo);    // Allocated by SeQueryInformationToken
         }
     }
 
@@ -7106,7 +7728,7 @@ AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
 
     BOOLEAN bIsValid = TRUE;
     ULONG ulCount = 0;
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
+    AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
 
     pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
 
@@ -7116,6 +7738,21 @@ AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
         if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
         {
             ulCount++;
+
+            if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
+            {
+
+                pDirEntry = NULL;
+
+                AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+                                                (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
+                                                &pDirEntry);
+
+                if( pDirEntry == NULL)
+                {
+                    DbgBreakPoint();
+                }
+            }
         }
 
         pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
@@ -7176,6 +7813,7 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pControlDevExt = NULL;
     ULONG ulTimeIncrement = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -7186,6 +7824,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSServerName = LibraryInit->AFSServerName;
 
+        AFSMountRootName = LibraryInit->AFSMountRootName;
+
         AFSDebugFlags = LibraryInit->AFSDebugFlags;
 
         //
@@ -7200,7 +7840,7 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
 
-        AFSExFreePool = LibraryInit->AFSExFreePool;
+        AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
 
         AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
 
@@ -7227,10 +7867,9 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
         ulTimeIncrement = KeQueryTimeIncrement();
 
         pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
-        pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
-        pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
+        pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
         pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
-        pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
+        pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
         pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
 
         //
@@ -7263,6 +7902,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
                           "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
                           ntStatus);
 
+            lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
+
             AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
             try_return( ntStatus);
@@ -7277,11 +7918,20 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
         SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
 
         //
+        // Invalidate all known volumes since contact with the service and therefore
+        // the file server was lost.
+        //
+
+        AFSInvalidateAllVolumes();
+
+        //
         // Drop the locks acquired above
         //
 
         AFSInitVolumeWorker( AFSGlobalRoot);
 
+        lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
+
         AFSReleaseResource( AFSGlobalRoot->VolumeLock);
 
         AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
@@ -7408,6 +8058,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
     UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
     AFSNameArrayHdr *pNameArray = NULL;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -7438,13 +8089,13 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             if( pVolumeCB != NULL)
             {
 
-                InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
                               pVolumeCB,
-                              pVolumeCB->VolumeReferenceCount);
+                              lCount);
             }
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -7460,9 +8111,9 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 pObjectInfo = &pVolumeCB->ObjectInformation;
 
-                InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo);
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
             }
             else
             {
@@ -7470,13 +8121,13 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                                   TRUE);
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
                               pVolumeCB,
-                              pVolumeCB->VolumeReferenceCount);
+                              lCount);
 
                 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
 
@@ -7491,13 +8142,13 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     // Reference the node so it won't be torn down
                     //
 
-                    InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
                                   pObjectInfo,
-                                  pObjectInfo->ObjectReferenceCount);
+                                  lCount);
                 }
 
                 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -7561,24 +8212,21 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
             pVolumeCB = AFSGlobalRoot;
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
-
             pParentDirEntry = AFSGlobalRoot->DirectoryCB;
 
             //
             // Increment the ref count on the volume and dir entry for correct processing below
             //
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
                           pVolumeCB,
-                          pVolumeCB->VolumeReferenceCount);
+                          lCount);
 
-            InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -7586,7 +8234,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                           &pParentDirEntry->NameInformation.FileName,
                           pParentDirEntry,
                           NULL,
-                          pParentDirEntry->OpenReferenceCount);
+                          lCount);
 
             ntStatus = AFSLocateNameEntry( NULL,
                                            NULL,
@@ -7614,21 +8262,19 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     if( pVolumeCB != NULL)
                     {
 
-                        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
                                       "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
                                       pVolumeCB,
-                                      pVolumeCB->VolumeReferenceCount);
-
-                        AFSReleaseResource( pVolumeCB->VolumeLock);
+                                      lCount);
                     }
 
                     if( pDirectoryEntry != NULL)
                     {
 
-                        InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -7636,12 +8282,12 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       &pDirectoryEntry->NameInformation.FileName,
                                       pDirectoryEntry,
                                       NULL,
-                                      pDirectoryEntry->OpenReferenceCount);
+                                      lCount);
                     }
                     else
                     {
 
-                        InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
+                        lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
@@ -7649,7 +8295,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       &pParentDirEntry->NameInformation.FileName,
                                       pParentDirEntry,
                                       NULL,
-                                      pParentDirEntry->OpenReferenceCount);
+                                      lCount);
                     }
                 }
 
@@ -7662,24 +8308,22 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             // Remove the reference made above
             //
 
-            InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
             pObjectInfo = pDirectoryEntry->ObjectInformation;
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             if( pVolumeCB != NULL)
             {
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
                               pVolumeCB,
                               pVolumeCB->VolumeReferenceCount);
-
-                AFSReleaseResource( pVolumeCB->VolumeLock);
             }
         }
 
@@ -7728,7 +8372,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
         }
 
         if( pNameArray != NULL)
@@ -7747,8 +8391,10 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSDirectoryCB *pDirEntry = NULL;
     ULONG ulCRC = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -7799,7 +8445,8 @@ 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))
                 {
@@ -7818,7 +8465,7 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         if( pDirEntry != NULL)
         {
-            InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
         }
 
         AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -7841,12 +8488,12 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE_2,
-                      "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
+                      "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
                       ComponentName);
 
-        ntStatus = STATUS_ACCESS_DENIED;
+        ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
-        InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
 
 try_exit:
 
@@ -7938,10 +8585,35 @@ AFSCreateDefaultSecurityDescriptor()
     SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
     ULONG ulSDLength = 0;
     SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
+    PSID pWorldSID = NULL;
+    ULONG *pulSubAuthority = NULL;
+    ULONG ulWorldSIDLEngth = 0;
 
     __Enter
     {
 
+        ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
+
+        pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
+                                                 ulWorldSIDLEngth,
+                                                 AFS_GENERIC_MEMORY_29_TAG);
+
+        if( pWorldSID == NULL)
+        {
+            AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
+            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+        }
+
+        RtlZeroMemory( pWorldSID,
+                       ulWorldSIDLEngth);
+
+        RtlInitializeSid( pWorldSID,
+                          &SeWorldSidAuthority,
+                          1);
+
+        pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
+        *pulSubAuthority = SECURITY_WORLD_RID;
+
         if( AFSRtlSetSaclSecurityDescriptor == NULL)
         {
 
@@ -8061,6 +8733,39 @@ AFSCreateDefaultSecurityDescriptor()
             }
         }
 
+        //
+        // Add in the group and owner to the SD
+        //
+
+        if( AFSRtlSetGroupSecurityDescriptor != NULL)
+        {
+            ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
+                                                         pWorldSID,
+                                                         FALSE);
+
+            if( !NT_SUCCESS( ntStatus))
+            {
+
+                AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
+                          ntStatus);
+
+                try_return( ntStatus);
+            }
+        }
+
+        ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
+                                                  pWorldSID,
+                                                  FALSE);
+
+        if( !NT_SUCCESS( ntStatus))
+        {
+
+            AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
+                      ntStatus);
+
+            try_return( ntStatus);
+        }
+
         if( !RtlValidSecurityDescriptor( pSecurityDescr))
         {
 
@@ -8123,6 +8828,566 @@ try_exit:
         {
             ExFreePool( pACE);
         }
+
+        if( pWorldSID != NULL)
+        {
+            ExFreePool( pWorldSID);
+        }
+    }
+
+    return ntStatus;
+}
+
+void
+AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
+                       OUT UNICODE_STRING *ParentPath)
+{
+
+    USHORT usIndex = 0;
+
+    *ParentPath = *FullFileName;
+
+    //
+    // If the final character is a \, jump over it
+    //
+
+    if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
+    {
+        ParentPath->Length -= sizeof( WCHAR);
+    }
+
+    while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
+    {
+        ParentPath->Length -= sizeof( WCHAR);
+    }
+
+    //
+    // And the separator
+    //
+
+    ParentPath->Length -= sizeof( WCHAR);
+
+    return;
+}
+
+NTSTATUS
+AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
+                           IN AFSObjectInfoCB *ObjectInfo,
+                           IN BOOLEAN WriteAccess,
+                           OUT GUID *AuthGroup)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    GUID     stAuthGroup, stZeroAuthGroup;
+    BOOLEAN  bFoundAuthGroup = FALSE;
+    AFSCcb  *pCcb = NULL;
+    AFSFcb *pFcb = Fcb;
+
+    __Enter
+    {
+
+        RtlZeroMemory( &stAuthGroup,
+                       sizeof( GUID));
+
+        RtlZeroMemory( &stZeroAuthGroup,
+                       sizeof( GUID));
+
+        if( Fcb == NULL)
+        {
+
+            if( ObjectInfo != NULL &&
+                ObjectInfo->Fcb != NULL)
+            {
+                pFcb = ObjectInfo->Fcb;
+            }
+        }
+
+        if( pFcb != NULL)
+        {
+
+            AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
+                              TRUE);
+
+            pCcb = Fcb->CcbListHead;
+
+            while( pCcb != NULL)
+            {
+
+                if( WriteAccess &&
+                    pCcb->GrantedAccess & FILE_WRITE_DATA)
+                {
+                    RtlCopyMemory( &stAuthGroup,
+                                   &pCcb->AuthGroup,
+                                   sizeof( GUID));
+
+                    bFoundAuthGroup = TRUE;
+
+                    break;
+                }
+                else if( pCcb->GrantedAccess & FILE_READ_DATA)
+                {
+                    //
+                    // At least get the read-only access
+                    //
+
+                    RtlCopyMemory( &stAuthGroup,
+                                   &pCcb->AuthGroup,
+                                   sizeof( GUID));
+
+                    bFoundAuthGroup = TRUE;
+                }
+
+                pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
+            }
+
+            AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
+        }
+
+        if( !bFoundAuthGroup)
+        {
+
+            AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
+                                     (ULONGLONG)PsGetCurrentThreadId(),
+                                      &stAuthGroup);
+
+            if( RtlCompareMemory( &stZeroAuthGroup,
+                                  &stAuthGroup,
+                                  sizeof( GUID)) == sizeof( GUID))
+            {
+
+                DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
+
+                try_return( ntStatus = STATUS_ACCESS_DENIED);
+            }
+        }
+
+        RtlCopyMemory( AuthGroup,
+                       &stAuthGroup,
+                       sizeof( GUID));
+
+try_exit:
+
+        NOTHING;
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
+                            IN ULONG InvalidateReason)
+{
+
+    NTSTATUS            ntStatus = STATUS_SUCCESS;
+    IO_STATUS_BLOCK     stIoStatus;
+    LIST_ENTRY         *le;
+    AFSExtent          *pEntry;
+    ULONG               ulProcessCount = 0;
+    ULONG               ulCount = 0;
+
+    __Enter
+    {
+
+        switch( InvalidateReason)
+        {
+
+            case AFS_INVALIDATE_DELETED:
+            {
+
+                if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
+                    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
+                    // And get rid of them (note this involves waiting
+                    // for any writes or reads to the cache to complete)
+                    //
+
+                    AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                           NULL);
+
+                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
+                }
+
+                break;
+            }
+
+            case AFS_INVALIDATE_DATA_VERSION:
+            {
+
+                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)
+                {
+
+                    AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
+                                    TRUE);
+
+                    bLocked = TRUE;
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
+                                  &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                  PsGetCurrentThread());
+
+                    AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                      TRUE);
+
+                    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)
+                    {
+
+                        if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
+                        {
+
+                            if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+                            {
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                bExtentsLocked = FALSE;
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                bLocked = FALSE;
+
+                                AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                                       NULL);
+                            }
+                            else
+                            {
+
+                                __try
+                                {
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                    bExtentsLocked = FALSE;
+
+                                    if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                        !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                              NULL,
+                                                              0,
+                                                              FALSE))
+                                    {
+
+                                        AFSDbgLogMsg( 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();
+
+                                    AFSDbgLogMsg( 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);
+                                }
+                            }
+                        }
+                        else
+                        {
+
+                            //
+                            // 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
+                            {
+
+                                ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
+                                                                                   &ByteRangeList);
+
+                                if ( ByteRangeList != NULL ||
+                                     ulByteRangeCount == 0)
+                                {
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                    bExtentsLocked = FALSE;
+
+                                    for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
+                                    {
+
+                                        ULONG ulSize;
+
+                                        do {
+
+                                            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))
+                                            {
+
+                                                AFSDbgLogMsg( 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
+                                {
+
+                                    //
+                                    // 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.
+                                    //
+
+                                    le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+
+                                    ulProcessCount = 0;
+
+                                    ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+
+                                    if( ulCount > 0)
+                                    {
+                                        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))
+                                                {
+
+                                                    AFSDbgLogMsg( 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))
+                                                    {
+
+                                                        AFSDbgLogMsg( 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
+                                    {
+                                        if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                  NULL,
+                                                                  0,
+                                                                  FALSE))
+                                        {
+
+                                            AFSDbgLogMsg( 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 ( bPurgeOnClose)
+                                    {
+
+                                        SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    }
+                                }
+                            }
+                            __except( EXCEPTION_EXECUTE_HANDLER)
+                            {
+
+                                ntStatus = GetExceptionCode();
+
+                                AFSDbgLogMsg( 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);
+                            }
+                        }
+                    }
+
+                    if ( bExtentsLocked)
+                    {
+
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+                    }
+
+                    if ( bLocked)
+                    {
+
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+                    }
+
+                    if ( bCleanExtents)
+                    {
+
+                        AFSReleaseCleanExtents( ObjectInfo->Fcb,
+                                                NULL);
+                    }
+                }
+
+                break;
+            }
+        }
+
+        if( ObjectInfo != NULL)
+        {
+
+            AFSObjectInfoDecrement( ObjectInfo);
+        }
     }
 
     return ntStatus;