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;
// 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
virtual FileSystem& fs() const = 0;

View File

@ -81,4 +81,37 @@ namespace TmpFS
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 <luna/Atomic.h>
#include <luna/Badge.h>
#include <luna/Buffer.h>
#include <luna/StaticString.h>
#include <luna/Vector.h>
@ -58,10 +59,15 @@ namespace TmpFS
return m_inode_number;
}
Result<usize> read(u8*, usize, usize) const override;
Result<usize> write(const u8*, usize, usize) override;
virtual ~FileInode() = default;
private:
VFS::FileSystem* m_fs;
Buffer m_data_buffer;
usize m_inode_number;
};
@ -87,6 +93,16 @@ namespace TmpFS
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
{
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());
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 {};
}

View File

@ -15,7 +15,9 @@ class Buffer
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()
{
@ -27,6 +29,16 @@ class Buffer
return m_data;
}
u8* end()
{
return m_data + m_size;
}
const u8* end() const
{
return m_data + m_size;
}
usize size() const
{
return m_size;

View File

@ -32,9 +32,15 @@ Result<void> Buffer::try_resize(usize new_size)
return {};
}
Result<u8*> Buffer::create_slice_at_end(usize size)
Result<u8*> Buffer::slice_at_end(usize size)
{
usize old_size = m_size;
TRY(try_resize(m_size + 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;
}