mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:33:01 +00:00
* Use the cache for images where the section offset is not page
alligned in MiReadPage. * Removed a wrong call to MmReferencePage in MmPageOutSectionView. * Fixed the length in MmAlterViewAttributes. * Wait for releasing of the pageop in MmFreeSectionPage. * Fixed some wrong return values in MmMapViewOfSection. svn path=/trunk/; revision=3706
This commit is contained in:
parent
9c17318aff
commit
95b7092276
1 changed files with 92 additions and 38 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: section.c,v 1.99 2002/10/01 19:27:24 chorns Exp $
|
/* $Id: section.c,v 1.100 2002/11/05 20:50:02 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -318,12 +318,13 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
* Page - Variable that receives a page contains the read data.
|
* Page - Variable that receives a page contains the read data.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatus;
|
ULONG BaseOffset;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
BOOLEAN UptoDate;
|
||||||
|
PCACHE_SEGMENT CacheSeg;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PMDL Mdl;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PREACTOS_COMMON_FCB_HEADER Fcb;
|
PREACTOS_COMMON_FCB_HEADER Fcb;
|
||||||
KEVENT Event;
|
|
||||||
|
|
||||||
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
||||||
Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
|
Fcb = (PREACTOS_COMMON_FCB_HEADER)FileObject->FsContext;
|
||||||
|
@ -336,10 +337,6 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
|
if (FileObject->Flags & FO_DIRECT_CACHE_PAGING_READ &&
|
||||||
(Offset->QuadPart % PAGE_SIZE) == 0)
|
(Offset->QuadPart % PAGE_SIZE) == 0)
|
||||||
{
|
{
|
||||||
ULONG BaseOffset;
|
|
||||||
PVOID BaseAddress;
|
|
||||||
BOOLEAN UptoDate;
|
|
||||||
PCACHE_SEGMENT CacheSeg;
|
|
||||||
PHYSICAL_ADDRESS Addr;
|
PHYSICAL_ADDRESS Addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -348,7 +345,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
* alignment less than the file system block size.
|
* alignment less than the file system block size.
|
||||||
*/
|
*/
|
||||||
Status = CcRosGetCacheSegment(Fcb->Bcb,
|
Status = CcRosGetCacheSegment(Fcb->Bcb,
|
||||||
(ULONG)Offset->QuadPart,
|
Offset->u.LowPart,
|
||||||
&BaseOffset,
|
&BaseOffset,
|
||||||
&BaseAddress,
|
&BaseAddress,
|
||||||
&UptoDate,
|
&UptoDate,
|
||||||
|
@ -366,6 +363,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
Status = ReadCacheSegment(CacheSeg);
|
Status = ReadCacheSegment(CacheSeg);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,15 +371,16 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
* Retrieve the page from the cache segment that we actually want.
|
* Retrieve the page from the cache segment that we actually want.
|
||||||
*/
|
*/
|
||||||
Addr = MmGetPhysicalAddress(BaseAddress +
|
Addr = MmGetPhysicalAddress(BaseAddress +
|
||||||
Offset->QuadPart - BaseOffset);
|
Offset->u.LowPart - BaseOffset);
|
||||||
(*Page) = Addr;
|
(*Page) = Addr;
|
||||||
MmReferencePage((*Page));
|
MmReferencePage((*Page));
|
||||||
|
|
||||||
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
PVOID PageAddr;
|
||||||
|
ULONG OffsetInPage;
|
||||||
/*
|
/*
|
||||||
* Allocate a page, this is rather complicated by the possibility
|
* Allocate a page, this is rather complicated by the possibility
|
||||||
* we might have to move other things out of memory
|
* we might have to move other things out of memory
|
||||||
|
@ -392,28 +391,70 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Status = CcRosGetCacheSegment(Fcb->Bcb,
|
||||||
* Create an mdl to hold the page we are going to read data into.
|
Offset->u.LowPart,
|
||||||
*/
|
&BaseOffset,
|
||||||
Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
|
&BaseAddress,
|
||||||
MmBuildMdlFromPages(Mdl, &Page->u.LowPart);
|
&UptoDate,
|
||||||
/*
|
&CacheSeg);
|
||||||
* Call the FSD to read the page
|
if (!NT_SUCCESS(Status))
|
||||||
*/
|
|
||||||
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
|
||||||
Status = IoPageRead(FileObject,
|
|
||||||
Mdl,
|
|
||||||
Offset,
|
|
||||||
&Event,
|
|
||||||
&IoStatus);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
return(IoStatus.Status);
|
|
||||||
}
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
if (!UptoDate)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the cache segment isn't up to date then call the file
|
||||||
|
* system to read in the data.
|
||||||
|
*/
|
||||||
|
Status = ReadCacheSegment(CacheSeg);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PageAddr = ExAllocatePageWithPhysPage(*Page);
|
||||||
|
OffsetInPage = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - Offset->u.LowPart;
|
||||||
|
if (OffsetInPage >= PAGE_SIZE)
|
||||||
|
{
|
||||||
|
memcpy(PageAddr, BaseAddress + Offset->u.LowPart - BaseOffset, PAGE_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(PageAddr, BaseAddress + Offset->u.LowPart - BaseOffset, OffsetInPage);
|
||||||
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
||||||
|
Status = CcRosGetCacheSegment(Fcb->Bcb,
|
||||||
|
Offset->u.LowPart + OffsetInPage,
|
||||||
|
&BaseOffset,
|
||||||
|
&BaseAddress,
|
||||||
|
&UptoDate,
|
||||||
|
&CacheSeg);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExUnmapPage(PageAddr);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
if (!UptoDate)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the cache segment isn't up to date then call the file
|
||||||
|
* system to read in the data.
|
||||||
|
*/
|
||||||
|
Status = ReadCacheSegment(CacheSeg);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE);
|
||||||
|
ExUnmapPage(PageAddr);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(PageAddr + OffsetInPage, BaseAddress, PAGE_SIZE - OffsetInPage);
|
||||||
|
}
|
||||||
|
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, FALSE);
|
||||||
|
ExUnmapPage(PageAddr);
|
||||||
|
}
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -558,7 +599,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
MemoryArea->Attributes,
|
||||||
Page,
|
Page,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1253,7 +1294,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Take an additional reference to the page.
|
* Take an additional reference to the page.
|
||||||
*/
|
*/
|
||||||
MmReferencePage(PhysicalAddress);
|
// MmReferencePage(PhysicalAddress);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Paging out data mapped read-only is easy.
|
* Paging out data mapped read-only is easy.
|
||||||
|
@ -1680,7 +1721,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
if (OldProtect != NewProtect)
|
if (OldProtect != NewProtect)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (RegionSize / PAGE_SIZE); i++)
|
for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
PVOID Address = BaseAddress + (i * PAGE_SIZE);
|
PVOID Address = BaseAddress + (i * PAGE_SIZE);
|
||||||
ULONG Protect = NewProtect;
|
ULONG Protect = NewProtect;
|
||||||
|
@ -2873,6 +2914,19 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
|
|
||||||
PageOp = MmCheckForPageOp(MArea, 0, NULL, MArea->Data.SectionData.Segment,
|
PageOp = MmCheckForPageOp(MArea, 0, NULL, MArea->Data.SectionData.Segment,
|
||||||
Offset);
|
Offset);
|
||||||
|
|
||||||
|
if (PageOp)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&PageOp->CompletionEvent,
|
||||||
|
0,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
PageOp = MmCheckForPageOp(MArea, 0, NULL, MArea->Data.SectionData.Segment,
|
||||||
|
Offset);
|
||||||
|
}
|
||||||
|
|
||||||
assert(PageOp == NULL);
|
assert(PageOp == NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3189,7 +3243,7 @@ MmAllocateSection (IN ULONG Length)
|
||||||
}
|
}
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
DPRINT("Result %p\n",Result);
|
DPRINT("Result %p\n",Result);
|
||||||
for (i = 0; (i <= (Length / PAGE_SIZE)); i++)
|
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PHYSICAL_ADDRESS Page;
|
||||||
|
|
||||||
|
@ -3310,22 +3364,22 @@ MmMapViewOfSection(IN PVOID SectionObject,
|
||||||
|
|
||||||
/* Check there is enough space to map the section at that point. */
|
/* Check there is enough space to map the section at that point. */
|
||||||
if (MmOpenMemoryAreaByRegion(AddressSpace, ImageBase,
|
if (MmOpenMemoryAreaByRegion(AddressSpace, ImageBase,
|
||||||
ImageSize) != NULL)
|
PAGE_ROUND_UP(ImageSize)) != NULL)
|
||||||
{
|
{
|
||||||
/* Fail if the user requested a fixed base address. */
|
/* Fail if the user requested a fixed base address. */
|
||||||
if ((*BaseAddress) != NULL)
|
if ((*BaseAddress) != NULL)
|
||||||
{
|
{
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return(Status);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
/* Otherwise find a gap to map the image. */
|
/* Otherwise find a gap to map the image. */
|
||||||
ImageBase = MmFindGap(AddressSpace, ImageSize);
|
ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize));
|
||||||
if (ImageBase == NULL)
|
if (ImageBase == NULL)
|
||||||
{
|
{
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return(Status);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue