kernel/fs: Add support for setting custom VMCaches in vnodes.
This adds one (private) VFS function, and checks in all usages of the vnode->cache as a VMVnodeCache that it really is one. (Generic usages, for the moment just the ReleaseRef() calls in vnode destruction, are intentionally not touched.) This will be used by ramfs to set the cache from its own, so that map_file() calls on a ramfs can work.
This commit is contained in:
@@ -112,6 +112,7 @@ status_t vfs_synchronous_io(io_request* request,
|
||||
void* cookie);
|
||||
status_t vfs_get_vnode_cache(struct vnode *vnode, struct VMCache **_cache,
|
||||
bool allocate);
|
||||
status_t vfs_set_vnode_cache(struct vnode *vnode, struct VMCache *_cache);
|
||||
status_t vfs_get_file_map(struct vnode *vnode, off_t offset, size_t size,
|
||||
struct file_io_vec *vecs, size_t *_count);
|
||||
status_t vfs_get_fs_node_from_path(fs_volume *volume, const char *path,
|
||||
|
||||
+4
-2
@@ -932,6 +932,8 @@ cache_prefetch_vnode(struct vnode* vnode, off_t offset, size_t size)
|
||||
VMCache* cache;
|
||||
if (vfs_get_vnode_cache(vnode, &cache, false) != B_OK)
|
||||
return;
|
||||
if (cache->type != CACHE_TYPE_VNODE)
|
||||
return;
|
||||
|
||||
file_cache_ref* ref = ((VMVnodeCache*)cache)->FileCacheRef();
|
||||
off_t fileSize = cache->virtual_end;
|
||||
@@ -1029,7 +1031,7 @@ cache_node_opened(struct vnode* vnode, int32 fdType, VMCache* cache,
|
||||
return;
|
||||
|
||||
off_t size = -1;
|
||||
if (cache != NULL) {
|
||||
if (cache != NULL && cache->type == CACHE_TYPE_VNODE) {
|
||||
file_cache_ref* ref = ((VMVnodeCache*)cache)->FileCacheRef();
|
||||
if (ref != NULL)
|
||||
size = cache->virtual_end;
|
||||
@@ -1048,7 +1050,7 @@ cache_node_closed(struct vnode* vnode, int32 fdType, VMCache* cache,
|
||||
return;
|
||||
|
||||
int32 accessType = 0;
|
||||
if (cache != NULL) {
|
||||
if (cache != NULL && cache->type == CACHE_TYPE_VNODE) {
|
||||
// ToDo: set accessType
|
||||
}
|
||||
|
||||
|
||||
@@ -1035,7 +1035,7 @@ free_vnode(struct vnode* vnode, bool reenter)
|
||||
// long as the vnode is busy and in the hash, that won't happen, but as
|
||||
// soon as we've removed it from the hash, it could reload the vnode -- with
|
||||
// a new cache attached!
|
||||
if (vnode->cache != NULL)
|
||||
if (vnode->cache != NULL && vnode->cache->type == CACHE_TYPE_VNODE)
|
||||
((VMVnodeCache*)vnode->cache)->VnodeDeleted();
|
||||
|
||||
// The file system has removed the resources of the vnode now, so we can
|
||||
@@ -4021,7 +4021,7 @@ change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID)
|
||||
vnode->id = newID;
|
||||
sVnodeTable->Insert(vnode);
|
||||
|
||||
if (vnode->cache != NULL)
|
||||
if (vnode->cache != NULL && vnode->cache->type == CACHE_TYPE_VNODE)
|
||||
((VMVnodeCache*)vnode->cache)->SetVnodeID(newID);
|
||||
|
||||
return B_OK;
|
||||
@@ -4828,6 +4828,31 @@ vfs_get_vnode_cache(struct vnode* vnode, VMCache** _cache, bool allocate)
|
||||
}
|
||||
|
||||
|
||||
/*! Sets the vnode's VMCache object, for subsystems that want to manage
|
||||
their own.
|
||||
In case it's successful, it will also grab a reference to the cache
|
||||
it returns.
|
||||
*/
|
||||
extern "C" status_t
|
||||
vfs_set_vnode_cache(struct vnode* vnode, VMCache* _cache)
|
||||
{
|
||||
rw_lock_read_lock(&sVnodeLock);
|
||||
vnode->Lock();
|
||||
|
||||
status_t status = B_OK;
|
||||
if (vnode->cache != NULL) {
|
||||
status = B_NOT_ALLOWED;
|
||||
} else {
|
||||
vnode->cache = _cache;
|
||||
_cache->AcquireRef();
|
||||
}
|
||||
|
||||
vnode->Unlock();
|
||||
rw_lock_read_unlock(&sVnodeLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
vfs_get_file_map(struct vnode* vnode, off_t offset, size_t size,
|
||||
file_io_vec* vecs, size_t* _count)
|
||||
|
||||
Reference in New Issue
Block a user