* satisfy_cache_io() was using the wrong value to compute the number of
pages to reserve, which could result in to few being reserved in certain situations. * Use MutexLocker where appropriate. * Reordered includes following the new rules. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22494 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+15
-24
@@ -6,22 +6,23 @@
|
|||||||
|
|
||||||
#include "vnode_store.h"
|
#include "vnode_store.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <fs_cache.h>
|
#include <fs_cache.h>
|
||||||
|
|
||||||
#include <condition_variable.h>
|
#include <condition_variable.h>
|
||||||
#include <file_cache.h>
|
#include <file_cache.h>
|
||||||
#include <generic_syscall.h>
|
#include <generic_syscall.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <vm_page.h>
|
#include <vm_page.h>
|
||||||
#include <vm_cache.h>
|
#include <vm_cache.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_FILE_CACHE
|
//#define TRACE_FILE_CACHE
|
||||||
#ifdef TRACE_FILE_CACHE
|
#ifdef TRACE_FILE_CACHE
|
||||||
@@ -221,7 +222,7 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size,
|
|||||||
// 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
|
||||||
// (ordered by offset, so that we can do a binary search on them)
|
// (ordered by offset, so that we can do a binary search on them)
|
||||||
|
|
||||||
mutex_lock(&ref->cache->lock);
|
MutexLocker _(ref->cache->lock);
|
||||||
|
|
||||||
// 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) {
|
||||||
@@ -231,10 +232,8 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size,
|
|||||||
while (true) {
|
while (true) {
|
||||||
status = vfs_get_file_map(ref->vnode, mapOffset, ~0UL, vecs,
|
status = vfs_get_file_map(ref->vnode, mapOffset, ~0UL, vecs,
|
||||||
&vecCount);
|
&vecCount);
|
||||||
if (status < B_OK && status != B_BUFFER_OVERFLOW) {
|
if (status < B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
mutex_unlock(&ref->cache->lock);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
status_t addStatus = ref->map.Add(vecs, vecCount, mapOffset);
|
status_t addStatus = ref->map.Add(vecs, vecCount, mapOffset);
|
||||||
if (addStatus != B_OK) {
|
if (addStatus != B_OK) {
|
||||||
@@ -250,8 +249,6 @@ get_file_map(file_cache_ref *ref, off_t offset, size_t size,
|
|||||||
vecCount = maxVecs;
|
vecCount = maxVecs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&ref->cache->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
@@ -776,7 +773,7 @@ satisfy_cache_io(file_cache_ref *ref, off_t offset, addr_t buffer,
|
|||||||
|
|
||||||
size_t requestSize = buffer - lastBuffer;
|
size_t requestSize = buffer - lastBuffer;
|
||||||
reservePages = min_c(MAX_IO_VECS,
|
reservePages = min_c(MAX_IO_VECS,
|
||||||
(bytesLeft - requestSize + B_PAGE_SIZE - 1) >> PAGE_SHIFT);
|
(lastLeft - requestSize + B_PAGE_SIZE - 1) >> PAGE_SHIFT);
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
if (doWrite) {
|
if (doWrite) {
|
||||||
@@ -844,7 +841,7 @@ cache_io(void *_cacheRef, off_t offset, addr_t buffer, size_t *_size,
|
|||||||
size_t reservePages = 0;
|
size_t reservePages = 0;
|
||||||
|
|
||||||
vm_page_reserve_pages(lastReservedPages);
|
vm_page_reserve_pages(lastReservedPages);
|
||||||
mutex_lock(&cache->lock);
|
MutexLocker locker(cache->lock);
|
||||||
|
|
||||||
while (bytesLeft > 0) {
|
while (bytesLeft > 0) {
|
||||||
// check if this page is already in memory
|
// check if this page is already in memory
|
||||||
@@ -857,17 +854,15 @@ cache_io(void *_cacheRef, off_t offset, addr_t buffer, size_t *_size,
|
|||||||
status_t status = satisfy_cache_io(ref, offset, buffer, pageOffset,
|
status_t status = satisfy_cache_io(ref, offset, buffer, pageOffset,
|
||||||
bytesLeft, reservePages, lastOffset, lastBuffer, lastPageOffset,
|
bytesLeft, reservePages, lastOffset, lastBuffer, lastPageOffset,
|
||||||
lastLeft, lastReservedPages, doWrite);
|
lastLeft, lastReservedPages, doWrite);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
mutex_unlock(&cache->lock);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
if (page->state == PAGE_STATE_BUSY) {
|
if (page->state == PAGE_STATE_BUSY) {
|
||||||
ConditionVariableEntry<vm_page> entry;
|
ConditionVariableEntry<vm_page> entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
mutex_unlock(&cache->lock);
|
locker.Unlock();
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
mutex_lock(&cache->lock);
|
locker.Lock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,7 +898,7 @@ cache_io(void *_cacheRef, off_t offset, addr_t buffer, size_t *_size,
|
|||||||
|
|
||||||
if (bytesLeft <= bytesInPage) {
|
if (bytesLeft <= bytesInPage) {
|
||||||
// we've read the last page, so we're done!
|
// we've read the last page, so we're done!
|
||||||
mutex_unlock(&cache->lock);
|
locker.Unlock();
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -927,10 +922,8 @@ cache_io(void *_cacheRef, off_t offset, addr_t buffer, size_t *_size,
|
|||||||
status_t status = satisfy_cache_io(ref, offset, buffer, pageOffset,
|
status_t status = satisfy_cache_io(ref, offset, buffer, pageOffset,
|
||||||
bytesLeft, reservePages, lastOffset, lastBuffer, lastPageOffset,
|
bytesLeft, reservePages, lastOffset, lastBuffer, lastPageOffset,
|
||||||
lastLeft, lastReservedPages, doWrite);
|
lastLeft, lastReservedPages, doWrite);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
mutex_unlock(&cache->lock);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,7 +938,6 @@ cache_io(void *_cacheRef, off_t offset, addr_t buffer, size_t *_size,
|
|||||||
lastBuffer, lastLeft, lastReservedPages, 0);
|
lastBuffer, lastLeft, lastReservedPages, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&cache->lock);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1333,8 +1325,7 @@ file_cache_invalidate_file_map(void *_cacheRef, off_t offset, off_t size)
|
|||||||
TRACE(("file_cache_invalidate_file_map(offset = %Ld, size = %Ld)\n", offset,
|
TRACE(("file_cache_invalidate_file_map(offset = %Ld, size = %Ld)\n", offset,
|
||||||
size));
|
size));
|
||||||
|
|
||||||
mutex_lock(&ref->cache->lock);
|
MutexLocker _(ref->cache->lock);
|
||||||
ref->map.Free();
|
ref->map.Free();
|
||||||
mutex_unlock(&ref->cache->lock);
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user