mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[NTOS:IO]
- Implement Fast I/O support in NtReadFile/NtWriteFile CORE-9624 svn path=/trunk/; revision=67494
This commit is contained in:
parent
68defa9dd4
commit
e03d4423da
|
@ -2255,6 +2255,10 @@ NtReadFile(IN HANDLE FileHandle,
|
|||
ULONG CapturedKey = 0;
|
||||
BOOLEAN Synchronous = FALSE;
|
||||
PMDL Mdl;
|
||||
PFAST_IO_DISPATCH FastIoDispatch;
|
||||
IO_STATUS_BLOCK KernelIosb;
|
||||
BOOLEAN Success;
|
||||
|
||||
PAGED_CODE();
|
||||
CapturedByteOffset.QuadPart = 0;
|
||||
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
|
||||
|
@ -2324,13 +2328,16 @@ NtReadFile(IN HANDLE FileHandle,
|
|||
KeClearEvent(EventObject);
|
||||
}
|
||||
|
||||
/* Get the device object */
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
/* Check if we should use Sync IO or not */
|
||||
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||
{
|
||||
/* Lock the file object */
|
||||
IopLockFileObject(FileObject);
|
||||
|
||||
/* Check if we don't have a byte offset avilable */
|
||||
/* Check if we don't have a byte offset available */
|
||||
if (!(ByteOffset) ||
|
||||
((CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION) &&
|
||||
(CapturedByteOffset.u.HighPart == -1)))
|
||||
|
@ -2339,6 +2346,61 @@ NtReadFile(IN HANDLE FileHandle,
|
|||
CapturedByteOffset = FileObject->CurrentByteOffset;
|
||||
}
|
||||
|
||||
/* If the file is cached, try fast I/O */
|
||||
if (FileObject->PrivateCacheMap)
|
||||
{
|
||||
/* Perform fast write */
|
||||
FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||
Success = FastIoDispatch->FastIoRead(FileObject,
|
||||
&CapturedByteOffset,
|
||||
Length,
|
||||
TRUE,
|
||||
CapturedKey,
|
||||
Buffer,
|
||||
&KernelIosb,
|
||||
DeviceObject);
|
||||
|
||||
/* Only accept the result if we got a straightforward status */
|
||||
if (Success &&
|
||||
(KernelIosb.Status == STATUS_SUCCESS ||
|
||||
KernelIosb.Status == STATUS_BUFFER_OVERFLOW ||
|
||||
KernelIosb.Status == STATUS_END_OF_FILE))
|
||||
{
|
||||
/* Fast path -- update transfer & operation counts */
|
||||
IopUpdateOperationCount(IopReadTransfer);
|
||||
IopUpdateTransferCount(IopReadTransfer,
|
||||
(ULONG)KernelIosb.Information);
|
||||
|
||||
/* Enter SEH to write the IOSB back */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Write it back to the caller */
|
||||
*IoStatusBlock = KernelIosb;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* The caller's IOSB was invalid, so fail */
|
||||
if (EventObject) ObDereferenceObject(EventObject);
|
||||
IopUnlockFileObject(FileObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Signal the completion event */
|
||||
if (EventObject)
|
||||
{
|
||||
KeSetEvent(EventObject, 0, FALSE);
|
||||
ObDereferenceObject(EventObject);
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
IopUnlockFileObject(FileObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return KernelIosb.Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember we are sync */
|
||||
Synchronous = TRUE;
|
||||
}
|
||||
|
@ -2351,9 +2413,6 @@ NtReadFile(IN HANDLE FileHandle,
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Get the device object */
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
/* Clear the File Object's event */
|
||||
KeClearEvent(&FileObject->Event);
|
||||
|
||||
|
@ -3150,6 +3209,10 @@ NtWriteFile(IN HANDLE FileHandle,
|
|||
BOOLEAN Synchronous = FALSE;
|
||||
PMDL Mdl;
|
||||
OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
|
||||
PFAST_IO_DISPATCH FastIoDispatch;
|
||||
IO_STATUS_BLOCK KernelIosb;
|
||||
BOOLEAN Success;
|
||||
|
||||
PAGED_CODE();
|
||||
CapturedByteOffset.QuadPart = 0;
|
||||
IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
|
||||
|
@ -3244,13 +3307,16 @@ NtWriteFile(IN HANDLE FileHandle,
|
|||
KeClearEvent(EventObject);
|
||||
}
|
||||
|
||||
/* Get the device object */
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
/* Check if we should use Sync IO or not */
|
||||
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||
{
|
||||
/* Lock the file object */
|
||||
IopLockFileObject(FileObject);
|
||||
|
||||
/* Check if we don't have a byte offset avilable */
|
||||
/* Check if we don't have a byte offset available */
|
||||
if (!(ByteOffset) ||
|
||||
((CapturedByteOffset.u.LowPart == FILE_USE_FILE_POINTER_POSITION) &&
|
||||
(CapturedByteOffset.u.HighPart == -1)))
|
||||
|
@ -3259,6 +3325,59 @@ NtWriteFile(IN HANDLE FileHandle,
|
|||
CapturedByteOffset = FileObject->CurrentByteOffset;
|
||||
}
|
||||
|
||||
/* If the file is cached, try fast I/O */
|
||||
if (FileObject->PrivateCacheMap)
|
||||
{
|
||||
/* Perform fast read */
|
||||
FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||
Success = FastIoDispatch->FastIoWrite(FileObject,
|
||||
&CapturedByteOffset,
|
||||
Length,
|
||||
TRUE,
|
||||
CapturedKey,
|
||||
Buffer,
|
||||
&KernelIosb,
|
||||
DeviceObject);
|
||||
|
||||
/* Only accept the result if it was successful */
|
||||
if (Success &&
|
||||
KernelIosb.Status == STATUS_SUCCESS)
|
||||
{
|
||||
/* Fast path -- update transfer & operation counts */
|
||||
IopUpdateOperationCount(IopWriteTransfer);
|
||||
IopUpdateTransferCount(IopWriteTransfer,
|
||||
(ULONG)KernelIosb.Information);
|
||||
|
||||
/* Enter SEH to write the IOSB back */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Write it back to the caller */
|
||||
*IoStatusBlock = KernelIosb;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* The caller's IOSB was invalid, so fail */
|
||||
if (EventObject) ObDereferenceObject(EventObject);
|
||||
IopUnlockFileObject(FileObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Signal the completion event */
|
||||
if (EventObject)
|
||||
{
|
||||
KeSetEvent(EventObject, 0, FALSE);
|
||||
ObDereferenceObject(EventObject);
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
IopUnlockFileObject(FileObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return KernelIosb.Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember we are sync */
|
||||
Synchronous = TRUE;
|
||||
}
|
||||
|
@ -3271,9 +3390,6 @@ NtWriteFile(IN HANDLE FileHandle,
|
|||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Get the device object */
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
/* Clear the File Object's event */
|
||||
KeClearEvent(&FileObject->Event);
|
||||
|
||||
|
|
Loading…
Reference in a new issue