More tmpfs stuff but mkdir corrupts the system

This commit is contained in:
apio 2022-10-31 09:53:37 +01:00
parent 70b3d70133
commit bc48b64ec6
5 changed files with 135 additions and 7 deletions

View File

@ -5,6 +5,9 @@ namespace TmpFSImpl
{ {
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer); ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer);
VFS::Node* find(VFS::Node* node, const char* filename);
VFS::Node* readdir(VFS::Node* node, long index);
int mkdir(VFS::Node* node, const char* filename, mode_t mode);
} }
class TmpFS class TmpFS
@ -21,6 +24,11 @@ class TmpFS
ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer); ssize_t read(VFS::Node* node, size_t offset, size_t size, char* buffer);
ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer); ssize_t write(VFS::Node* node, size_t offset, size_t size, char* buffer);
VFS::Node* find(VFS::Node* node, const char* filename);
VFS::Node* readdir(VFS::Node* node, long index);
int mkdir(VFS::Node* node, const char* filename, mode_t mode);
void purge(); void purge();
private: private:

View File

@ -1,4 +1,8 @@
#define MODULE "tmpfs"
#include "fs/TmpFS.h" #include "fs/TmpFS.h"
#include "log/Log.h"
#include "std/errno.h"
#include "std/stdlib.h" #include "std/stdlib.h"
#include "std/string.h" #include "std/string.h"
@ -16,6 +20,27 @@ ssize_t TmpFSImpl::write(VFS::Node* node, size_t offset, size_t size, char* buff
return ((TmpFS*)node->impl)->write(node, offset, size, buffer); return ((TmpFS*)node->impl)->write(node, offset, size, buffer);
} }
VFS::Node* TmpFSImpl::find(VFS::Node* node, const char* filename)
{
if (!node) return 0;
if (!node->impl) return 0;
return ((TmpFS*)node->impl)->find(node, filename);
}
VFS::Node* TmpFSImpl::readdir(VFS::Node* node, long index)
{
if (!node) return 0;
if (!node->impl) return 0;
return ((TmpFS*)node->impl)->readdir(node, index);
}
int TmpFSImpl::mkdir(VFS::Node* node, const char* filename, mode_t mode)
{
if (!node) return -1;
if (!node->impl) return -1;
return ((TmpFS*)node->impl)->mkdir(node, filename, mode);
}
TmpFS* TmpFS::create(const char* name) TmpFS* TmpFS::create(const char* name)
{ {
return new TmpFS(name); return new TmpFS(name);
@ -42,6 +67,10 @@ TmpFS::TmpFS(const char* name)
m_root->length = 0; m_root->length = 0;
m_root->type = VFS_DIRECTORY; m_root->type = VFS_DIRECTORY;
m_root->tty = 0; m_root->tty = 0;
m_root->readdir_func = TmpFSImpl::readdir;
m_root->find_func = TmpFSImpl::find;
m_root->mkdir_func = TmpFSImpl::mkdir;
m_root->flags = 0;
strlcpy(m_root->name, name, sizeof(m_root->name)); strlcpy(m_root->name, name, sizeof(m_root->name));
m_dirs.buf = (Directory*)krealloc(nullptr, sizeof(Directory)); m_dirs.buf = (Directory*)krealloc(nullptr, sizeof(Directory));
m_dirs.len = 1; m_dirs.len = 1;
@ -96,4 +125,83 @@ ssize_t TmpFS::write(VFS::Node* node, size_t offset, size_t size, char* buffer)
} }
memcpy((void*)(file.buf + offset), buffer, size); memcpy((void*)(file.buf + offset), buffer, size);
return size; return size;
}
VFS::Node* TmpFS::find(VFS::Node* node, const char* filename)
{
if (!node) return 0;
if (node->inode >= m_dirs.len) return 0;
Directory& dir = m_dirs.buf[node->inode];
if (!dir.valid) return 0;
for (size_t i = 0; i < dir.len; i++)
{
if (!strncmp(dir.buf[i].name, filename, sizeof(dir.buf[i].name))) { return &dir.buf[i]; }
}
return 0;
}
VFS::Node* TmpFS::readdir(VFS::Node* node, long index)
{
if (!node) return 0;
if (node->inode >= m_dirs.len) return 0;
Directory& dir = m_dirs.buf[node->inode];
if (!dir.valid) return 0;
if (index >= (long)dir.len) return 0;
return &dir.buf[index];
}
int TmpFS::mkdir(VFS::Node* node, const char* filename, mode_t mode)
{
kinfoln("starting to create directory %s in %s", filename, node->name);
if (!node) return 0;
if (node->inode >= m_dirs.len) return 0;
Directory& dir = m_dirs.buf[node->inode];
if (!dir.valid) return 0;
kinfoln("creating directory %s in %s", filename, node->name);
size_t new_len = m_dirs.len + 1;
Directory* new_buf = (Directory*)krealloc(m_dirs.buf, new_len);
if (!new_buf) return -ENOMEM;
m_dirs.len = new_len;
m_dirs.buf = new_buf;
uint64_t new_inode = m_dirs.len - 1;
m_dirs.buf[new_inode].valid = 0;
size_t new_dir_len = dir.len + 1;
VFS::Node* new_dir_buf = (VFS::Node*)krealloc(dir.buf, new_dir_len);
if (!new_dir_buf) return -ENOMEM;
m_dirs.buf[new_inode].valid = 1;
m_dirs.buf[new_inode].len = 0;
m_dirs.buf[new_inode].buf = nullptr;
dir.buf = new_dir_buf;
dir.len = new_dir_len;
node->mtime = clock_now();
node->ctime = clock_now();
node->length++;
VFS::Node* new_node = &dir.buf[dir.len - 1];
new_node->inode = new_inode;
new_node->atime = new_node->ctime = new_node->mtime = clock_now();
new_node->impl = (uint64_t)this;
new_node->gid = new_node->uid = 0;
new_node->mode = mode;
new_node->length = 0;
new_node->type = VFS_DIRECTORY;
new_node->tty = 0;
new_node->readdir_func = TmpFSImpl::readdir;
new_node->find_func = TmpFSImpl::find;
new_node->mkdir_func = TmpFSImpl::mkdir;
new_node->flags = 0;
strlcpy(new_node->name, filename, sizeof(new_node->name));
return 0;
} }

View File

@ -25,12 +25,12 @@ ssize_t VFS::read(Node* node, size_t offset, size_t length, char* buffer)
} }
if (node->type == VFS_DIRECTORY) if (node->type == VFS_DIRECTORY)
{ {
kwarnln("read() failed: is a directory"); kwarnln("read() failed for %s: is a directory", node->name);
return -EISDIR; return -EISDIR;
} }
if (!node->read_func) if (!node->read_func)
{ {
kwarnln("read() failed: the chosen node doesn't support reading"); kwarnln("read() failed for %s: the chosen node doesn't support reading", node->name);
return -1; return -1;
} }
@ -46,12 +46,12 @@ ssize_t VFS::write(Node* node, size_t offset, size_t length, const char* buffer)
} }
if (node->type == VFS_DIRECTORY) if (node->type == VFS_DIRECTORY)
{ {
kwarnln("write() failed: is a directory"); kwarnln("write() failed for %s: is a directory", node->name);
return -EISDIR; return -EISDIR;
} }
if (!node->write_func) if (!node->write_func)
{ {
kwarnln("write() failed: the chosen node doesn't support writing"); kwarnln("write() failed for %s: the chosen node doesn't support writing", node->name);
return -1; return -1;
} }
@ -107,7 +107,7 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root)
buffer[path_section_size] = 0; buffer[path_section_size] = 0;
if (!current_node->find_func) if (!current_node->find_func)
{ {
kwarnln("Current node has no way to find child nodes"); kwarnln("Current node %s has no way to find child nodes", current_node->name);
return 0; return 0;
} }
Node* child = current_node->find_func(current_node, buffer); Node* child = current_node->find_func(current_node, buffer);
@ -239,8 +239,16 @@ bool VFS::exists(const char* pathname)
void VFS::mount(Node* mountpoint, Node* mounted) void VFS::mount(Node* mountpoint, Node* mounted)
{ {
if (!mountpoint || !mounted) return; if (!mountpoint || !mounted)
if (mountpoint->flags & VFS_MOUNTPOINT || mounted->flags & VFS_MOUNTPOINT) return; {
kinfoln("mount failed: invalid pointers");
return;
}
if (mountpoint->flags & VFS_MOUNTPOINT || mounted->flags & VFS_MOUNTPOINT)
{
kinfoln("mount failed: already a mountpoint");
return;
}
mountpoint->link = mounted; mountpoint->link = mounted;
mountpoint->flags |= VFS_MOUNTPOINT; mountpoint->flags |= VFS_MOUNTPOINT;
} }

View File

@ -2,6 +2,7 @@
#include "config.h" #include "config.h"
#include "cpu/CPU.h" #include "cpu/CPU.h"
#include "fs/TmpFS.h"
#include "fs/devices/DeviceFS.h" #include "fs/devices/DeviceFS.h"
#include "gdt/GDT.h" #include "gdt/GDT.h"
#include "init/Init.h" #include "init/Init.h"
@ -69,6 +70,8 @@ extern "C" void _start()
ASSERT(VFS::mkdir("/dev") == 0); ASSERT(VFS::mkdir("/dev") == 0);
VFS::mount("/dev", DeviceFS::get()); VFS::mount("/dev", DeviceFS::get());
ASSERT(VFS::mkdir("/tmp") == 0);
VFS::mount("/tmp", TmpFS::create("tmp")->root());
Init::finish_kernel_boot(); Init::finish_kernel_boot();

View File

@ -43,6 +43,7 @@ template <typename Callback> void sched_for_each_task(Callback callback)
bool will_continue = callback(task); bool will_continue = callback(task);
if (!will_continue) break; if (!will_continue) break;
task = task->next_task; task = task->next_task;
if (!task) break;
} while (task != base_task); } while (task != base_task);
} }