Fixed another stupid bug in cache_io(): if one request needed new pages

more than once, the size requested was only correct for the first time.
Added preliminary support for cache modules.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10335 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-12-01 07:38:27 +00:00
parent a16bf97a7d
commit 324fc66b90
+45 -2
View File
@@ -40,6 +40,9 @@ struct file_cache_ref {
};
static struct cache_module_info *sCacheModule;
static void
add_to_iovec(iovec *vecs, int32 &index, int32 max, addr_t address, size_t size)
{
@@ -365,7 +368,6 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d
size_t size = *_size + pageOffset;
offset -= pageOffset;
addr_t buffer = bufferBase;
if (offset + size > fileSize) {
// adapt size to be within the file's offsets
size = fileSize - offset;
@@ -373,6 +375,7 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d
}
size_t bytesLeft = size, lastLeft = size;
addr_t buffer = bufferBase;
off_t lastOffset = offset;
for (; bytesLeft > 0; offset += B_PAGE_SIZE) {
@@ -393,12 +396,13 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d
&& 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
if (bufferBase != buffer) {
size_t requestSize = buffer - (addr_t)bufferBase;
size_t requestSize = buffer - bufferBase;
if ((doWrite && write_to_cache(ref, lastOffset + pageOffset, requestSize, bufferBase, requestSize) != B_OK)
|| (!doWrite && read_from_cache(ref, lastOffset + pageOffset, requestSize, bufferBase, requestSize) != B_OK)) {
vm_put_physical_page(virtualAddress);
return B_IO_ERROR;
}
bufferBase += requestSize;
}
// and copy the contents of the page already in memory
@@ -440,6 +444,45 @@ cache_io(void *_cacheRef, off_t offset, addr_t bufferBase, size_t *_size, bool d
}
// #pragma mark -
// kernel public API
extern "C" void
cache_prefetch(mount_id mountID, vnode_id vnodeID)
{
// ToDo: schedule prefetch
// ToDo: maybe get 1) access type (random/sequential), 2) file vecs which blocks to prefetch
dprintf("prefetch vnode %ld:%Ld\n", mountID, vnodeID);
}
extern "C" void
cache_node_opened(void *_ref, mount_id mountID, vnode_id vnodeID)
{
file_cache_ref *ref = (file_cache_ref *)_ref;
if (ref != NULL && sCacheModule != NULL)
sCacheModule->node_opened(ref->cache->cache->virtual_size, mountID, vnodeID);
}
extern "C" void
cache_node_closed(void *ref, mount_id mountID, vnode_id vnodeID)
{
if (ref != NULL && sCacheModule != NULL)
sCacheModule->node_closed(mountID, vnodeID);
}
extern "C" status_t
file_cache_init(void)
{
// ToDo: get cache module
return B_OK;
}
// #pragma mark -
// public FS API