From bc48b64ec66ec0afd62407300e32308a229905eb Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 31 Oct 2022 09:53:37 +0100 Subject: [PATCH] More tmpfs stuff but mkdir corrupts the system --- kernel/include/fs/TmpFS.h | 8 +++ kernel/src/fs/TmpFS.cpp | 108 ++++++++++++++++++++++++++++++++ kernel/src/fs/VFS.cpp | 22 ++++--- kernel/src/main.cpp | 3 + kernel/src/thread/Scheduler.cpp | 1 + 5 files changed, 135 insertions(+), 7 deletions(-) diff --git a/kernel/include/fs/TmpFS.h b/kernel/include/fs/TmpFS.h index 2a4bea96..4411389e 100644 --- a/kernel/include/fs/TmpFS.h +++ b/kernel/include/fs/TmpFS.h @@ -5,6 +5,9 @@ namespace TmpFSImpl { 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); + 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 @@ -21,6 +24,11 @@ class TmpFS 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); + 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(); private: diff --git a/kernel/src/fs/TmpFS.cpp b/kernel/src/fs/TmpFS.cpp index 2ad64036..e6567d02 100644 --- a/kernel/src/fs/TmpFS.cpp +++ b/kernel/src/fs/TmpFS.cpp @@ -1,4 +1,8 @@ +#define MODULE "tmpfs" + #include "fs/TmpFS.h" +#include "log/Log.h" +#include "std/errno.h" #include "std/stdlib.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); } +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) { return new TmpFS(name); @@ -42,6 +67,10 @@ TmpFS::TmpFS(const char* name) m_root->length = 0; m_root->type = VFS_DIRECTORY; 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)); m_dirs.buf = (Directory*)krealloc(nullptr, sizeof(Directory)); 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); 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; } \ No newline at end of file diff --git a/kernel/src/fs/VFS.cpp b/kernel/src/fs/VFS.cpp index ef0deae2..0a61980a 100644 --- a/kernel/src/fs/VFS.cpp +++ b/kernel/src/fs/VFS.cpp @@ -25,12 +25,12 @@ ssize_t VFS::read(Node* node, size_t offset, size_t length, char* buffer) } if (node->type == VFS_DIRECTORY) { - kwarnln("read() failed: is a directory"); + kwarnln("read() failed for %s: is a directory", node->name); return -EISDIR; } 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; } @@ -46,12 +46,12 @@ ssize_t VFS::write(Node* node, size_t offset, size_t length, const char* buffer) } if (node->type == VFS_DIRECTORY) { - kwarnln("write() failed: is a directory"); + kwarnln("write() failed for %s: is a directory", node->name); return -EISDIR; } 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; } @@ -107,7 +107,7 @@ VFS::Node* VFS::resolve_path(const char* filename, Node* root) buffer[path_section_size] = 0; 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; } 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) { - if (!mountpoint || !mounted) return; - if (mountpoint->flags & VFS_MOUNTPOINT || mounted->flags & VFS_MOUNTPOINT) return; + if (!mountpoint || !mounted) + { + 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->flags |= VFS_MOUNTPOINT; } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index ab5c3751..131b7ab8 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -2,6 +2,7 @@ #include "config.h" #include "cpu/CPU.h" +#include "fs/TmpFS.h" #include "fs/devices/DeviceFS.h" #include "gdt/GDT.h" #include "init/Init.h" @@ -69,6 +70,8 @@ extern "C" void _start() ASSERT(VFS::mkdir("/dev") == 0); VFS::mount("/dev", DeviceFS::get()); + ASSERT(VFS::mkdir("/tmp") == 0); + VFS::mount("/tmp", TmpFS::create("tmp")->root()); Init::finish_kernel_boot(); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 8248095d..11365c22 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -43,6 +43,7 @@ template void sched_for_each_task(Callback callback) bool will_continue = callback(task); if (!will_continue) break; task = task->next_task; + if (!task) break; } while (task != base_task); }