From: Jeffrey Altman Date: Tue, 24 Jan 2012 17:52:12 +0000 (-0500) Subject: Windows: Refactor and consolidate afsredir invalidation X-Git-Tag: upstream/1.8.0_pre1^2~2800 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=e44163a5470c6a9ff766641e4ce1ade6569cbadb;p=packages%2Fo%2Fopenafs.git Windows: Refactor and consolidate afsredir invalidation 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 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 59a47e7bc..3869d29db 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -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, diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index 197bb6b84..dca9a6333 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -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);