From: Rod Widdowson Date: Fri, 15 Feb 2013 10:57:29 +0000 (-0500) Subject: Windows: Allow the Library to pend a write request X-Git-Tag: upstream/1.8.0_pre1^2~1491 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=82161c478a871d959daf7f3ffb4d38d1bfabe6d6;p=packages%2Fo%2Fopenafs.git Windows: Allow the Library to pend a write request If the library pends a request pending memory becoming available then the FS must ensure that the library stays loaded until the IRP is completed. Change-Id: Idbfdd84ecd364c99d3ad9cd8dd7e000f47be4b58 Reviewed-on: http://gerrit.openafs.org/9126 Reviewed-by: Rod Widdowson Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp index db85d9dd1..a9962625b 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp @@ -1327,6 +1327,11 @@ AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject, // Set the completion routine. // + AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "Setting AFSIrpComplete as IoCompletion Routine Irp %p\n", + pIrp); + IoSetCompletionRoutine( pIrp, AFSIrpComplete, &kEvent, diff --git a/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp b/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp index 342058765..1ada0128f 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp @@ -38,12 +38,22 @@ #include "AFSCommon.h" + +static +NTSTATUS +AFSWriteComplete( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Contxt); + // // Function: AFSWrite // // Description: // -// This is the dispatch handler for the IRP_MJ_WRITE request +// This is the dispatch handler for the IRP_MJ_WRITE request. Since we want to +// allow the library to pend the write we need to lock the library for the +// duration of the thread calling the library but also for the life of the IRP. +// So this code path establishes an IO completion function. // // Return: // @@ -84,19 +94,54 @@ AFSWrite( IN PDEVICE_OBJECT DeviceObject, if( ntStatus != STATUS_PENDING) { + + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + // + // Increment the outstanding IO count again - this time for the + // completion routine. + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + AFSClearLibraryRequest(); + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); } try_return( ntStatus); } - IoSkipCurrentIrpStackLocation( Irp); + // + // And send it down, but arrange to capture the comletion + // so we can free our lock against unloading. + // + + IoCopyCurrentIrpStackLocationToNext( Irp); + + AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "Setting AFSWriteComplete as IoCompletion Routine Irp %p\n", + Irp); + + IoSetCompletionRoutine( Irp, AFSWriteComplete, NULL, TRUE, TRUE, TRUE); ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, Irp); // - // Indicate the library is done with the request + // Indicate the library/thread pair is done with the request // AFSClearLibraryRequest(); @@ -115,3 +160,39 @@ try_exit: return ntStatus; } + +// +// AFSWriteComplete +// +static +NTSTATUS +AFSWriteComplete( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Irp); + UNREFERENCED_PARAMETER(Context); + BOOLEAN bPending = FALSE; + + // + // Indicate the library/IRP pair is done with the request + // + + AFSClearLibraryRequest(); + + if (Irp->PendingReturned) { + + bPending = TRUE; + + IoMarkIrpPending(Irp); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSWriteComplete Irp %p%s\n", + Irp, + bPending ? " PENDING" : ""); + + return STATUS_CONTINUE_COMPLETION; +}