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
This commit is contained in:
@@ -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--;
|
||||
|
||||
Reference in New Issue
Block a user