From bd5ed534cff597ba657854c6165caf59bdede30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 22 May 2006 09:59:07 +0000 Subject: [PATCH] a fix to the file cache (done by Axel), that prevents a crash when reading the file map of certain files (hope I got that more or less right) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17525 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/file_cache.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 1980ef94d0..b54ef83dff 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -108,6 +108,13 @@ file_map::Add(file_io_vec *vecs, size_t vecCount) { off_t offset = 0; +#if 0 +for (uint32 i = 0; i < vecCount; i++) { + dprintf("[%ld] vecs offset %Ld, length %Ld\n", + i, vecs[i].offset, vecs[i].length); +} +#endif + if (vecCount <= CACHED_FILE_EXTENTS && count == 0) { // just use the reserved area in the file_cache_ref structure } else { @@ -197,6 +204,7 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size, file_io_vec *vecs, size_t *_count) { size_t maxVecs = *_count; + status_t status = B_OK; if (ref->map.count == 0) { // we don't yet have the map of this file, so let's grab it @@ -207,9 +215,8 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size, // the file map could have been requested in the mean time if (ref->map.count == 0) { size_t vecCount = maxVecs; - status_t status; off_t mapOffset = 0; - + while (true) { status = vfs_get_file_map(ref->vnode, mapOffset, ~0UL, vecs, &vecCount); if (status < B_OK && status != B_BUFFER_OVERFLOW) { @@ -217,8 +224,8 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size, return status; } - ref->map.Add(vecs, vecCount); - + status = ref->map.Add(vecs, vecCount); +//dprintf("map.Add() status %s\n", strerror(status)); if (status != B_BUFFER_OVERFLOW) break; @@ -233,6 +240,13 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size, mutex_unlock(&ref->cache->lock); } + if (status != B_OK) { + // We must invalidate the (part of the) map we already + // have, as we cannot know if it's complete or not + ref->map.Free(); + return status; + } + // We now have cached the map of this file, we now need to // translate it for the requested access.