From 1f611c018b474c78f84ea905e574c24586ae85b1 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 16 Feb 2010 17:22:56 +0000 Subject: [PATCH] The file cache code was completely ignoring the vm_page::modified flag. In particular it wouldn't set the flag when writing something to a page, but only move it to the modified queue. Since mapping the page would move it to another queue, the information that the page was modified would be lost and it would never be written to disk. Was well reproducible with a Haiku image build and limited amount of memory. Fixes the hopefully last remaining cause for #5374. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35500 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/file_cache.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 0d05540d4f..0bd3993b8b 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -309,7 +309,8 @@ reserve_pages(file_cache_ref* ref, vm_page_reservation* reservation, vm_page* page; for (VMCachePagesTree::Iterator it = cache->pages.GetIterator(); (page = it.Next()) != NULL && left > 0;) { - if (page->state != PAGE_STATE_MODIFIED && !page->busy) { + if (page->state != PAGE_STATE_MODIFIED && !page->modified + && !page->busy) { DEBUG_PAGE_ACCESS_START(page); cache->RemovePage(page); vm_page_set_state(page, PAGE_STATE_FREE); @@ -514,6 +515,8 @@ write_to_cache(file_cache_ref* ref, void* cookie, off_t offset, (writeThrough ? PAGE_STATE_CACHED : PAGE_STATE_MODIFIED) | VM_PAGE_ALLOC_BUSY); + page->modified = !writeThrough; + ref->cache->InsertPage(page, offset + pos); add_to_iovec(vecs, vecCount, MAX_IO_VECS, @@ -807,9 +810,14 @@ cache_io(void* _cacheRef, void* cookie, off_t offset, addr_t buffer, locker.Lock(); - if (doWrite && page->state != PAGE_STATE_MODIFIED) { + if (doWrite) { DEBUG_PAGE_ACCESS_START(page); - vm_page_set_state(page, PAGE_STATE_MODIFIED); + + page->modified = true; + + if (page->state != PAGE_STATE_MODIFIED) + vm_page_set_state(page, PAGE_STATE_MODIFIED); + DEBUG_PAGE_ACCESS_END(page); }