From 70b3d70133936c2a61c1360882ccbd9396243e66 Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 30 Oct 2022 21:30:49 +0100 Subject: [PATCH] Initial TmpFS work --- kernel/include/fs/TmpFS.h | 51 ++++++++++++++++++++ kernel/src/fs/TmpFS.cpp | 99 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 kernel/include/fs/TmpFS.h create mode 100644 kernel/src/fs/TmpFS.cpp diff --git a/kernel/include/fs/TmpFS.h b/kernel/include/fs/TmpFS.h new file mode 100644 index 00000000..2a4bea96 --- /dev/null +++ b/kernel/include/fs/TmpFS.h @@ -0,0 +1,51 @@ +#pragma once +#include "fs/VFS.h" + +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); +} + +class TmpFS +{ + public: + VFS::Node* root() + { + return m_root; + } + + static TmpFS* create(const char* name); + static void release(TmpFS* fs); + + 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); + + void purge(); + + private: + struct File + { + char* buf; + size_t len; + int valid; + }; + + struct Directory + { + VFS::Node* buf; + size_t len; + int valid; + }; + + template struct Array + { + T* buf; + size_t len; + }; + + TmpFS(const char* name); + Array m_files; + Array m_dirs; + VFS::Node* m_root; +}; \ No newline at end of file diff --git a/kernel/src/fs/TmpFS.cpp b/kernel/src/fs/TmpFS.cpp new file mode 100644 index 00000000..2ad64036 --- /dev/null +++ b/kernel/src/fs/TmpFS.cpp @@ -0,0 +1,99 @@ +#include "fs/TmpFS.h" +#include "std/stdlib.h" +#include "std/string.h" + +ssize_t TmpFSImpl::read(VFS::Node* node, size_t offset, size_t size, char* buffer) +{ + if (!node) return -1; + if (!node->impl) return -1; + return ((TmpFS*)node->impl)->read(node, offset, size, buffer); +} + +ssize_t TmpFSImpl::write(VFS::Node* node, size_t offset, size_t size, char* buffer) +{ + if (!node) return -1; + if (!node->impl) return -1; + return ((TmpFS*)node->impl)->write(node, offset, size, buffer); +} + +TmpFS* TmpFS::create(const char* name) +{ + return new TmpFS(name); +} + +void TmpFS::release(TmpFS* fs) +{ + fs->purge(); + kfree(fs->m_dirs.buf); + delete fs->root(); + delete fs; +} + +extern uint64_t clock_now(); + +TmpFS::TmpFS(const char* name) +{ + m_root = new VFS::Node; + m_root->atime = m_root->ctime = m_root->mtime = clock_now(); + m_root->impl = (uint64_t)this; + m_root->inode = 0; + m_root->gid = m_root->uid = 0; + m_root->mode = 0755; + m_root->length = 0; + m_root->type = VFS_DIRECTORY; + m_root->tty = 0; + strlcpy(m_root->name, name, sizeof(m_root->name)); + m_dirs.buf = (Directory*)krealloc(nullptr, sizeof(Directory)); + m_dirs.len = 1; + m_dirs.buf[0] = {nullptr, 0, 1}; +} + +void TmpFS::purge() +{ + for (size_t i = 0; i < m_dirs.len; i++) + { + if (m_dirs.buf[i].valid && m_dirs.buf[i].len) kfree(m_dirs.buf[i].buf); + } + + m_dirs.buf = (Directory*)krealloc(m_dirs.buf, sizeof(Directory)); // leave space for the root directory + + for (size_t i = 0; i < m_files.len; i++) + { + if (m_files.buf[i].valid && m_files.buf[i].len) kfree(m_files.buf[i].buf); + } + + kfree(m_files.buf); +} + +ssize_t TmpFS::read(VFS::Node* node, size_t offset, size_t size, char* buffer) +{ + if (!node) return -1; + if (node->inode >= m_files.len) return -1; + File& file = m_files.buf[node->inode]; + if (!file.valid) return -1; + if (offset > file.len) return 0; + if (offset + size > file.len) { size = file.len - offset; } + memcpy(buffer, (void*)(file.buf + offset), size); + return size; +} + +ssize_t TmpFS::write(VFS::Node* node, size_t offset, size_t size, char* buffer) +{ + if (!node) return -1; + if (node->inode >= m_files.len) return -1; + File& file = m_files.buf[node->inode]; + if (!file.valid) return -1; + if (offset + size > file.len) + { + char* newbuf = (char*)krealloc(file.buf, offset + size); + if (!newbuf) { size = file.len - offset; } + else + { + file.buf = newbuf; + file.len = offset + size; + node->length = file.len; + } + } + memcpy((void*)(file.buf + offset), buffer, size); + return size; +} \ No newline at end of file