tmpfs: Implement FileInode read() and write()

This commit is contained in:
apio 2023-03-11 00:52:39 +01:00
parent 89bea931cd
commit e5a41d2d52
Signed by: apio
GPG Key ID: B8A7D06E42258954
6 changed files with 82 additions and 2 deletions

View File

@ -21,6 +21,11 @@ namespace VFS
virtual Result<SharedPtr<Inode>> create_subdirectory(const char* name) = 0; virtual Result<SharedPtr<Inode>> create_subdirectory(const char* name) = 0;
// File-specific methods
virtual Result<usize> read(u8* buf, usize offset, usize length) const = 0;
virtual Result<usize> write(const u8* buf, usize offset, usize length) = 0;
// Generic methods // Generic methods
virtual FileSystem& fs() const = 0; virtual FileSystem& fs() const = 0;

View File

@ -81,4 +81,37 @@ namespace TmpFS
return inode; return inode;
} }
Result<usize> FileInode::read(u8* buf, usize offset, usize length) const
{
if (length == 0) return 0;
if (offset > m_data_buffer.size()) return 0;
if (offset + length > m_data_buffer.size()) length = m_data_buffer.size() - offset;
memcpy(buf, m_data_buffer.data() + offset, length);
return length;
}
Result<usize> FileInode::write(const u8* buf, usize offset, usize length)
{
if (length == 0) return 0;
if (offset > m_data_buffer.size())
{
// Fill the in-between space with zeroes.
usize old_size = m_data_buffer.size();
usize zeroes = offset - old_size;
TRY(m_data_buffer.try_resize(offset));
memset(m_data_buffer.data() + old_size, 0, zeroes);
}
u8* slice = TRY(m_data_buffer.slice(offset, length));
memcpy(slice, buf, length);
return length;
}
} }

View File

@ -2,6 +2,7 @@
#include "fs/VFS.h" #include "fs/VFS.h"
#include <luna/Atomic.h> #include <luna/Atomic.h>
#include <luna/Badge.h> #include <luna/Badge.h>
#include <luna/Buffer.h>
#include <luna/StaticString.h> #include <luna/StaticString.h>
#include <luna/Vector.h> #include <luna/Vector.h>
@ -58,10 +59,15 @@ namespace TmpFS
return m_inode_number; return m_inode_number;
} }
Result<usize> read(u8*, usize, usize) const override;
Result<usize> write(const u8*, usize, usize) override;
virtual ~FileInode() = default; virtual ~FileInode() = default;
private: private:
VFS::FileSystem* m_fs; VFS::FileSystem* m_fs;
Buffer m_data_buffer;
usize m_inode_number; usize m_inode_number;
}; };
@ -87,6 +93,16 @@ namespace TmpFS
Result<SharedPtr<VFS::Inode>> find(const char* name) const override; Result<SharedPtr<VFS::Inode>> find(const char* name) const override;
Result<usize> read(u8*, usize, usize) const override
{
return err(EISDIR);
}
Result<usize> write(const u8*, usize, usize) override
{
return err(EISDIR);
}
VFS::FileSystem& fs() const override VFS::FileSystem& fs() const override
{ {
return *m_fs; return *m_fs;

View File

@ -75,6 +75,14 @@ static Result<void> try_init_vfs()
kinfoln("/etc/passwd's inode number: %zu", passwd.inode_number()); kinfoln("/etc/passwd's inode number: %zu", passwd.inode_number());
const char* data = "hello, world!";
TRY(passwd.write((const u8*)data, 0, 14));
char output[14];
TRY(passwd.read((u8*)output, 0, 14));
kinfoln("/etc/passwd contents: '%s'", output);
return {}; return {};
} }

View File

@ -15,7 +15,9 @@ class Buffer
Result<void> try_resize(usize new_size); Result<void> try_resize(usize new_size);
Result<u8*> create_slice_at_end(usize size); Result<u8*> slice_at_end(usize size);
Result<u8*> slice(usize offset, usize size);
u8* data() u8* data()
{ {
@ -27,6 +29,16 @@ class Buffer
return m_data; return m_data;
} }
u8* end()
{
return m_data + m_size;
}
const u8* end() const
{
return m_data + m_size;
}
usize size() const usize size() const
{ {
return m_size; return m_size;

View File

@ -32,9 +32,15 @@ Result<void> Buffer::try_resize(usize new_size)
return {}; return {};
} }
Result<u8*> Buffer::create_slice_at_end(usize size) Result<u8*> Buffer::slice_at_end(usize size)
{ {
usize old_size = m_size; usize old_size = m_size;
TRY(try_resize(m_size + size)); TRY(try_resize(m_size + size));
return m_data + old_size; return m_data + old_size;
} }
Result<u8*> Buffer::slice(usize offset, usize size)
{
if (offset + size > m_size) { TRY(try_resize(offset + size)); }
return m_data + offset;
}