Author: pschweitzer
Date: Mon May 18 19:47:11 2015
New Revision: 67822
URL:
http://svn.reactos.org/svn/reactos?rev=67822&view=rev
Log:
[NTOSKRNL]
Implement FastIO support for:
- NtFsControlFile()
- NtLockFile()
- NtUnlockFile()
- NtQueryInformationFile()
Modified:
trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/iofunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iofunc.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iofunc.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iofunc.c [iso-8859-1] Mon May 18 19:47:11 2015
@@ -1,11 +1,12 @@
/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/io/iofunc.c
+ * FILE: ntoskrnl/io/iomgr/iofunc.c
* PURPOSE: Generic I/O Functions that build IRPs for various operations
* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
* Gunnar Dalsnes
* Filip Navara (navaraf(a)reactos.org)
+ * Pierre Schweitzer (pierre(a)reactos.org)
*/
/* INCLUDES *****************************************************************/
@@ -339,6 +340,113 @@
{
/* Otherwise get the related device */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ }
+
+ /* If that's FS I/O, try to do it with FastIO path */
+ if (!IsDevIoCtl)
+ {
+ PFAST_IO_DISPATCH FastIoDispatch =
DeviceObject->DriverObject->FastIoDispatch;
+
+ /* Check whether FSD is FastIO aware and provide an appropriate routine */
+ if (FastIoDispatch != NULL && FastIoDispatch->FastIoDeviceControl !=
NULL)
+ {
+ IO_STATUS_BLOCK KernelIosb;
+
+ /* If we have an output buffer coming from usermode */
+ if (PreviousMode != KernelMode && OutputBuffer != NULL)
+ {
+ /* Probe it according to its usage */
+ _SEH2_TRY
+ {
+ if (AccessType == METHOD_IN_DIRECT)
+ {
+ ProbeForRead(OutputBuffer, OutputBufferLength, sizeof(CHAR));
+ }
+ else if (AccessType == METHOD_OUT_DIRECT)
+ {
+ ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(CHAR));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Cleanup after exception and return */
+ IopCleanupAfterException(FileObject, NULL, EventObject, NULL);
+
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+
+ /* If we're to dismount a volume, increaase the dismount count */
+ if (IoControlCode == FSCTL_DISMOUNT_VOLUME)
+ {
+ InterlockedExchangeAdd((PLONG)&SharedUserData->DismountCount, 1);
+ }
+
+ /* Call the FSD */
+ if (FastIoDispatch->FastIoDeviceControl(FileObject,
+ TRUE,
+ InputBuffer,
+ InputBufferLength,
+ OutputBuffer,
+ OutputBufferLength,
+ IoControlCode,
+ &KernelIosb,
+ DeviceObject))
+ {
+ IO_COMPLETION_CONTEXT CompletionInfo = { NULL, NULL };
+
+ /* Write the IOSB back */
+ _SEH2_TRY
+ {
+ *IoStatusBlock = KernelIosb;
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ KernelIosb.Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Backup our complete context in case it exists */
+ if (FileObject->CompletionContext)
+ {
+ CompletionInfo = *(FileObject->CompletionContext);
+ }
+
+ /* If we had an event, signal it */
+ if (Event)
+ {
+ KeSetEvent(EventObject, IO_NO_INCREMENT, FALSE);
+ ObDereferenceObject(EventObject);
+ }
+
+ /* If FO was locked, unlock it */
+ if (LockedForSynch)
+ {
+ IopUnlockFileObject(FileObject);
+ }
+
+ /* Set completion if required */
+ if (CompletionInfo.Port != NULL && UserApcContext != NULL)
+ {
+ if (!NT_SUCCESS(IoSetIoCompletion(CompletionInfo.Port,
+ CompletionInfo.Key,
+ UserApcContext,
+ KernelIosb.Status,
+ KernelIosb.Information,
+ TRUE)))
+ {
+ KernelIosb.Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ /* We're done with FastIO! */
+ ObDereferenceObject(FileObject);
+ return KernelIosb.Status;
+ }
+ }
}
/* Clear the event */
@@ -1491,6 +1599,7 @@
LARGE_INTEGER CapturedByteOffset, CapturedLength;
NTSTATUS Status;
OBJECT_HANDLE_INFORMATION HandleInformation;
+ PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
CapturedByteOffset.QuadPart = 0;
CapturedLength.QuadPart = 0;
@@ -1557,6 +1666,62 @@
/* Get the device object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ /* Try to do it the FastIO way if possible */
+ FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
+ if (FastIoDispatch != NULL && FastIoDispatch->FastIoLock != NULL)
+ {
+ IO_STATUS_BLOCK KernelIosb;
+
+ if (FastIoDispatch->FastIoLock(FileObject,
+ &CapturedByteOffset,
+ &CapturedLength,
+ PsGetCurrentProcess(),
+ Key,
+ FailImmediately,
+ ExclusiveLock,
+ &KernelIosb,
+ DeviceObject))
+ {
+ /* Write the IOSB back */
+ _SEH2_TRY
+ {
+ *IoStatusBlock = KernelIosb;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ KernelIosb.Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* If we had an event, signal it */
+ if (EventHandle)
+ {
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+ ObDereferenceObject(Event);
+ }
+
+ /* Set completion if required */
+ if (FileObject->CompletionContext != NULL && ApcContext != NULL)
+ {
+ if
(!NT_SUCCESS(IoSetIoCompletion(FileObject->CompletionContext->Port,
+
FileObject->CompletionContext->Key,
+ ApcContext,
+ KernelIosb.Status,
+ KernelIosb.Information,
+ TRUE)))
+ {
+ KernelIosb.Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ FileObject->LockOperation = TRUE;
+
+ /* We're done with FastIO! */
+ ObDereferenceObject(FileObject);
+ return KernelIosb.Status;
+ }
+ }
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
@@ -1897,6 +2062,7 @@
PFILE_MODE_INFORMATION ModeBuffer;
PFILE_ALIGNMENT_INFORMATION AlignmentBuffer;
PFILE_ALL_INFORMATION AllBuffer;
+ PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
@@ -2018,6 +2184,52 @@
}
KeInitializeEvent(Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
+ }
+
+ /* Check if FastIO is possible for the two available information classes */
+ FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
+ if (FastIoDispatch != NULL &&
+ ((FileInformationClass == FileBasicInformation &&
FastIoDispatch->FastIoQueryBasicInfo != NULL) ||
+ (FileInformationClass == FileStandardInformation &&
FastIoDispatch->FastIoQueryStandardInfo != NULL)))
+ {
+ BOOLEAN Success = FALSE;
+
+ if (FileInformationClass == FileBasicInformation)
+ {
+ Success = FastIoDispatch->FastIoQueryBasicInfo(FileObject, TRUE,
+ FileInformation,
+ &KernelIosb,
+ DeviceObject);
+ }
+ else
+ {
+ Success = FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE,
+ FileInformation,
+ &KernelIosb,
+ DeviceObject);
+ }
+
+ /* If call succeed */
+ if (Success)
+ {
+ /* Write the IOSB back */
+ _SEH2_TRY
+ {
+ *IoStatusBlock = KernelIosb;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ KernelIosb.Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Unlock FO */
+ IopUnlockFileObject(FileObject);
+
+ /* We're done with FastIO! */
+ ObDereferenceObject(FileObject);
+ return KernelIosb.Status;
+ }
}
/* Clear the File Object event */
@@ -2668,6 +2880,9 @@
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
+ DPRINT("Will call: %p\n", DeviceObject);
+ DPRINT("Associated driver: %p (%wZ)\n", DeviceObject->DriverObject,
&DeviceObject->DriverObject->DriverName);
+
/* Check if this is a file that was opened for Synch I/O */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
@@ -3028,6 +3243,7 @@
NTSTATUS Status;
OBJECT_HANDLE_INFORMATION HandleInformation;
IO_STATUS_BLOCK KernelIosb;
+ PFAST_IO_DISPATCH FastIoDispatch;
PAGED_CODE();
CapturedByteOffset.QuadPart = 0;
CapturedLength.QuadPart = 0;
@@ -3086,6 +3302,35 @@
else
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ }
+
+ /* Try to do it the FastIO way if possible */
+ FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
+ if (FastIoDispatch != NULL && FastIoDispatch->FastIoUnlockSingle != NULL)
+ {
+ if (FastIoDispatch->FastIoUnlockSingle(FileObject,
+ &CapturedByteOffset,
+ &CapturedLength,
+ PsGetCurrentProcess(),
+ Key,
+ &KernelIosb,
+ DeviceObject))
+ {
+ /* Write the IOSB back */
+ _SEH2_TRY
+ {
+ *IoStatusBlock = KernelIosb;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ KernelIosb.Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* We're done with FastIO! */
+ ObDereferenceObject(FileObject);
+ return KernelIosb.Status;
+ }
}
/* Check if we should use Sync IO or not */