Author: pschweitzer
Date: Sat Nov 26 22:39:08 2016
New Revision: 73384
URL:
http://svn.reactos.org/svn/reactos?rev=73384&view=rev
Log:
[NTOSKRNL]
A hack has gained enough XP and levels up! Congratulations to the MmCreateSection() in
charge of forcing file cache initialization.
As show by kmtest:NtCreateSection tests and real world FSD (starting with MS FastFAT and
Ext2Fsd), caching of a file can be initialized rather late (ie, on first effective
read/write).
That means that our current hack is totally opless on newly created files with 0-size
where the IRP_MJ_READ is most of the time opless too.
The hack, thanks to its level up, can now force a write (1-byte) in case read was
unsuccessful and end of file.
In other words, this is the hack of a hack (and a hack v2).
It fixes a few failing kmtests.
Thomas, Peter, please retry the FSDs on which you are currently working on and report.
Thanks :-)
CORE-11819
CORE-12475
Modified:
trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/mm/section.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Sat Nov 26 22:39:08 2016
@@ -2909,9 +2909,6 @@
PFILE_OBJECT FileObject;
PMM_SECTION_SEGMENT Segment;
ULONG FileAccess;
- IO_STATUS_BLOCK Iosb;
- LARGE_INTEGER Offset;
- CHAR Buffer;
FILE_STANDARD_INFORMATION FileInfo;
ULONG Length;
@@ -2967,7 +2964,6 @@
sizeof(FILE_STANDARD_INFORMATION),
&FileInfo,
&Length);
- Iosb.Information = Length;
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Section);
@@ -3012,35 +3008,9 @@
if (FileObject->SectionObjectPointer == NULL ||
FileObject->SectionObjectPointer->SharedCacheMap == NULL)
{
- /*
- * Read a bit so caching is initiated for the file object.
- * This is only needed because MiReadPage currently cannot
- * handle non-cached streams.
- */
- Offset.QuadPart = 0;
- Status = ZwReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- &Buffer,
- sizeof (Buffer),
- &Offset,
- 0);
- if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
- {
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return(Status);
- }
- if (FileObject->SectionObjectPointer == NULL ||
- FileObject->SectionObjectPointer->SharedCacheMap == NULL)
- {
- /* FIXME: handle this situation */
- ObDereferenceObject(Section);
- ObDereferenceObject(FileObject);
- return STATUS_INVALID_FILE_FOR_SECTION;
- }
+ ObDereferenceObject(Section);
+ ObDereferenceObject(FileObject);
+ return STATUS_INVALID_FILE_FOR_SECTION;
}
/*
@@ -3836,10 +3806,19 @@
if(ImageSectionObject->Segments != NULL)
ExFreePool(ImageSectionObject->Segments);
+ /*
+ * If image file is empty, then return that the file is invalid for section
+ */
+ Status = StatusExeFmt;
+ if (StatusExeFmt == STATUS_END_OF_FILE)
+ {
+ Status = STATUS_INVALID_FILE_FOR_SECTION;
+ }
+
ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
- return(StatusExeFmt);
+ return(Status);
}
Section->ImageSection = ImageSectionObject;
@@ -5101,6 +5080,33 @@
return Status;
}
// Caching is initialized...
+
+ // Hack of the hack: actually, it might not be initialized if FSD init on
effective right and if file is null-size
+ // In such case, force cache by initiating a write IRP
+ if (Status == STATUS_END_OF_FILE && !(AllocationAttributes &
SEC_IMAGE) && FileObject != NULL &&
+ (FileObject->SectionObjectPointer == NULL ||
FileObject->SectionObjectPointer->SharedCacheMap == NULL))
+ {
+ Status = ZwWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ &Buffer,
+ sizeof(Buffer),
+ &ByteOffset,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ LARGE_INTEGER Zero;
+ Zero.QuadPart = 0LL;
+
+ Status = IoSetInformation(FileObject,
+ FileEndOfFileInformation,
+ sizeof(LARGE_INTEGER),
+ &Zero);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ }
}
#endif