From 0f8e6927d8b1cbb26b060e02dd426652d7985c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 19 Jan 2005 02:35:39 +0000 Subject: [PATCH] Fixed another big and stupid bug: the first read/write not in the cache and not on a page boundary had been executed with a I/O size too large, and thus clobbering all sorts of memory (oh my god). The problems with ResourceFile now seems to be gone. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10863 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/cache/file_cache.cpp | 35 ++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/kernel/core/cache/file_cache.cpp b/src/kernel/core/cache/file_cache.cpp index 50cf95a2ee..7c8f6a0169 100644 --- a/src/kernel/core/cache/file_cache.cpp +++ b/src/kernel/core/cache/file_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -462,12 +462,12 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d } int32 pageOffset = offset & (B_PAGE_SIZE - 1); - size_t size = *_size + pageOffset; + size_t size = *_size; offset -= pageOffset; - if (offset + size > fileSize) { + if (offset + pageOffset + size > fileSize) { // adapt size to be within the file's offsets - size = fileSize - offset; + size = fileSize - pageOffset - offset; *_size = size; } @@ -492,12 +492,20 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d TRACE(("lookup page from offset %Ld: %p\n", offset, page)); if (page != NULL - && vm_get_physical_page(page->ppn * B_PAGE_SIZE, &virtualAddress, PHYSICAL_PAGE_CAN_WAIT) == B_OK) { - // it is, so let's satisfy in the first part of the request + && vm_get_physical_page(page->ppn * B_PAGE_SIZE, + &virtualAddress, PHYSICAL_PAGE_CAN_WAIT) == B_OK) { + // it is, so let's satisfy the first part of the request, if we have to if (bufferBase != buffer) { size_t requestSize = buffer - bufferBase; - if ((doWrite && write_to_cache(ref, lastOffset + pageOffset, requestSize, bufferBase, requestSize) != B_OK) - || (!doWrite && read_into_cache(ref, lastOffset + pageOffset, requestSize, bufferBase, requestSize) != B_OK)) { + status_t status; + if (doWrite) { + status = write_to_cache(ref, lastOffset + pageOffset, + requestSize, bufferBase, requestSize); + } else { + status = read_into_cache(ref, lastOffset + pageOffset, + requestSize, bufferBase, requestSize); + } + if (status != B_OK) { vm_put_physical_page(virtualAddress); mutex_unlock(&cache->lock); return B_IO_ERROR; @@ -506,10 +514,13 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d } // and copy the contents of the page already in memory - if (doWrite) - user_memcpy((void *)(virtualAddress + pageOffset), (void *)buffer, min_c(B_PAGE_SIZE, bytesLeft) - pageOffset); - else - user_memcpy((void *)buffer, (void *)(virtualAddress + pageOffset), min_c(B_PAGE_SIZE, bytesLeft) - pageOffset); + if (doWrite) { + user_memcpy((void *)(virtualAddress + pageOffset), (void *)buffer, + min_c(size_t(B_PAGE_SIZE - pageOffset), bytesLeft)); + } else { + user_memcpy((void *)buffer, (void *)(virtualAddress + pageOffset), + min_c(size_t(B_PAGE_SIZE - pageOffset), bytesLeft)); + } vm_put_physical_page(virtualAddress);