From 91880bad83c33748f0c626fb3d5efddf439d991a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 25 Feb 2025 20:25:41 +0100 Subject: [PATCH] kernel/vm: when resizing down a VMCache, fill a partial page with zeros * factored out file_cache * fix two gVisor tests: MMapFileTest.ReadSharedTruncatePartialPage and MMapFileTest.WriteSharedTruncatePartialPage * fix #19438 Change-Id: Ia7f119478d306ab6d867632e4a5270733f0b29df Reviewed-on: https://review.haiku-os.org/c/haiku/+/9060 Reviewed-by: waddlesplash --- src/system/kernel/cache/file_cache.cpp | 14 -------------- src/system/kernel/vm/VMCache.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 7d25293536..1d08c6a545 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -1276,23 +1276,9 @@ file_cache_set_size(void* _cacheRef, off_t newSize) VMCache* cache = ref->cache; AutoLocker _(cache); - off_t oldSize = cache->virtual_end; status_t status = cache->Resize(newSize, VM_PRIORITY_USER); // Note, the priority doesn't really matter, since this cache doesn't // reserve any memory. - if (status == B_OK && newSize < oldSize) { - // We may have a new partial page at the end of the cache that must be - // cleared. - uint32 partialBytes = newSize % B_PAGE_SIZE; - if (partialBytes != 0) { - vm_page* page = cache->LookupPage(newSize - partialBytes); - if (page != NULL) { - vm_memset_physical(page->physical_page_number * B_PAGE_SIZE - + partialBytes, 0, B_PAGE_SIZE - partialBytes); - } - } - } - return status; } diff --git a/src/system/kernel/vm/VMCache.cpp b/src/system/kernel/vm/VMCache.cpp index 6eb764d8d0..1eca0b2391 100644 --- a/src/system/kernel/vm/VMCache.cpp +++ b/src/system/kernel/vm/VMCache.cpp @@ -1172,6 +1172,17 @@ VMCache::Resize(off_t newSize, int priority) while (_FreePageRange(pages.GetIterator(newPageCount, true, true))) ; } + if (newSize < virtual_end && newPageCount > 0) { + // We may have a partial page at the end of the cache that must be cleared. + uint32 partialBytes = newSize % B_PAGE_SIZE; + if (partialBytes != 0) { + vm_page* page = LookupPage(newSize - partialBytes); + if (page != NULL) { + vm_memset_physical(page->physical_page_number * B_PAGE_SIZE + + partialBytes, 0, B_PAGE_SIZE - partialBytes); + } + } + } if (priority >= 0) { status_t status = Commit(PAGE_ALIGN(newSize - virtual_base), priority);