* 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
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)
}
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
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))
{
Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE);
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
- MmUnlockAddressSpace(AddressSpace);
Status = MmReadFromSwapPage(SwapEntry, Mdl);
if (!NT_SUCCESS(Status))
{
* 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,
* 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);
/*
/*
* 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.
*/
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)
{
/*
* If necessary, allocate an entry in the paging file for this page
*/
- SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0)
{
SwapEntry = MmAllocSwapPage();
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);
}
}
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);
/*
* If necessary, allocate an entry in the paging file for this page
*/
- SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0)
{
SwapEntry = MmAllocSwapPage();
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);
}
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)
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
*/