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; return m_can_read && m_is_open;
} }
bool can_write()
{
return m_can_write && m_is_open;
}
void close() void close()
{ {
m_is_open = false; m_is_open = false;
} }
ssize_t read(size_t size, char* buffer); 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(const Descriptor& other);
Descriptor(); Descriptor();
@ -29,6 +35,7 @@ struct Descriptor
private: private:
bool m_is_open; bool m_is_open;
bool m_can_read; bool m_can_read;
bool m_can_write;
VFS::Node* m_node; VFS::Node* m_node;
uint64_t m_offset; uint64_t m_offset;
}; };

View File

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

View File

@ -5,13 +5,15 @@ Descriptor::Descriptor() : m_is_open(false)
} }
Descriptor::Descriptor(const Descriptor& other) 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_read = can_read;
m_can_write = can_write;
m_node = node; m_node = node;
m_offset = 0; m_offset = 0;
m_is_open = true; m_is_open = true;
@ -23,3 +25,10 @@ ssize_t Descriptor::read(size_t size, char* buffer)
m_offset += result; m_offset += result;
return 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; 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); 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) void VFS::mount_root(Node* root)
{ {
if (!root) if (!root)
@ -92,15 +110,12 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root)
} }
if (child->flags & VFS_MOUNTPOINT) if (child->flags & VFS_MOUNTPOINT)
{ {
kdbgln("Current node (%s, inode=%ld) is a mountpoint, resolving actual node", child->name,
child->inode);
if (!child->link) if (!child->link)
{ {
kwarnln("Current node's link is null"); kwarnln("Current node's link is null");
return 0; return 0;
} }
child = child->link; child = child->link;
kdbgln("Resolved to %s (inode %ld)", child->name, child->inode);
} }
current_node = child; current_node = child;
kfree(buffer); kfree(buffer);