ramfs: Set the vnode's cache object when opening files.

Now it is possible to run applications, do Git checkouts, etc.
on a ramfs (and those seem to work just fine -- a git checkout
followed by a git fsck both succeeded.)
This commit is contained in:
Augustin Cavalier 2019-08-31 20:37:27 -04:00
parent a9be0efb2e
commit 58a582ff22
3 changed files with 27 additions and 8 deletions

View File

@ -41,6 +41,15 @@ DataContainer::InitCheck() const
return (fVolume != NULL ? B_OK : B_ERROR);
}
// GetCache
VMCache*
DataContainer::GetCache()
{
if (!_IsCacheMode())
_SwitchToCacheMode();
return fCache;
}
// Resize
status_t
DataContainer::Resize(off_t newSize)
@ -63,7 +72,7 @@ DataContainer::Resize(off_t newSize)
// grow
if (_RequiresCacheMode(newSize)) {
if (!_IsCacheMode())
error = _SwitchToCacheMode(fSize);
error = _SwitchToCacheMode();
if (error != B_OK)
return error;
@ -187,7 +196,7 @@ DataContainer::_CountBlocks() const
// _SwitchToCacheMode
status_t
DataContainer::_SwitchToCacheMode(size_t newBlockSize)
DataContainer::_SwitchToCacheMode()
{
status_t error = VMCacheFactory::CreateAnonymousCache(fCache, false, 0,
0, false, VM_PRIORITY_SYSTEM);
@ -195,9 +204,9 @@ DataContainer::_SwitchToCacheMode(size_t newBlockSize)
return error;
fCache->temporary = 1;
fCache->virtual_end = newBlockSize;
fCache->virtual_end = fSize;
error = fCache->Commit(newBlockSize, VM_PRIORITY_SYSTEM);
error = fCache->Commit(fSize, VM_PRIORITY_SYSTEM);
if (error != B_OK)
return error;

View File

@ -46,6 +46,8 @@ public:
status_t Resize(off_t newSize);
off_t GetSize() const { return fSize; }
VMCache* GetCache();
virtual status_t ReadAt(off_t offset, void *buffer, size_t size,
size_t *bytesRead);
virtual status_t WriteAt(off_t offset, const void *buffer, size_t size,
@ -57,7 +59,7 @@ public:
private:
inline bool _RequiresCacheMode(size_t size);
inline bool _IsCacheMode() const;
status_t _SwitchToCacheMode(size_t newBlockSize);
status_t _SwitchToCacheMode();
void _GetPages(off_t offset, off_t length, bool isWrite, vm_page** pages);
void _PutPages(off_t offset, off_t length, vm_page** pages, bool success);
status_t _DoCacheIO(const off_t offset, uint8* buffer, ssize_t length,

View File

@ -36,6 +36,7 @@
#include <fs_interface.h>
#include <fs_query.h>
#include <fs_volume.h>
#include <vfs.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include <TypeConstants.h>
@ -227,9 +228,9 @@ SET_ERROR(error, error);
}
// ramfs_read_vnode
// ramfs_get_vnode
static status_t
ramfs_read_vnode(fs_volume* _volume, ino_t vnid, fs_vnode* node, int* _type,
ramfs_get_vnode(fs_volume* _volume, ino_t vnid, fs_vnode* node, int* _type,
uint32* _flags, bool reenter)
{
// FUNCTION_START();
@ -889,6 +890,13 @@ ramfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
// truncate if requested
if (error == B_OK && (openMode & O_TRUNC))
error = node->SetSize(0);
// set cache in vnode
if (File *file = dynamic_cast<File*>(node)) {
struct vnode* vnode;
if (vfs_lookup_vnode(_volume->id, node->GetID(), &vnode) == B_OK) {
vfs_set_vnode_cache(vnode, file->GetCache());
}
}
NodeMTimeUpdater mTimeUpdater(node);
// set result / cleanup on failure
if (error == B_OK)
@ -2146,7 +2154,7 @@ fs_volume_ops gRamFSVolumeOps = {
&ramfs_read_fs_info,
&ramfs_write_fs_info,
&ramfs_sync,
&ramfs_read_vnode,
&ramfs_get_vnode,
/* index directory & index operations */
&ramfs_open_index_dir,