VFS: Support writing to files

This commit is contained in:
apio 2022-10-11 21:03:30 +02:00
parent f6e783ea45
commit e67ef7778c
4 changed files with 43 additions and 9 deletions

View File

@ -14,14 +14,20 @@ struct Descriptor
return m_can_read && m_is_open;
}
bool can_write()
{
return m_can_write && m_is_open;
}
void close()
{
m_is_open = false;
}
ssize_t read(size_t size, char* buffer);
ssize_t write(size_t size, const char* buffer);
void open(VFS::Node* node, bool can_read);
void open(VFS::Node* node, bool can_read, bool can_write);
Descriptor(const Descriptor& other);
Descriptor();
@ -29,6 +35,7 @@ struct Descriptor
private:
bool m_is_open;
bool m_can_read;
bool m_can_write;
VFS::Node* m_node;
uint64_t m_offset;
};

View File

@ -14,6 +14,7 @@ namespace VFS
struct Node;
typedef ssize_t (*node_read)(Node*, size_t, size_t, char*);
typedef ssize_t (*node_write)(Node*, size_t, size_t, const char*);
typedef Node* (*node_finddir)(Node*, const char*);
typedef int (*node_mkdir)(Node*, const char*);
@ -27,10 +28,12 @@ namespace VFS
node_read read_func;
node_finddir find_func;
node_mkdir mkdir_func;
node_write write_func;
Node* link;
};
ssize_t read(Node* node, size_t offset, size_t length, char* buffer);
ssize_t write(Node* node, size_t offset, size_t length, const char* buffer);
int mkdir(const char* path, const char* name); // FIXME: Support deducing this via a single path.
void mount_root(Node* root);

View File

@ -5,13 +5,15 @@ Descriptor::Descriptor() : m_is_open(false)
}
Descriptor::Descriptor(const Descriptor& other)
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_node(other.m_node), m_offset(other.m_offset)
: m_is_open(other.m_is_open), m_can_read(other.m_can_read), m_can_write(other.m_can_write), m_node(other.m_node),
m_offset(other.m_offset)
{
}
void Descriptor::open(VFS::Node* node, bool can_read)
void Descriptor::open(VFS::Node* node, bool can_read, bool can_write)
{
m_can_read = can_read;
m_can_write = can_write;
m_node = node;
m_offset = 0;
m_is_open = true;
@ -22,4 +24,11 @@ ssize_t Descriptor::read(size_t size, char* buffer)
ssize_t result = VFS::read(m_node, m_offset, size, buffer);
m_offset += result;
return result;
}
ssize_t Descriptor::write(size_t size, const char* buffer)
{
ssize_t result = VFS::write(m_node, m_offset, size, buffer);
m_offset += result;
return result;
}

View File

@ -26,12 +26,30 @@ ssize_t VFS::read(Node* node, size_t offset, size_t length, char* buffer)
return -1;
}
kdbgln("read(): node %s (inode %ld), offset %zd, %zd bytes, into %p", node->name, node->inode, offset, length,
(void*)buffer);
return node->read_func(node, offset, length, buffer);
}
ssize_t VFS::write(Node* node, size_t offset, size_t length, const char* buffer)
{
if (!node)
{
kwarnln("write() failed: trying to write to nullptr");
return -1;
}
if (node->type == VFS_DIRECTORY)
{
kwarnln("write() failed: is a directory");
return -EISDIR;
}
if (!node->write_func)
{
kwarnln("write() failed: the chosen node doesn't support writing");
return -1;
}
return node->write_func(node, offset, length, buffer);
}
void VFS::mount_root(Node* root)
{
if (!root)
@ -92,15 +110,12 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root)
}
if (child->flags & VFS_MOUNTPOINT)
{
kdbgln("Current node (%s, inode=%ld) is a mountpoint, resolving actual node", child->name,
child->inode);
if (!child->link)
{
kwarnln("Current node's link is null");
return 0;
}
child = child->link;
kdbgln("Resolved to %s (inode %ld)", child->name, child->inode);
}
current_node = child;
kfree(buffer);