VFS: Support writing to files
This commit is contained in:
parent
f6e783ea45
commit
e67ef7778c
@ -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;
|
||||||
};
|
};
|
@ -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);
|
||||||
|
@ -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;
|
||||||
@ -22,4 +24,11 @@ ssize_t Descriptor::read(size_t size, char* buffer)
|
|||||||
ssize_t result = VFS::read(m_node, m_offset, size, buffer);
|
ssize_t result = VFS::read(m_node, m_offset, size, 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;
|
||||||
}
|
}
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user