Completed file cache support.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29442 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-03-08 15:56:07 +00:00
parent 224d5dc603
commit 4e5971527e
2 changed files with 142 additions and 17 deletions
@@ -10,6 +10,8 @@
#include <unistd.h>
#include <sys/stat.h>
#include <fs_cache.h>
#include <util/AutoLock.h>
#include <util/OpenHashTable.h>
@@ -41,15 +43,26 @@ static const bigtime_t kUserlandServerlandPortTimeout = 10000000; // 10s
struct Volume::VNode : HashTableLink<VNode> {
ino_t id;
void* clientNode;
void* fileCache;
int32 useCount;
VNode(ino_t id, void* clientNode)
:
id(id),
clientNode(clientNode),
fileCache(NULL),
useCount(0)
{
}
~VNode()
{
if (fileCache != NULL)
{
ERROR(("VNode %lld still has a file cache!\n", id));
file_cache_delete(fileCache);
}
}
};
@@ -295,8 +308,31 @@ PRINT(("get_vnode_removed(%ld, %lld, %p)\n", GetID(), vnid, removed));
status_t
Volume::CreateFileCache(ino_t vnodeID, off_t size)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node already have a file cache?
if (vnode->fileCache != NULL)
RETURN_ERROR(B_BAD_VALUE);
// create the file cache
locker.Unlock();
void* fileCache = file_cache_create(GetID(), vnodeID, size);
locker.Lock();
// re-check whether the node still lives
vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL) {
file_cache_delete(fileCache);
RETURN_ERROR(B_BAD_VALUE);
}
vnode->fileCache = fileCache;
return B_OK;
}
@@ -304,8 +340,24 @@ Volume::CreateFileCache(ino_t vnodeID, off_t size)
status_t
Volume::DeleteFileCache(ino_t vnodeID)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
vnode->fileCache = NULL;
locker.Unlock();
file_cache_delete(fileCache);
return B_OK;
}
@@ -313,8 +365,29 @@ Volume::DeleteFileCache(ino_t vnodeID)
status_t
Volume::SetFileCacheEnabled(ino_t vnodeID, bool enabled)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
locker.Unlock();
// TODO: We should use some kind of ref counting to avoid that another thread
// deletes the file cache now that we have dropped the lock. Applies to the
// other file cache operations as well.
// enable/disable the file cache
if (enabled) {
file_cache_enable(fileCache);
return B_OK;
}
return file_cache_disable(fileCache);
}
@@ -322,8 +395,21 @@ Volume::SetFileCacheEnabled(ino_t vnodeID, bool enabled)
status_t
Volume::SetFileCacheSize(ino_t vnodeID, off_t size)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
locker.Unlock();
// set the size
return file_cache_set_size(fileCache, size);
}
@@ -331,8 +417,21 @@ Volume::SetFileCacheSize(ino_t vnodeID, off_t size)
status_t
Volume::SyncFileCache(ino_t vnodeID)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
locker.Unlock();
// sync
return file_cache_sync(fileCache);
}
@@ -341,18 +440,44 @@ status_t
Volume::ReadFileCache(ino_t vnodeID, void* cookie,
off_t offset, void* buffer, size_t* _size)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
locker.Unlock();
// read
return file_cache_read(fileCache, cookie, offset, buffer, _size);
}
// WriteFileCache
status_t
Volume::WriteFileCache(ino_t vnodeID, void* cookie,
off_t offset, const void *buffer, size_t *_size)
off_t offset, const void* buffer, size_t* _size)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
// lookup the node
MutexLocker locker(fLock);
VNode* vnode = fVNodes->Lookup(vnodeID);
if (vnode == NULL)
RETURN_ERROR(B_BAD_VALUE);
// does the node have a file cache
if (vnode->fileCache == NULL)
RETURN_ERROR(B_BAD_VALUE);
void* fileCache = vnode->fileCache;
locker.Unlock();
// read
return file_cache_write(fileCache, cookie, offset, buffer, _size);
}
@@ -66,8 +66,8 @@ public:
status_t ReadFileCache(ino_t vnodeID, void* cookie,
off_t offset, void* buffer, size_t* _size);
status_t WriteFileCache(ino_t vnodeID, void* cookie,
off_t offset, const void *buffer,
size_t *_size);
off_t offset, const void* buffer,
size_t* _size);
// FS
status_t Mount(const char* device, uint32 flags,