Windows: Refactor and consolidate afsredir invalidation
authorJeffrey Altman <jaltman@your-file-system.com>
Tue, 24 Jan 2012 17:52:12 +0000 (12:52 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 27 Jan 2012 00:11:08 +0000 (16:11 -0800)
Invalidation requests were being processed in an inconsistent
manner because different rules were being applied to volume root
directories and other objects and whether or not the invalidation
was a whole volume invalidation or not.

This patchset consolidates all invalidation logic for an object
in the new AFSInvalidateObject function.  AFSInvalidateObject
is then called from AFSInvalidateCache and AFSInvalidateVolume
as necessary.

AFSInvalidateVolume executes AFSInvalidateObject on all objects
in the volume object tree.  As a result, whole volume invalidations
whether triggered by the file server or "fs flushvolume" now work.

Change-Id: I83f110b0987eb153794b6803a1fe48247090277f
Reviewed-on: http://gerrit.openafs.org/6616
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h

index 59a47e7..3869d29 100644 (file)
@@ -1553,199 +1553,260 @@ try_exit:
 }
 
 NTSTATUS
-AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
+AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
+                     IN     ULONG Reason)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSFcb      *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
-    AFSVolumeCB *pVolumeCB = NULL;
-    AFSFcb      *pTargetDcb = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
-    BOOLEAN     bIsChild = FALSE;
-    ULONGLONG   ullIndex = 0;
-    AFSObjectInfoCB *pObjectInfo = NULL;
     IO_STATUS_BLOCK stIoStatus;
     ULONG ulFilter = 0;
-    LONG lCount;
 
-    __Enter
+    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)
     {
-
         //
-        // Need to locate the Fcb for the directory to purge
+        // 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
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
-                      &pDevExt->Specific.RDR.VolumeTreeLock,
-                      PsGetCurrentThread());
-
-        //
-        // Starve any exclusive waiters on this paticular call
-        //
+        if( Reason == AFS_INVALIDATE_DELETED)
+        {
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
+        }
+        else
+        {
 
-        AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
+            if( Reason == AFS_INVALIDATE_FLUSHED)
+            {
 
-        //
-        // Locate the volume node
-        //
+                (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
 
-        ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
+                SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+            }
 
-        ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
-                                       ullIndex,
-                                       (AFSBTreeEntry **)&pVolumeCB);
+            (*ppObjectInfo)->Expiration.QuadPart = 0;
 
-        if( pVolumeCB != NULL)
-        {
+            (*ppObjectInfo)->TargetFileId.Vnode = 0;
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            (*ppObjectInfo)->TargetFileId.Unique = 0;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
-                          pVolumeCB,
-                          lCount);
+                          "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);
         }
 
-        AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
+        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
 
-        if( !NT_SUCCESS( ntStatus) ||
-            pVolumeCB == NULL)
+        if( Reason == AFS_INVALIDATE_CREDS)
         {
-            try_return( ntStatus = STATUS_SUCCESS);
+            ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
         }
 
-        //
-        // If this is a whole volume invalidation then go do it now
-        //
-
-        if( InvalidateCB->WholeVolume ||
-            AFSIsVolumeFID( &InvalidateCB->FileID))
+        if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+            Reason == AFS_INVALIDATE_FLUSHED)
         {
-
-            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);
-
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
-            try_return( ntStatus);
+            ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
+        }
+        else
+        {
+            ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
         }
 
-        AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
-                          TRUE);
-
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
+                                        NULL,
+                                        FILE_NOTIFY_CHANGE_FILE_NAME |
+                                        FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                        FILE_ACTION_MODIFIED);
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
-                      pVolumeCB,
-                      pVolumeCB->VolumeReferenceCount);
+        try_return( ntStatus);
+    }
 
-        ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
+    //
+    // Depending on the reason for invalidation then perform work on the node
+    //
 
-        ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
-                                       ullIndex,
-                                       (AFSBTreeEntry **)&pObjectInfo);
+    switch( Reason)
+    {
 
-        if( pObjectInfo != NULL)
+    case AFS_INVALIDATE_DELETED:
         {
 
             //
-            // Reference the node so it won't be torn down
+            // Mark this node as invalid
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
-                          pObjectInfo,
-                          lCount);
-        }
+                          "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
+                          (*ppObjectInfo)->FileId.Cell,
+                          (*ppObjectInfo)->FileId.Volume,
+                          (*ppObjectInfo)->FileId.Vnode,
+                          (*ppObjectInfo)->FileId.Unique);
 
-        AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+            if( (*ppObjectInfo)->ParentObjectInformation != NULL)
+            {
 
-        if( !NT_SUCCESS( ntStatus) ||
-            pObjectInfo == NULL)
-        {
-            try_return( ntStatus = STATUS_SUCCESS);
-        }
+                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);
 
-        if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
-            pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
-        {
+                SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
 
-            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);
+                (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
 
-            //
-            // 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
-            //
+                (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
+            }
 
-            if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
+            if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
             {
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
+                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
+            }
 
-                if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
+            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
                 {
 
-                    pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+                    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;
+                    }
 
-                    SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+                    CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
+                                         NULL,
+                                         0,
+                                         FALSE);
                 }
+                __except( EXCEPTION_EXECUTE_HANDLER)
+                {
 
-                pObjectInfo->Expiration.QuadPart = 0;
+                    ntStatus = GetExceptionCode();
+                }
 
-                pObjectInfo->TargetFileId.Vnode = 0;
+                AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
 
-                pObjectInfo->TargetFileId.Unique = 0;
+                //
+                // Clear out the extents
+                // Get rid of them (note this involves waiting
+                // for any writes or reads to the cache to complete)
+                //
+
+                (VOID) 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,
-                              "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
-                              pObjectInfo->FileId.Cell,
-                              pObjectInfo->FileId.Volume,
-                              pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique);
+                              "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( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+                SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
             }
 
-            ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
+            // Fall through to the default processing
+        }
 
-            if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
+    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( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
-                InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
+            if( Reason == AFS_INVALIDATE_DATA_VERSION)
             {
                 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
             }
@@ -1754,223 +1815,213 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
                 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
             }
 
-            AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+            AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
                                             NULL,
-                                            FILE_NOTIFY_CHANGE_FILE_NAME |
-                                            FILE_NOTIFY_CHANGE_ATTRIBUTES,
+                                            ulFilter,
                                             FILE_ACTION_MODIFIED);
 
-            try_return( ntStatus);
-        }
+            //
+            // Indicate this node requires re-evaluation for the remaining reasons
+            //
 
-        //
-        // Depending on the reason for invalidation then perform work on the node
-        //
+            (*ppObjectInfo)->Expiration.QuadPart = 0;
 
-        switch( InvalidateCB->Reason)
-        {
+            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);
 
-            case AFS_INVALIDATE_DELETED:
+            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)))
+                {
 
-                //
-                // Mark this node as invalid
-                //
+                    (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
+                }
+            }
 
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
+            break;
+        }
+    }
 
-                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);
+  try_exit:
 
-                if( pObjectInfo->ParentObjectInformation != NULL)
-                {
+    return ntStatus;
+}
 
-                    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);
+NTSTATUS
+AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
+{
 
-                    SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    AFSFcb      *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
+    AFSVolumeCB *pVolumeCB = NULL;
+    AFSFcb      *pTargetDcb = NULL;
+    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    AFSDirectoryCB *pCurrentDirEntry = NULL;
+    BOOLEAN     bIsChild = FALSE;
+    ULONGLONG   ullIndex = 0;
+    AFSObjectInfoCB *pObjectInfo = NULL;
+    LONG lCount;
 
-                    pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
+    __Enter
+    {
 
-                    pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
-                }
+        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);
 
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                }
-                else
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                }
+        //
+        // Need to locate the Fcb for the directory to purge
+        //
 
-                AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
-                                                NULL,
-                                                ulFilter,
-                                                FILE_ACTION_REMOVED);
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
+                      &pDevExt->Specific.RDR.VolumeTreeLock,
+                      PsGetCurrentThread());
 
-                if( NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
-                                                          InvalidateCB->Reason)))
-                {
-                    pObjectInfo = NULL; // We'll dec the count in the worker item
-                }
+        //
+        // Starve any exclusive waiters on this paticular call
+        //
 
-                break;
-            }
+        AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
 
-            case AFS_INVALIDATE_FLUSHED:
-            {
+        //
+        // Locate the volume node
+        //
 
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
-                    pObjectInfo->Fcb != NULL)
-                {
+        ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
 
-                    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);
+        ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
+                                       ullIndex,
+                                       (AFSBTreeEntry **)&pVolumeCB);
 
-                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
-                                    TRUE);
+        if( pVolumeCB != NULL)
+        {
 
-                    __try
-                    {
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
-                        CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                      NULL,
-                                      0,
-                                      &stIoStatus);
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+        }
 
-                        if( !NT_SUCCESS( stIoStatus.Status))
-                        {
+        AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
 
-                            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);
+        if( !NT_SUCCESS( ntStatus) ||
+            pVolumeCB == NULL)
+        {
 
-                            ntStatus = stIoStatus.Status;
-                        }
+            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);
 
-                        CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                             NULL,
-                                             0,
-                                             FALSE);
-                    }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
-                    {
+            try_return( ntStatus = STATUS_SUCCESS);
+        }
 
-                        ntStatus = GetExceptionCode();
-                    }
+        //
+        // If this is a whole volume invalidation then go do it now
+        //
 
-                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
+        if( InvalidateCB->WholeVolume)
+        {
 
-                    //
-                    // Clear out the extents
-                    // Get rid of them (note this involves waiting
-                    // for any writes or reads to the cache to complete)
-                    //
+            ntStatus = AFSInvalidateVolume( pVolumeCB,
+                                            InvalidateCB->Reason);
 
-                    (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
-                                                  NULL);
-                }
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
-                pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+            try_return( ntStatus);
+        }
 
+        if ( AFSIsVolumeFID( &InvalidateCB->FileID))
+        {
 
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
-                {
+            pObjectInfo = &pVolumeCB->ObjectInformation;
+        }
+        else
+        {
 
-                    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);
+            AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+                              TRUE);
 
-                    SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                }
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
-                // Fall through to the default processing
-            }
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          pVolumeCB->VolumeReferenceCount);
 
-            default:
-            {
+            ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
 
-                if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                }
-                else
-                {
-                    ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                }
+            ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
+                                           ullIndex,
+                                           (AFSBTreeEntry **)&pObjectInfo);
 
-                if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                }
+            AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
 
-                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);
+        if( pObjectInfo != NULL)
+        {
 
-                //
-                // Indicate this node requires re-evaluation for the remaining reasons
-                //
+            //
+            // Reference the node so it won't be torn down
+            //
 
-                pObjectInfo->Expiration.QuadPart = 0;
+            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
-                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);
+            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
+                          pObjectInfo,
+                          lCount);
+        }
 
-                SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+        if( !NT_SUCCESS( ntStatus) ||
+            pObjectInfo == NULL)
+        {
 
-                if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION &&
-                    NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
-                                                          InvalidateCB->Reason)))
-                {
-                    pObjectInfo = NULL; // We'll dec the count in the worker item
-                }
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "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);
 
-                break;
-            }
+            try_return( ntStatus = STATUS_SUCCESS);
         }
 
+        AFSInvalidateObject( &pObjectInfo,
+                             InvalidateCB->Reason);
+
 try_exit:
 
         if( pObjectInfo != NULL)
@@ -2371,8 +2422,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
@@ -2401,203 +2454,113 @@ 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);
-
-                AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
-                                  TRUE);
-
-                pCurrentObject = VolumeCB->ObjectInfoListHead;
-
-                while( pCurrentObject != NULL)
-                {
-
-                    if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                    }
-                    else
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                    }
-
-                    AFSFsRtlNotifyFullReportChange( pCurrentObject,
-                                                    NULL,
-                                                    ulFilter,
-                                                    FILE_ACTION_REMOVED);
-
-                    SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
-
-                    pFcb = pCurrentObject->Fcb;
-
-                    if( pFcb != NULL &&
-                        pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
-                    {
-
-
-                        //
-                        // 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( pFcb,
-                                                      NULL);
-                    }
-
-                    pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
-                }
-
-                AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
-
                 break;
             }
+        }
 
-            default:
-            {
-
-                //
-                // Indicate this node requires re-evaluation for the remaining reasons
-                //
-
-                VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              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)
-                {
+        //
+        // Invalidate the volume root directory
+        //
 
-                    VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
-                }
+        pCurrentObject = &VolumeCB->ObjectInformation;
 
-                //
-                // Notify anyone that cares
-                //
+        if ( pCurrentObject )
+        {
 
-                ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
+            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
 
-                if( Reason == AFS_INVALIDATE_CREDS)
-                {
-                    ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                }
+            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                          pCurrentObject,
+                          lCount);
 
-                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;
-                }
+            AFSInvalidateObject( &pCurrentObject,
+                                 Reason);
 
-                AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
-                                                NULL,
-                                                ulFilter,
-                                                FILE_ACTION_MODIFIED);
+            lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
 
-                //
-                // Volume invalidations require all objects in the volume be re-verified
-                //
+            AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                          pCurrentObject,
+                          lCount);
+        }
 
-                AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
-                                  TRUE);
+        //
+        // Apply invalidation to all other volume objects
+        //
 
-                pCurrentObject = VolumeCB->ObjectInfoListHead;
+        AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+                          TRUE);
 
-                while( pCurrentObject != NULL)
-                {
+        pCurrentObject = VolumeCB->ObjectInfoListHead;
 
-                    pCurrentObject->Expiration.QuadPart = 0;
+        if ( pCurrentObject)
+        {
 
-                    pCurrentObject->TargetFileId.Vnode = 0;
+            //
+            // Reference the node so it won't be torn down
+            //
 
-                    pCurrentObject->TargetFileId.Unique = 0;
+            lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
 
-                    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);
+            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_VERIFY);
+        while( pCurrentObject != NULL)
+        {
 
-                    if( Reason == AFS_INVALIDATE_FLUSHED)
-                    {
+            pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
 
-                        pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
-                    }
+            if ( pNextObject)
+            {
 
-                    if( Reason == AFS_INVALIDATE_FLUSHED &&
-                        pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
-                    {
+                //
+                // Reference the node so it won't be torn down
+                //
 
-                        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);
+                lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
 
-                        SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
-                    }
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
+                              pNextObject,
+                              lCount);
+            }
 
-                    if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
-                    }
-                    else
-                    {
-                        ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
-                    }
+            AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
 
-                    if( Reason == AFS_INVALIDATE_CREDS)
-                    {
-                        ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
-                    }
+            AFSInvalidateObject( &pCurrentObject,
+                                 Reason);
 
-                    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;
-                    }
+            if ( pCurrentObject )
+            {
 
-                    AFSFsRtlNotifyFullReportChange( pCurrentObject,
-                                                    NULL,
-                                                    ulFilter,
-                                                    FILE_ACTION_MODIFIED);
+                lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
 
-                    pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
-                }
+                AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+                              pCurrentObject,
+                              lCount);
+            }
 
-                AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+            AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+                              TRUE);
 
-                break;
-            }
+            pCurrentObject = pNextObject;
         }
+
+        AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
     }
 
     return ntStatus;
@@ -2763,7 +2726,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
-                                  "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
+                                  "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
                                   &DirEntry->NameInformation.FileName,
                                   pObjectInfo->FileId.Cell,
                                   pObjectInfo->FileId.Volume,
index 197bb6b..dca9a63 100644 (file)
@@ -1114,6 +1114,10 @@ AFSValidateSymLink( IN GUID *AuthGroup,
 NTSTATUS
 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB);
 
+NTSTATUS
+AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
+                     IN     ULONG Reason);
+
 BOOLEAN
 AFSIsChildOfParent( IN AFSFcb *Dcb,
                     IN AFSFcb *Fcb);