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
This commit is contained in:
Stephan Aßmus
2006-05-22 09:59:07 +00:00
parent a0c5ca01a5
commit bd5ed534cf
+18 -4
View File
@@ -108,6 +108,13 @@ file_map::Add(file_io_vec *vecs, size_t vecCount)
{ {
off_t offset = 0; 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) { if (vecCount <= CACHED_FILE_EXTENTS && count == 0) {
// just use the reserved area in the file_cache_ref structure // just use the reserved area in the file_cache_ref structure
} else { } 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) file_io_vec *vecs, size_t *_count)
{ {
size_t maxVecs = *_count; size_t maxVecs = *_count;
status_t status = B_OK;
if (ref->map.count == 0) { if (ref->map.count == 0) {
// we don't yet have the map of this file, so let's grab it // 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 // the file map could have been requested in the mean time
if (ref->map.count == 0) { if (ref->map.count == 0) {
size_t vecCount = maxVecs; size_t vecCount = maxVecs;
status_t status;
off_t mapOffset = 0; off_t mapOffset = 0;
while (true) { while (true) {
status = vfs_get_file_map(ref->vnode, mapOffset, ~0UL, vecs, &vecCount); status = vfs_get_file_map(ref->vnode, mapOffset, ~0UL, vecs, &vecCount);
if (status < B_OK && status != B_BUFFER_OVERFLOW) { 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; 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) if (status != B_BUFFER_OVERFLOW)
break; break;
@@ -233,6 +240,13 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size,
mutex_unlock(&ref->cache->lock); 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 // We now have cached the map of this file, we now need to
// translate it for the requested access. // translate it for the requested access.