mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Fixed the handling for page file backed sections.
svn path=/trunk/; revision=5121
This commit is contained in:
parent
9789c326b0
commit
3364b9cc5f
1 changed files with 104 additions and 26 deletions
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: section.c,v 1.122 2003/07/12 01:55:50 dwelch Exp $
|
||||
/* $Id: section.c,v 1.123 2003/07/14 20:14:11 hbirr Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/section.c
|
||||
|
@ -279,8 +279,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
|||
FileOffset = Offset + Segment->FileOffset;
|
||||
|
||||
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
|
||||
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, 0);
|
||||
|
||||
Page = (PHYSICAL_ADDRESS)(LONGLONG)PAGE_FROM_SSE(Entry);
|
||||
FileObject = Section->FileObject;
|
||||
if (FileObject != NULL)
|
||||
|
@ -302,10 +301,37 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
|||
}
|
||||
|
||||
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||
if (SavedSwapEntry != 0)
|
||||
if (SavedSwapEntry == 0)
|
||||
{
|
||||
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* Try to page out this page and set the swap entry
|
||||
* within the section segment. There exist no rmap entry
|
||||
* for this page. The pager thread can't page out a
|
||||
* page without a rmap entry.
|
||||
*/
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||
MmReferencePage(Page);
|
||||
}
|
||||
else
|
||||
{
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MmFreeSwapPage(SavedSwapEntry);
|
||||
MmSetSavedSwapEntryPage(Page, 0);
|
||||
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry));
|
||||
}
|
||||
else
|
||||
{
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, 0);
|
||||
MmFreeSwapPage(SavedSwapEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -689,9 +715,19 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
SWAPENTRY SwapEntry;
|
||||
PMDL Mdl;
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
DPRINT1("Found a swaped out private page in a pagefile section.\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry);
|
||||
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -700,7 +736,6 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
|
||||
Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
|
||||
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
Status = MmReadFromSwapPage(SwapEntry, Mdl);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -923,9 +958,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
* Mark the offset within the section as having valid, in-memory
|
||||
* data
|
||||
*/
|
||||
Entry = Page.u.LowPart;
|
||||
Entry = MAKE_SSE(Page.u.LowPart, 1);
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||
MmSharePageEntrySectionSegment(Segment, Offset);
|
||||
MmUnlockSectionSegment(Segment);
|
||||
|
||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||
|
@ -1009,9 +1043,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
* Mark the offset within the section as having valid, in-memory
|
||||
* data
|
||||
*/
|
||||
Entry = Page.u.LowPart;
|
||||
Entry = MAKE_SSE(Page.u.LowPart, 1);
|
||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||
MmSharePageEntrySectionSegment(Segment, Offset);
|
||||
MmUnlockSectionSegment(Segment);
|
||||
|
||||
/*
|
||||
|
@ -1407,7 +1440,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
/*
|
||||
* Paging out data mapped read-only is easy.
|
||||
*/
|
||||
if (Context.Segment->Protection & (PAGE_READONLY|PAGE_EXECUTE_READ))
|
||||
if (Context.Segment->Protection & (PAGE_READONLY|PAGE_EXECUTE_READ))
|
||||
{
|
||||
/*
|
||||
* Read-only data should never be in the swapfile.
|
||||
|
@ -1474,15 +1507,24 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
*/
|
||||
if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT))
|
||||
{
|
||||
CHECKPOINT1;
|
||||
KeBugCheck(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the page wasn't dirty then we can just free it as for a readonly page.
|
||||
* Since we unmapped all the mappings above we know it will not suddenly
|
||||
* become dirty.
|
||||
* become dirty.
|
||||
* If the page is from a pagefile section and has no swap entry,
|
||||
* we can't free the page at this point.
|
||||
*/
|
||||
if (!Context.WasDirty)
|
||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||
if (!Context.WasDirty &&
|
||||
!(SwapEntry == 0 && Context.Segment->Flags & MM_PAGEFILE_SEGMENT))
|
||||
|
||||
{
|
||||
if (Context.Private)
|
||||
{
|
||||
|
@ -1549,7 +1591,6 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
/*
|
||||
* If necessary, allocate an entry in the paging file for this page
|
||||
*/
|
||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||
if (SwapEntry == 0)
|
||||
{
|
||||
SwapEntry = MmAllocSwapPage();
|
||||
|
@ -1588,14 +1629,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
MmInsertRmap(PhysicalAddress,
|
||||
MemoryArea->Process,
|
||||
Address);
|
||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset,
|
||||
PhysicalAddress.u.LowPart);
|
||||
MmSharePageEntrySectionSegment(Context.Segment, Context.Offset);
|
||||
Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
|
||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||
}
|
||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_PAGEFILE_QUOTA);
|
||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
MmReleasePageOp(PageOp);
|
||||
return(STATUS_PAGEFILE_QUOTA);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1636,9 +1676,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
MmInsertRmap(PhysicalAddress,
|
||||
MemoryArea->Process,
|
||||
Address);
|
||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset,
|
||||
PhysicalAddress.u.LowPart);
|
||||
MmSharePageEntrySectionSegment(Context.Segment, Context.Offset);
|
||||
Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
|
||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||
}
|
||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||
|
@ -1787,7 +1826,6 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
/*
|
||||
* If necessary, allocate an entry in the paging file for this page
|
||||
*/
|
||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
||||
if (SwapEntry == 0)
|
||||
{
|
||||
SwapEntry = MmAllocSwapPage();
|
||||
|
@ -1984,6 +2022,30 @@ MmpDeleteSection(PVOID ObjectBody)
|
|||
|
||||
if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
ULONG Offset;
|
||||
ULONG Length;
|
||||
ULONG Entry;
|
||||
PMM_SECTION_SEGMENT Segment;
|
||||
|
||||
Segment = Section->Segment;
|
||||
Length = PAGE_ROUND_UP(Segment->Length);
|
||||
|
||||
for (Offset = 0; Offset < Length; Offset += PAGE_SIZE)
|
||||
{
|
||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
||||
if (Entry)
|
||||
{
|
||||
if (IS_SWAP_FROM_SSE(Entry))
|
||||
{
|
||||
MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry));
|
||||
}
|
||||
else
|
||||
{
|
||||
PHYSICAL_ADDRESS Page = (PHYSICAL_ADDRESS)(LONGLONG)PAGE_FROM_SSE(Entry);
|
||||
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||
}
|
||||
}
|
||||
}
|
||||
MmFreePageTablesSectionSegment(Section->Segment);
|
||||
ExFreePool(Section->Segment);
|
||||
}
|
||||
|
@ -3149,6 +3211,14 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
|||
|
||||
if (SwapEntry != 0)
|
||||
{
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
DPRINT1("Found a swap entry for a page in a pagefile section.\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
MmFreeSwapPage(SwapEntry);
|
||||
}
|
||||
else if (PhysAddr.QuadPart != 0)
|
||||
|
@ -3156,6 +3226,14 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
|||
if (IS_SWAP_FROM_SSE(Entry) ||
|
||||
PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry)))
|
||||
{
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
if (Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||
{
|
||||
DPRINT1("Found a private page in a pagefile section.\n");
|
||||
KeBugCheck(0);
|
||||
}
|
||||
/*
|
||||
* Just dereference private pages
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue