tmpfs: Implement FileInode read() and write()
This commit is contained in:
parent
89bea931cd
commit
e5a41d2d52
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user