mirror of
https://github.com/reactos/reactos.git
synced 2025-01-20 18:44:09 +08:00
[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 svn path=/trunk/; revision=73384
This commit is contained in:
parent
89c3520c86
commit
3ff70dc5d5
@ -2909,9 +2909,6 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
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 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
sizeof(FILE_STANDARD_INFORMATION),
|
||||
&FileInfo,
|
||||
&Length);
|
||||
Iosb.Information = Length;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(Section);
|
||||
@ -3012,35 +3008,9 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
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 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
|
||||
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 @@ MmCreateSection (OUT PVOID * Section,
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user