Windows: Performing async work after cache invalidation
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index f51e31e..ca071ed 100644 (file)
@@ -324,43 +324,6 @@ AFSCompleteRequest( IN PIRP Irp,
 }
 
 //
-// Function: AFSBuildCRCTable
-//
-// Description:
-//
-//      This function builds the CRC table for mapping filenames to a CRC value.
-//
-// Return:
-//
-//      A status is returned for the function
-//
-
-void
-AFSBuildCRCTable()
-{
-    ULONG crc;
-    int i, j;
-
-    for ( i = 0; i <= 255; i++)
-    {
-        crc = i;
-        for ( j = 8; j > 0; j--)
-        {
-            if (crc & 1)
-            {
-                crc = ( crc >> 1 ) ^ CRC32_POLYNOMIAL;
-            }
-            else
-            {
-                crc >>= 1;
-            }
-        }
-
-        AFSCRCTable[ i ] = crc;
-    }
-}
-
-//
 // Function: AFSGenerateCRC
 //
 // Description:
@@ -377,54 +340,20 @@ AFSGenerateCRC( IN PUNICODE_STRING FileName,
                 IN BOOLEAN UpperCaseName)
 {
 
-    ULONG crc;
-    ULONG temp1, temp2;
-    UNICODE_STRING UpcaseString;
-    WCHAR *lpbuffer;
-    USHORT size = 0;
-
-    if( !AFSCRCTable[1])
-    {
-        AFSBuildCRCTable();
-    }
-
-    crc = 0xFFFFFFFFL;
-
-    if( UpperCaseName)
-    {
-
-        RtlUpcaseUnicodeString( &UpcaseString,
-                                FileName,
-                                TRUE);
-
-        lpbuffer = UpcaseString.Buffer;
-
-        size = (UpcaseString.Length/sizeof( WCHAR));
-    }
-    else
-    {
-
-        lpbuffer = FileName->Buffer;
-
-        size = (FileName->Length/sizeof( WCHAR));
-    }
+    ULONG ulCRC = 0;
+    NTSTATUS ntStatus = STATUS_SUCCESS;
 
-    while (size--)
-    {
-        temp1 = (crc >> 8) & 0x00FFFFFFL;
-        temp2 = AFSCRCTable[((int)crc ^ *lpbuffer++) & 0xff];
-        crc = temp1 ^ temp2;
-    }
+    ntStatus = RtlHashUnicodeString( FileName,
+                                     UpperCaseName,
+                                     HASH_STRING_ALGORITHM_DEFAULT,
+                                     &ulCRC);
 
-    if( UpperCaseName)
+    if( !NT_SUCCESS( ntStatus))
     {
-
-        RtlFreeUnicodeString( &UpcaseString);
+        ulCRC = 0;
     }
 
-    crc ^= 0xFFFFFFFFL;
-
-    return crc;
+    return ulCRC;
 }
 
 void *
@@ -714,6 +643,7 @@ AFSInitializeGlobalDirectoryEntries()
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfoCB = NULL;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -736,13 +666,13 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
 
         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;
 
@@ -843,13 +773,13 @@ AFSInitializeGlobalDirectoryEntries()
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
 
         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;
 
@@ -983,6 +913,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
     BOOLEAN bAllocatedObjectCB = FALSE;
     ULONGLONG ullIndex = 0;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -1031,7 +962,7 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
             bAllocatedObjectCB = TRUE;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
                           pObjectInfoCB,
@@ -1039,13 +970,13 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                           FileName);
         }
 
-        InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
+        lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
 
         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);
 
@@ -1093,10 +1024,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;
 
@@ -1128,6 +1059,16 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
                                                                            TRUE);
         }
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
+                      pDirNode,
+                      FileName,
+                      ParentObjectInfo->FileId.Cell,
+                      ParentObjectInfo->FileId.Volume,
+                      ParentObjectInfo->FileId.Vnode,
+                      ParentObjectInfo->FileId.Unique);
+
         if( TargetName != NULL &&
             TargetName->Length > 0)
         {
@@ -1176,12 +1117,17 @@ AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
 
             pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
 
-            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
-                pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
+            if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+            {
+
+                pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+            }
+
+            if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
                 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
             {
 
-                pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+                pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
             }
 
             pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
@@ -1250,13 +1196,13 @@ try_exit:
             if( pObjectInfoCB != NULL)
             {
 
-                InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
+                lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
 
                 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)
                 {
@@ -1392,12 +1338,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;
@@ -1572,12 +1523,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;
@@ -1611,6 +1567,7 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
     AFSObjectInfoCB *pObjectInfo = NULL;
     IO_STATUS_BLOCK stIoStatus;
     ULONG ulFilter = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -1644,13 +1601,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);
@@ -1675,13 +1632,13 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             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_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);
         }
@@ -1689,7 +1646,7 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -1710,13 +1667,13 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             // Reference the node so it won't be torn down
             //
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
             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);
@@ -1755,10 +1712,12 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
             else
             {
 
-                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
-                    InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
+                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
                 {
+
                     pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+                    SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
                 }
 
                 pObjectInfo->Expiration.QuadPart = 0;
@@ -1785,7 +1744,8 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
             }
 
-            if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
+            if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
+                InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
             {
                 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
             }
@@ -1839,7 +1799,9 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                                   pObjectInfo->ParentObjectInformation->FileId.Unique);
 
                     SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
                     pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+
                     pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
                 }
 
@@ -1857,6 +1819,12 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                                                 ulFilter,
                                                 FILE_ACTION_REMOVED);
 
+                if( NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
+                                                          InvalidateCB->Reason)))
+                {
+                    pObjectInfo = NULL; // We'll dec the count in the worker item
+                }
+
                 break;
             }
 
@@ -1921,7 +1889,25 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                     // for any writes or reads to the cache to complete)
                     //
 
-                    (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
+                    (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
+                                                  NULL);
+                }
+
+                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);
                 }
 
                 // Fall through to the default processing
@@ -1974,24 +1960,11 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
 
                 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
-                    InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
+                if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION &&
+                    NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
+                                                          InvalidateCB->Reason)))
                 {
-                    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);
-                    }
+                    pObjectInfo = NULL; // We'll dec the count in the worker item
                 }
 
                 break;
@@ -2003,13 +1976,13 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
     }
 
@@ -2476,7 +2449,8 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                         // for any writes or reads to the cache to complete)
                         //
 
-                        (VOID) AFSTearDownFcbExtents( pFcb);
+                        (VOID) AFSTearDownFcbExtents( pFcb,
+                                                      NULL);
                     }
 
                     pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
@@ -2506,8 +2480,7 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
 
                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-                if( Reason == AFS_INVALIDATE_FLUSHED ||
-                    Reason == AFS_INVALIDATE_DATA_VERSION)
+                if( Reason == AFS_INVALIDATE_FLUSHED)
                 {
 
                     VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
@@ -2524,7 +2497,8 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                     ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
                 }
 
-                if( Reason == AFS_INVALIDATE_DATA_VERSION)
+                if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+                    Reason == AFS_INVALIDATE_FLUSHED)
                 {
                     ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
                 }
@@ -2566,25 +2540,25 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
 
                     SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-                    if( Reason == AFS_INVALIDATE_FLUSHED ||
-                        Reason == AFS_INVALIDATE_DATA_VERSION)
+                    if( Reason == AFS_INVALIDATE_FLUSHED)
                     {
 
                         pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
+                    }
 
-                        if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
-                        {
+                    if( Reason == AFS_INVALIDATE_FLUSHED &&
+                        pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
+                    {
 
-                            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);
+                        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);
 
-                            SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                        }
+                        SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
                     }
 
                     if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
@@ -2601,7 +2575,8 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
                         ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
                     }
 
-                    if( Reason == AFS_INVALIDATE_DATA_VERSION)
+                    if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+                        Reason == AFS_INVALIDATE_FLUSHED)
                     {
                         ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
                     }
@@ -2867,7 +2842,8 @@ AFSVerifyEntry( IN GUID *AuthGroup,
 
                     if ( bPurgeExtents)
                     {
-                        AFSFlushExtents( pObjectInfo->Fcb);
+                        AFSFlushExtents( pObjectInfo->Fcb,
+                                         AuthGroup);
                     }
 
                     //
@@ -2944,10 +2920,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);
+                    }
                 }
 
                 //
@@ -3030,8 +3012,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;
         }
@@ -3058,6 +3045,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
     AFSVolumeCB *pVolumeCB = NULL;
     AFSFcb *pFcb = NULL;
     AFSObjectInfoCB *pCurrentObject = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -3094,7 +3082,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
         if( pVolumeCB != NULL)
         {
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
@@ -3181,7 +3169,8 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
                     // for any writes or reads to the cache to complete)
                     //
 
-                    (VOID) AFSTearDownFcbExtents( pFcb);
+                    (VOID) AFSTearDownFcbExtents( pFcb,
+                                                  NULL);
                 }
 
                 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
@@ -3189,7 +3178,7 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
 
             AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
         }
         else
         {
@@ -3307,21 +3296,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
@@ -3337,11 +3380,60 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
             if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
             {
 
+                if( !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)
             {
 
@@ -3387,6 +3479,8 @@ AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
         }
 #endif
 
+try_exit:
+
         if( bAcquiredLock)
         {
 
@@ -3472,12 +3566,17 @@ 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;
@@ -3659,7 +3758,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,
@@ -3676,7 +3776,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,
@@ -3829,7 +3930,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
 
                     if ( bPurgeExtents)
                     {
-                        AFSFlushExtents( pCurrentFcb);
+                        AFSFlushExtents( pCurrentFcb,
+                                         AuthGroup);
                     }
 
                     //
@@ -3971,8 +4073,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;
         }
@@ -4733,6 +4841,7 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
 
     AFSNameArrayHdr *pNameArray = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount;
 
     __Enter
     {
@@ -4769,16 +4878,16 @@ AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
 
             pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
 
-            InterlockedIncrement( &pNameArray->Count);
+            lCount = InterlockedIncrement( &pNameArray->Count);
 
-            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;
 
@@ -4808,6 +4917,7 @@ AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
     ULONG  ulTotalCount = 0;
     ULONG ulIndex = 0;
     USHORT usLength = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -4826,14 +4936,14 @@ 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;
 
@@ -4873,6 +4983,7 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
     ULONG  ulTotalCount = 0;
     ULONG ulIndex = 0;
     USHORT usLength = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -4902,16 +5013,16 @@ AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
 
             pCurrentElement->FileId    = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
 
-            InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
+            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);
 
             if( pCurrentElement->DirectoryCB == DirectoryCB ||
                 NameArray->Count == RelatedNameArray->Count)
@@ -4944,6 +5055,7 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSNameArrayCB *pCurrentElement = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -4959,14 +5071,14 @@ AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
                 break;
             }
 
-            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);
+                          lCount);
 
             pCurrentElement++;
         }
@@ -4984,6 +5096,7 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount;
 
     __Enter
     {
@@ -5011,16 +5124,16 @@ AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
             NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
         }
 
-        InterlockedIncrement( &NameArray->Count);
+        lCount = InterlockedIncrement( &NameArray->Count);
 
-        InterlockedIncrement( &DirEntry->OpenReferenceCount);
+        lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
                       &DirEntry->NameInformation.FileName,
                       DirEntry,
-                      DirEntry->OpenReferenceCount);
+                      lCount);
 
         NameArray->CurrentEntry->DirectoryCB = DirEntry;
 
@@ -5040,26 +5153,27 @@ void
 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
                           IN AFSDirectoryCB *DirectoryCB)
 {
+    LONG lCount;
 
     ASSERT( NameArray->CurrentEntry != NULL);
 
-    InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+    lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
                   &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
                   NameArray->CurrentEntry->DirectoryCB,
-                  NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
+                  lCount);
 
-    InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
+    lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
                   &DirectoryCB->NameInformation.FileName,
                   DirectoryCB,
-                  DirectoryCB->OpenReferenceCount);
+                  lCount);
 
     NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
 
@@ -5081,6 +5195,7 @@ AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
 {
 
     AFSDirectoryCB *pCurrentDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5090,18 +5205,20 @@ AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
             try_return( pCurrentDirEntry);
         }
 
-        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;
         }
@@ -5155,6 +5272,7 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
 
     AFSNameArrayCB *pCurrentElement = NULL;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    LONG lCount;
 
     __Enter
     {
@@ -5170,14 +5288,14 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
                 break;
             }
 
-            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);
+                          lCount);
 
             pCurrentElement++;
         }
@@ -5193,16 +5311,16 @@ AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
 
             NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
 
-            InterlockedIncrement( &NameArray->Count);
+            lCount = InterlockedIncrement( &NameArray->Count);
 
-            InterlockedIncrement( &DirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &DirEntry->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);
+                          lCount);
 
             NameArray->CurrentEntry->DirectoryCB = DirEntry;
 
@@ -5246,6 +5364,7 @@ AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
 void
 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
 {
+    LONG lCount;
 
     //
     // Depending on the type of node, set the event
@@ -5261,7 +5380,7 @@ AFSSetEnumerationEvent( IN AFSFcb *Fcb)
                         0,
                         FALSE);
 
-            InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
+            lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
             break;
         }
@@ -5274,7 +5393,7 @@ AFSSetEnumerationEvent( IN AFSFcb *Fcb)
                         0,
                         FALSE);
 
-            InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
+            lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
             break;
         }
@@ -5287,6 +5406,8 @@ void
 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
 {
 
+    LONG lCount;
+
     //
     // Depending on the type of node, set the event
     //
@@ -5299,7 +5420,9 @@ AFSClearEnumerationEvent( IN AFSFcb *Fcb)
 
             ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
 
-            if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
+            lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
+
+            if( lCount == 0)
             {
 
                 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
@@ -5314,7 +5437,9 @@ AFSClearEnumerationEvent( IN AFSFcb *Fcb)
 
             ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
 
-            if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
+            lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
+
+            if( lCount == 0)
             {
 
                 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
@@ -5448,10 +5573,6 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
         if( pNonPagedDirEntry == NULL)
         {
 
-            AFSExFreePool( pDirNode);
-
-            AFSDeleteObjectInfo( pObjectInfoCB);
-
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
@@ -5492,7 +5613,21 @@ AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
 
 try_exit:
 
-        NOTHING;
+        if ( !NT_SUCCESS( ntStatus))
+        {
+
+            if ( pDirNode != NULL)
+            {
+
+                AFSExFreePool( pDirNode);
+            }
+
+            if ( pObjectInfoCB != NULL)
+            {
+
+                AFSDeleteObjectInfo( pObjectInfoCB);
+            }
+        }
     }
 
     return ntStatus;
@@ -5503,6 +5638,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                            IN AFSDirectoryCB *DirectoryCB,
                            IN UNICODE_STRING *ParentPathName,
                            IN AFSNameArrayHdr *RelatedNameArray,
+                           IN GUID           *AuthGroup,
                            OUT AFSFileInfoCB *FileInfo)
 {
 
@@ -5515,7 +5651,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
-    GUID *pAuthGroup = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -5532,17 +5668,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);
 
@@ -5553,7 +5680,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                 if( pDirEntry != NULL)
                 {
 
-                    ntStatus = STATUS_ACCESS_DENIED;
+                    ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
                 }
 
                 try_return( ntStatus);
@@ -5688,9 +5815,6 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
             pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
-
             pParentDirEntry = ParentDirectoryCB;
         }
         else
@@ -5768,9 +5892,6 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
             pVolumeCB = AFSGlobalRoot;
 
-            AFSAcquireShared( pVolumeCB->VolumeLock,
-                              TRUE);
-
             pParentDirEntry = AFSGlobalRoot->DirectoryCB;
         }
 
@@ -5778,15 +5899,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,
@@ -5794,7 +5915,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      pParentDirEntry->OpenReferenceCount);
+                      lCount);
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -5821,21 +5942,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,
@@ -5843,12 +5962,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,
@@ -5856,7 +5975,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                   &pParentDirEntry->NameInformation.FileName,
                                   pParentDirEntry,
                                   NULL,
-                                  pParentDirEntry->OpenReferenceCount);
+                                  lCount);
                 }
             }
 
@@ -5878,13 +5997,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;
@@ -5903,7 +6031,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,
@@ -5911,7 +6039,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                       &pDirectoryEntry->NameInformation.FileName,
                       pDirectoryEntry,
                       NULL,
-                      pDirectoryEntry->OpenReferenceCount);
+                      lCount);
 
 try_exit:
 
@@ -5924,15 +6052,13 @@ try_exit:
         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)
@@ -5952,14 +6078,14 @@ try_exit:
             // offset by the length of the server name
             //
 
-            AFSExFreePool( pwchBuffer);
-
             if( uniFullPathName.Length > 0 &&
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
                 AFSExFreePool( uniFullPathName.Buffer);
             }
+
+            AFSExFreePool( pwchBuffer);
         }
     }
 
@@ -5973,6 +6099,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSObjectInfoCB *pObjectInfo = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -6012,7 +6139,7 @@ AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
 
         if( ParentObjectInfo != NULL)
         {
-            InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
         }
 
         //
@@ -6083,6 +6210,7 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 {
 
     BOOLEAN bAcquiredTreeLock = FALSE;
+    LONG lCount;
 
     if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
     {
@@ -6146,7 +6274,8 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
 
     if( ObjectInfo->ParentObjectInformation != NULL)
     {
-        InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
+
+        lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
     }
 
     if( bAcquiredTreeLock)
@@ -6188,11 +6317,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
         //
@@ -6205,13 +6345,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);
 
@@ -6222,7 +6357,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                 if( pDirEntry != NULL)
                 {
 
-                    ntStatus = STATUS_ACCESS_DENIED;
+                    ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
                 }
 
                 try_return( ntStatus);
@@ -6335,20 +6470,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,
@@ -6356,7 +6488,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                       &pParentDirEntry->NameInformation.FileName,
                       pParentDirEntry,
                       NULL,
-                      pParentDirEntry->OpenReferenceCount);
+                      lCount);
 
         ntStatus = AFSLocateNameEntry( NULL,
                                        NULL,
@@ -6383,21 +6515,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,
@@ -6405,12 +6535,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,
@@ -6418,7 +6548,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                   &pParentDirEntry->NameInformation.FileName,
                                   pParentDirEntry,
                                   NULL,
-                                  pParentDirEntry->OpenReferenceCount);
+                                  lCount);
                 }
             }
 
@@ -6444,15 +6574,13 @@ try_exit:
         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)
@@ -6472,14 +6600,14 @@ try_exit:
             // offset by the length of the server name
             //
 
-            AFSExFreePool( pwchBuffer);
-
             if( uniFullPathName.Length > 0 &&
                 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
             {
 
                 AFSExFreePool( uniFullPathName.Buffer);
             }
+
+            AFSExFreePool( pwchBuffer);
         }
     }
 
@@ -6563,10 +6691,12 @@ 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);
                 }
             }
 
@@ -6575,7 +6705,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
             {
 
-                AFSTearDownFcbExtents( Fcb);
+                AFSTearDownFcbExtents( Fcb,
+                                       NULL);
             }
 
             try_return( ntStatus);
@@ -6595,12 +6726,13 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
               (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);
             }
         }
         else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
@@ -6611,7 +6743,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
             // The file has been marked as invalid.  Dump it
             //
 
-            AFSTearDownFcbExtents( Fcb);
+            AFSTearDownFcbExtents( Fcb,
+                                   NULL);
         }
 
         //
@@ -6675,7 +6808,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                 // Tear em down we'll not be needing them again
                 //
 
-                AFSTearDownFcbExtents( Fcb);
+                AFSTearDownFcbExtents( Fcb,
+                                       NULL);
             }
         }
 
@@ -6963,6 +7097,12 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
         {
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
+                          DirEntry,
+                          &DirEntry->NameInformation.FileName);
+
             try_return( ntStatus);
         }
 
@@ -6972,26 +7112,53 @@ AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
         // Remove the entry from the parent tree
         //
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
+                      DirEntry,
+                      &DirEntry->NameInformation.FileName);
+
         AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
                                         DirEntry);
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
+                      DirEntry,
+                      &DirEntry->NameInformation.FileName);
+
         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))
         {
 
             //
             // From the short name tree
             //
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
+                          DirEntry,
+                          &DirEntry->NameInformation.FileName);
+
             AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
                                         DirEntry);
+
+            ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
         }
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
+                      DirEntry,
+                      &DirEntry->NameInformation.FileName);
+
         SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
 
+        ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
 try_exit:
 
         NOTHING;
@@ -7127,7 +7294,7 @@ AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
 
     BOOLEAN bIsValid = TRUE;
     ULONG ulCount = 0;
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
+    AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
 
     pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
 
@@ -7137,6 +7304,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;
@@ -7248,10 +7430,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);
 
         //
@@ -7429,6 +7610,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
     UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
     AFSNameArrayHdr *pNameArray = NULL;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -7459,13 +7641,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);
@@ -7481,9 +7663,9 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
                 pObjectInfo = &pVolumeCB->ObjectInformation;
 
-                InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
             }
             else
             {
@@ -7491,13 +7673,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);
 
@@ -7512,13 +7694,13 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     // Reference the node so it won't be torn down
                     //
 
-                    InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
                     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);
@@ -7582,24 +7764,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,
@@ -7607,7 +7786,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                           &pParentDirEntry->NameInformation.FileName,
                           pParentDirEntry,
                           NULL,
-                          pParentDirEntry->OpenReferenceCount);
+                          lCount);
 
             ntStatus = AFSLocateNameEntry( NULL,
                                            NULL,
@@ -7635,21 +7814,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,
@@ -7657,12 +7834,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,
@@ -7670,7 +7847,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                       &pParentDirEntry->NameInformation.FileName,
                                       pParentDirEntry,
                                       NULL,
-                                      pParentDirEntry->OpenReferenceCount);
+                                      lCount);
                     }
                 }
 
@@ -7683,24 +7860,22 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             // Remove the reference made above
             //
 
-            InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
+            lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
 
             pObjectInfo = pDirectoryEntry->ObjectInformation;
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
             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);
             }
         }
 
@@ -7749,7 +7924,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
         }
 
         if( pNameArray != NULL)
@@ -7770,6 +7945,7 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSDirectoryCB *pDirEntry = NULL;
     ULONG ulCRC = 0;
+    LONG lCount;
 
     __Enter
     {
@@ -7839,7 +8015,7 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
 
         if( pDirEntry != NULL)
         {
-            InterlockedIncrement( &pDirEntry->OpenReferenceCount);
+            lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
         }
 
         AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -7862,12 +8038,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:
 
@@ -7959,10 +8135,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)
         {
 
@@ -8082,6 +8283,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))
         {
 
@@ -8144,6 +8378,255 @@ 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)
+                {
+
+
+                    //
+                    // Clear out the extents
+                    // And get rid of them (note this involves waiting
+                    // for any writes or reads to the cache to complete)
+                    //
+
+                    (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                                  NULL);
+                }
+
+                break;
+            }
+
+            case AFS_INVALIDATE_DATA_VERSION:
+            {
+
+                if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
+                    ObjectInfo->Fcb != NULL)
+                {
+
+                    AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
+                                    TRUE);
+
+                    AFSLockForExtentsTrim( ObjectInfo->Fcb);
+
+                    __try
+                    {
+
+                        le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+
+                        ulProcessCount = 0;
+
+                        ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+
+                        while( ulProcessCount < ulCount)
+                        {
+                            pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                            if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                            {
+                                CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                     &pEntry->FileOffset,
+                                                     pEntry->Size,
+                                                     FALSE);
+                            }
+
+                            ulProcessCount++;
+                            le = le->Flink;
+                        }
+                    }
+                    __except( EXCEPTION_EXECUTE_HANDLER)
+                    {
+
+                        ntStatus = GetExceptionCode();
+                    }
+
+                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                    AFSReleaseCleanExtents( ObjectInfo->Fcb,
+                                            NULL);
+                }
+
+                break;
+            }
+
+            default:
+            {
+
+                break;
+            }
+        }
+
+        if( ObjectInfo != NULL)
+        {
+            InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+        }
     }
 
     return ntStatus;