From 6de822d647c2d2707f4f0af149579101dd0071f8 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 2 Sep 2013 14:31:38 -0400 Subject: [PATCH] Windows: Skip Extent operations if Direct IO If the redirector is using Direct IO servicing there are no extents in use. Skip the AFSFlushExtents, AFSTearDownExtents, and related calls unless extent processing is in use. This will reduce lock contention and reduce cpu processing. Change-Id: I2948295bdd6056e6fbdab7d32c46575a8a7aebbc Reviewed-on: http://gerrit.openafs.org/10215 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSClose.cpp | 77 ++++---- src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp | 43 +++-- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 245 ++++++++++++++---------- src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp | 22 ++- 4 files changed, 224 insertions(+), 163 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp index 5ee30f1..d290eee 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp @@ -274,51 +274,60 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED); - // - // Attempt to tear down our extent list for the file - // If there are remaining dirty extents then attempt to - // flush them as well - // + if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - if( pFcb->Specific.File.ExtentsDirtyCount) - { + // + // Attempt to tear down our extent list for the file + // If there are remaining dirty extents then attempt to + // flush them as well + // - AFSFlushExtents( pFcb, - &pCcb->AuthGroup); - } + if( pFcb->Specific.File.ExtentsDirtyCount) + { - // - // Wait for any outstanding queued flushes to complete - // + AFSFlushExtents( pFcb, + &pCcb->AuthGroup); + } - AFSWaitOnQueuedFlushes( pFcb); + // + // Wait for any outstanding queued flushes to complete + // - ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 && - pFcb->Specific.File.QueuedFlushCount == 0); + AFSWaitOnQueuedFlushes( pFcb); - AFSReleaseResource( &pFcb->NPFcb->Resource); + ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 && + pFcb->Specific.File.QueuedFlushCount == 0); - // - // Tear 'em down, we'll not be needing them again - // + AFSReleaseResource( &pFcb->NPFcb->Resource); - AFSTearDownFcbExtents( pFcb, - &pCcb->AuthGroup); - } - else - { + // + // Tear 'em down, we'll not be needing them again + // - if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB && - pFcb->Specific.File.ExtentsDirtyCount && - (pCcb->GrantedAccess & FILE_WRITE_DATA)) - { + AFSTearDownFcbExtents( pFcb, + &pCcb->AuthGroup); + } + else + { - AFSFlushExtents( pFcb, - &pCcb->AuthGroup); - } + if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB && + pFcb->Specific.File.ExtentsDirtyCount && + (pCcb->GrantedAccess & FILE_WRITE_DATA)) + { - AFSReleaseResource( &pFcb->NPFcb->Resource); - } + AFSFlushExtents( pFcb, + &pCcb->AuthGroup); + } + + AFSReleaseResource( &pFcb->NPFcb->Resource); + } + } + else + { + + AFSReleaseResource( &pFcb->NPFcb->Resource); + } pDirCB = pCcb->DirectoryCB; diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp index 0e58603..524feec 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp @@ -44,6 +44,7 @@ AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject, { UNREFERENCED_PARAMETER(LibDeviceObject); + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; NTSTATUS ntStatus = STATUS_SUCCESS; IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; @@ -130,32 +131,36 @@ AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject, try_return( ntStatus = GetExceptionCode()); } - AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT, - AFS_TRACE_LEVEL_VERBOSE, - "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n", - &pFcb->NPFcb->SectionObjectResource, - PsGetCurrentThread())); + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { + + AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n", + &pFcb->NPFcb->SectionObjectResource, + PsGetCurrentThread())); - AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource); + AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource); - bReleaseSectionObject = FALSE; + bReleaseSectionObject = FALSE; - // - // Now, flush to the server - if there is stuff to do - // + // + // Now, flush to the server - if there is stuff to do + // - ntStatus = AFSFlushExtents( pFcb, - &pCcb->AuthGroup); + ntStatus = AFSFlushExtents( pFcb, + &pCcb->AuthGroup); - if( !NT_SUCCESS( ntStatus)) - { + if( !NT_SUCCESS( ntStatus)) + { - AFSReleaseExtentsWithFlush( pFcb, - &pCcb->AuthGroup, - TRUE); + AFSReleaseExtentsWithFlush( pFcb, + &pCcb->AuthGroup, + TRUE); - ntStatus = STATUS_SUCCESS; - } + ntStatus = STATUS_SUCCESS; + } + } try_exit: diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index e623623..94fb9e1 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -1695,6 +1695,7 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo, { NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; IO_STATUS_BLOCK stIoStatus; ULONG ulFilter = 0; AFSObjectInfoCB * pParentObjectInfo = NULL; @@ -1967,14 +1968,18 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo, AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource); - // - // Clear out the extents - // Get rid of them (note this involves waiting - // for any writes or reads to the cache to complete) - // + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb, - NULL); + // + // Clear out the extents + // Get rid of them (note this involves waiting + // for any writes or reads to the cache to complete) + // + + AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb, + NULL); + } } (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1; @@ -2917,6 +2922,7 @@ AFSVerifyEntry( IN GUID *AuthGroup, { NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; AFSDirEnumEntry *pDirEnumEntry = NULL; AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation; IO_STATUS_BLOCK stIoStatus; @@ -3157,29 +3163,33 @@ AFSVerifyEntry( IN GUID *AuthGroup, AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource); - AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n", - &pObjectInfo->Fcb->NPFcb->Resource, - PsGetCurrentThread())); + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource); + AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n", + &pObjectInfo->Fcb->NPFcb->Resource, + PsGetCurrentThread())); - AFSFlushExtents( pObjectInfo->Fcb, - AuthGroup); + AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource); - // - // Acquire the Fcb to purge the cache - // + AFSFlushExtents( pObjectInfo->Fcb, + AuthGroup); - AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n", - &pObjectInfo->Fcb->NPFcb->Resource, - PsGetCurrentThread())); + // + // Acquire the Fcb to purge the cache + // - AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource, - TRUE); + AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n", + &pObjectInfo->Fcb->NPFcb->Resource, + PsGetCurrentThread())); + + AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource, + TRUE); + } // // Update the metadata for the entry @@ -4010,6 +4020,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry, { NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; LARGE_INTEGER liSystemTime; AFSDirEnumEntry *pDirEnumEntry = NULL; AFSFcb *pCurrentFcb = NULL; @@ -4343,8 +4354,12 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry, if ( bPurgeExtents && bSafeToPurge) { - AFSFlushExtents( pCurrentFcb, - AuthGroup); + + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { + AFSFlushExtents( pCurrentFcb, + AuthGroup); + } } } @@ -6992,70 +7007,81 @@ AFSCleanupFcb( IN AFSFcb *Fcb, AFSReleaseResource( &Fcb->NPFcb->Resource); - // - // Wait for any currently running flush or release requests to complete - // + if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { + // + // Wait for any currently running flush or release requests to complete + // - AFSWaitOnQueuedFlushes( Fcb); + AFSWaitOnQueuedFlushes( Fcb); - // - // Now perform another flush on the file - // + // + // Now perform another flush on the file + // - if( !NT_SUCCESS( AFSFlushExtents( Fcb, - NULL))) - { + if( !NT_SUCCESS( AFSFlushExtents( Fcb, + NULL))) + { - AFSReleaseExtentsWithFlush( Fcb, - NULL, - TRUE); - } - } + AFSReleaseExtentsWithFlush( Fcb, + NULL, + TRUE); + } + } + } - if( Fcb->OpenReferenceCount == 0 || - BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) || - BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED)) - { + if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - AFSTearDownFcbExtents( Fcb, - NULL); - } + if( Fcb->OpenReferenceCount == 0 || + BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) || + BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED)) + { + + AFSTearDownFcbExtents( Fcb, + NULL); + } + } try_return( ntStatus); } KeQueryTickCount( &liTime); - // - // First up are there dirty extents in the cache to flush? - // + if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { + // + // First up are there dirty extents in the cache to flush? + // - if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) || - BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED)) - { + if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) || + BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED)) + { - // - // The file has been marked as invalid. Dump it - // + // + // The file has been marked as invalid. Dump it + // - AFSTearDownFcbExtents( Fcb, - NULL); - } - else if( ForceFlush || - ( ( Fcb->Specific.File.ExtentsDirtyCount || - Fcb->Specific.File.ExtentCount) && - (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart) - >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart)) - { - if( !NT_SUCCESS( AFSFlushExtents( Fcb, - NULL)) && - Fcb->OpenReferenceCount == 0) - { + AFSTearDownFcbExtents( Fcb, + NULL); + } + else if( ForceFlush || + ( ( Fcb->Specific.File.ExtentsDirtyCount || + Fcb->Specific.File.ExtentCount) && + (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart) + >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart)) + { - AFSReleaseExtentsWithFlush( Fcb, - NULL, - TRUE); - } + if( !NT_SUCCESS( AFSFlushExtents( Fcb, + NULL)) && + Fcb->OpenReferenceCount == 0) + { + + AFSReleaseExtentsWithFlush( Fcb, + NULL, + TRUE); + } + } } // @@ -7174,16 +7200,20 @@ AFSCleanupFcb( IN AFSFcb *Fcb, AFSReleaseResource( &Fcb->NPFcb->Resource); - if( Fcb->OpenReferenceCount <= 0) - { + if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - // - // Tear em down we'll not be needing them again - // + if( Fcb->OpenReferenceCount <= 0) + { - AFSTearDownFcbExtents( Fcb, - NULL); - } + // + // Tear em down we'll not be needing them again + // + + AFSTearDownFcbExtents( Fcb, + NULL); + } + } } else { @@ -9117,38 +9147,51 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo, __Enter { - switch( InvalidateReason) + switch( InvalidateReason) { case AFS_INVALIDATE_DELETED: { - if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE && + AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DELETED\n", + ObjectInfo->FileType, + ObjectInfo->FileId.Cell, + ObjectInfo->FileId.Volume, + ObjectInfo->FileId.Vnode, + ObjectInfo->FileId.Unique)); + + if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE && ObjectInfo->Fcb != NULL) { - AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource, - TRUE); + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { - ObjectInfo->Links = 0; + AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource, + TRUE); - ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; + ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED; - KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete, - 0, - FALSE); + KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete, + 0, + FALSE); - // - // Clear out the extents - // And get rid of them (note this involves waiting - // for any writes or reads to the cache to complete) - // + // + // Clear out the extents + // And get rid of them (note this involves waiting + // for any writes or reads to the cache to complete) + // - AFSTearDownFcbExtents( ObjectInfo->Fcb, - NULL); + AFSTearDownFcbExtents( ObjectInfo->Fcb, + NULL); - AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource); - } + AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource); + } + } + + ObjectInfo->Links = 0; break; } diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp index 31dc7de..f42860c 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp @@ -653,6 +653,7 @@ AFSWorkerThread( IN PVOID Context) AFSWorkItem *pWorkItem; BOOLEAN freeWorkItem = TRUE; AFSDeviceExt *pControlDevExt = NULL; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension; LONG lCount; pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; @@ -719,18 +720,21 @@ AFSWorkerThread( IN PVOID Context) case AFS_WORK_FLUSH_FCB: { - ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb, - &pWorkItem->AuthGroup); + if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO)) + { + ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb, + &pWorkItem->AuthGroup); - if( !NT_SUCCESS( ntStatus)) - { + if( !NT_SUCCESS( ntStatus)) + { - AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb, - &pWorkItem->AuthGroup, - FALSE); - } + AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb, + &pWorkItem->AuthGroup, + FALSE); + } + } - ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0); + ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0); lCount = InterlockedDecrement( &pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount); -- 1.9.4