From 3658aa350d7b63944a96dc3e5d14b1a4cdb94b50 Mon Sep 17 00:00:00 2001 From: Dominique Cote Date: Sun, 21 Jan 2007 04:46:38 +0000 Subject: [PATCH] =================================================================== cctypes.h ntoskrnl/cc/copy.c =================================================================== Added CcFastMdlReadNotPossible =================================================================== fastio.c =================================================================== Added #ifdef to allow the file to compile "as is" in my windows framework. This doesnt affect RosBE Brought back Alex's code for FsRtlMdlReadCompleteDev FsRtlMdlReadDev FsRtlMdlReadComplete after having code reviewed it. =================================================================== ntoskrnl/include/internal/cc.h ntoskrnl/cc/mdl.c =================================================================== Change the name of CcMdlReadCompleteDev to CcMdlReadComplete2 svn path=/trunk/; revision=25550 --- reactos/include/ndk/cctypes.h | 1 + reactos/ntoskrnl/cc/copy.c | 2 +- reactos/ntoskrnl/cc/mdl.c | 8 +- reactos/ntoskrnl/fsrtl/fastio.c | 163 +++++++++++++++++++++++-- reactos/ntoskrnl/include/internal/cc.h | 4 +- 5 files changed, 159 insertions(+), 19 deletions(-) diff --git a/reactos/include/ndk/cctypes.h b/reactos/include/ndk/cctypes.h index 5f57e1cba66..572b3668e45 100644 --- a/reactos/include/ndk/cctypes.h +++ b/reactos/include/ndk/cctypes.h @@ -33,6 +33,7 @@ extern ULONG NTSYSAPI CcFastReadNotPossible; extern ULONG NTSYSAPI CcFastReadWait; extern ULONG NTSYSAPI CcFastReadResourceMiss; extern ULONG NTSYSAPI CcFastReadNoWait; +extern ULONG NTSYSAPI CcFastMdlReadNotPossible; #ifdef _NTIFS_INCLUDED_ diff --git a/reactos/ntoskrnl/cc/copy.c b/reactos/ntoskrnl/cc/copy.c index 1faec95eb9e..20319ed5273 100644 --- a/reactos/ntoskrnl/cc/copy.c +++ b/reactos/ntoskrnl/cc/copy.c @@ -30,12 +30,12 @@ void* _alloca(size_t size); #endif ULONG CcFastMdlReadWait; +ULONG CcFastMdlReadNotPossible; ULONG CcFastReadNotPossible; ULONG CcFastReadWait; ULONG CcFastReadNoWait; ULONG CcFastReadResourceMiss; - /* FUNCTIONS *****************************************************************/ VOID diff --git a/reactos/ntoskrnl/cc/mdl.c b/reactos/ntoskrnl/cc/mdl.c index 7e91d707c4a..79242f926ce 100644 --- a/reactos/ntoskrnl/cc/mdl.c +++ b/reactos/ntoskrnl/cc/mdl.c @@ -51,15 +51,15 @@ CcMdlRead( */ VOID STDCALL -CcMdlReadCompleteDev(IN PMDL MdlChain, +CcMdlReadComplete2(IN PMDL MemoryDescriptorList, IN PFILE_OBJECT FileObject) { PMDL Mdl; /* Free MDLs */ - while ((Mdl = MdlChain)) + while ((Mdl = MemoryDescriptorList)) { - MdlChain = Mdl->Next; + MemoryDescriptorList = Mdl->Next; MmUnlockPages(Mdl); IoFreeMdl(Mdl); } @@ -103,7 +103,7 @@ CcMdlReadComplete(IN PFILE_OBJECT FileObject, } /* Use slow path */ - CcMdlReadCompleteDev(MdlChain, FileObject); + CcMdlReadComplete2(MdlChain, FileObject); } /* diff --git a/reactos/ntoskrnl/fsrtl/fastio.c b/reactos/ntoskrnl/fsrtl/fastio.c index 644d66717ff..4c446594ff2 100644 --- a/reactos/ntoskrnl/fsrtl/fastio.c +++ b/reactos/ntoskrnl/fsrtl/fastio.c @@ -8,11 +8,18 @@ /* INCLUDES ******************************************************************/ +#ifdef _WINDOWS_TESTING +#include +#include "ntndk.h" +#include "fsrtl_glue.h" +#else #include #define NDEBUG #include #include #include +#endif /* _WINDOWS_TESTING */ + /* PUBLIC FUNCTIONS **********************************************************/ @@ -708,31 +715,57 @@ FsRtlMdlRead(IN PFILE_OBJECT FileObject, return FALSE; } -/* - * @implemented - */ BOOLEAN NTAPI FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, IN OUT PMDL MdlChain) { - KEBUGCHECK(0); - return FALSE; + PDEVICE_OBJECT DeviceObject, BaseDeviceObject; + PFAST_IO_DISPATCH FastDispatch; + + /* Get Device Object and Fast Calls */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + FastDispatch = DeviceObject->DriverObject->FastIoDispatch; + + /* Check if we support Fast Calls, and check this one */ + if (FastDispatch && FastDispatch->MdlReadComplete) + { + /* Use the fast path */ + return FastDispatch->MdlReadComplete(FileObject, + MdlChain, + DeviceObject); + } + + /* Get the Base File System (Volume) and Fast Calls */ + BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject); + FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; + + /* If the Base Device Object has its own FastDispatch Routine, fail */ + if ((BaseDeviceObject != DeviceObject) && FastDispatch + && FastDispatch->MdlReadComplete) + { + return FALSE; + } + + /* No fast path, use slow path */ + return FsRtlMdlReadCompleteDev(FileObject, MdlChain, DeviceObject); } /* * @implemented */ -BOOLEAN -NTAPI + BOOLEAN + NTAPI FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, - IN PMDL MdlChain, + IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject) { - KEBUGCHECK(0); - return FALSE; + /* Call the Cache Manager */ + CcMdlReadComplete2(MemoryDescriptorList, FileObject); + return TRUE; } + /* * @implemented */ @@ -746,8 +779,114 @@ FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) { - KEBUGCHECK(0); - return FALSE; + PFSRTL_COMMON_FCB_HEADER FcbHeader; + BOOLEAN Result = TRUE; + LARGE_INTEGER Offset; + PFAST_IO_DISPATCH FastIoDispatch; + PDEVICE_OBJECT Device; + PAGED_CODE(); + + /* No actual read */ + if (!Length) + { + /* Return success */ + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = 0; + return TRUE; + } + + /* Sanity check */ + ASSERT(MAXLONGLONG - FileOffset->QuadPart >= (LONGLONG)Length); + + /* Get the offset and FCB header */ + Offset.QuadPart = FileOffset->QuadPart + Length; + FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; + + /* Enter the FS */ + FsRtlEnterFileSystem(); + CcFastMdlReadWait++; + + /* Lock the FCB */ + ExAcquireResourceShared(FcbHeader->Resource, TRUE); + + /* Check if this is a fast I/O cached file */ + if (!(FileObject->PrivateCacheMap) || + (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) + { + /* It's not, so fail */ + CcFastMdlReadNotPossible += 1; + Result = FALSE; + goto Cleanup; + } + + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; + + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffset, + Length, + TRUE, + LockKey, + TRUE, + IoStatus, + Device)) + { + /* It's not, fail */ + CcFastMdlReadNotPossible += 1; + Result = FALSE; + goto Cleanup; + } + } + + /* Check if we read too much */ + if (Offset.QuadPart > FcbHeader->FileSize.QuadPart) + { + /* We did, check if the file offset is past the end */ + if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart) + { + /* Set end of file */ + IoStatus->Status = STATUS_END_OF_FILE; + IoStatus->Information = 0; + goto Cleanup; + } + + /* Otherwise, just normalize the length */ + Length = (ULONG)(FcbHeader->FileSize.QuadPart - FileOffset->QuadPart); + } + + /* Set this as top-level IRP */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + + _SEH_TRY + { + /* Attempt a read */ + CcMdlRead(FileObject, FileOffset, Length, MdlChain, IoStatus); + FileObject->Flags |= FO_FILE_FAST_IO_READ; + } + _SEH_EXCEPT(FsRtlCcCopyFilter) + { + Result = FALSE; + } _SEH_END; + + + /* Remove the top-level IRP flag */ + PsGetCurrentThread()->TopLevelIrp = 0; + + /* Return to caller */ +Cleanup: + ExReleaseResourceLite(FcbHeader->Resource); + FsRtlExitFileSystem(); + return Result; } /* diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index db19b69f7a9..bdd0c14c464 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -63,8 +63,8 @@ typedef struct _INTERNAL_BCB VOID NTAPI -CcMdlReadCompleteDev( - IN PMDL MdlChain, +CcMdlReadComplete2( + IN PMDL MemoryDescriptorList, IN PFILE_OBJECT FileObject );