From ba3d62b66f8e33304ed71ee6a2d403cc75d95e87 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 15 Feb 2010 19:36:17 +0000 Subject: [PATCH] X86VMTranslationMap::UnmapArea(): Don't change the page state before it has been unmapped. This way modified pages could end up in the "cached" queue without having been written back. That would be a good explanation for #5374 (partially wrong file contents) -- as soon as such a page was freed, the invalid on-disk contents would become visible. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35477 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../arch/x86/arch_vm_translation_map.cpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp index 3553234dc0..ef0c10545e 100644 --- a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp +++ b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp @@ -800,23 +800,12 @@ X86VMTranslationMap::UnmapArea(VMArea* area, bool deletingAddressSpace, VMCache* cache = page->Cache(); - DEBUG_PAGE_ACCESS_START(page); - + bool pageFullyUnmapped = false; if (page->wired_count == 0 && page->mappings.IsEmpty()) { atomic_add(&gMappedPagesCount, -1); - - if (!ignoreTopCachePageFlags || cache != area->cache) { - if (cache->temporary) - vm_page_set_state(page, PAGE_STATE_INACTIVE); - else if (page->modified) - vm_page_set_state(page, PAGE_STATE_MODIFIED); - else - vm_page_set_state(page, PAGE_STATE_CACHED); - } + pageFullyUnmapped = true; } - DEBUG_PAGE_ACCESS_END(page); - if (unmapPages || cache != area->cache) { addr_t address = area->Base() + ((page->cache_offset * B_PAGE_SIZE) - area->cache_offset); @@ -861,6 +850,19 @@ X86VMTranslationMap::UnmapArea(VMArea* area, bool deletingAddressSpace, if ((oldEntry & X86_PTE_DIRTY) != 0) page->modified = true; + + if (pageFullyUnmapped) { + DEBUG_PAGE_ACCESS_START(page); + + if (cache->temporary) + vm_page_set_state(page, PAGE_STATE_INACTIVE); + else if (page->modified) + vm_page_set_state(page, PAGE_STATE_MODIFIED); + else + vm_page_set_state(page, PAGE_STATE_CACHED); + + DEBUG_PAGE_ACCESS_END(page); + } } fMapCount--;