mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
vfs experiments 1
This commit is contained in:
@@ -4,11 +4,15 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include "LockGuard.hpp"
|
||||
#include "MemFs.hpp"
|
||||
#include "MountTable.hpp"
|
||||
#include "SerialTty.hpp"
|
||||
#include "SkipList.hpp"
|
||||
#include "String.hpp"
|
||||
#include "TestTemplates.hpp"
|
||||
#include "TtyManager.hpp"
|
||||
#include "VFSGlobals.hpp"
|
||||
#include "VFSTester.hpp"
|
||||
#include "VMA.hpp"
|
||||
#include "asserts.hpp"
|
||||
#include "globals.hpp"
|
||||
@@ -202,6 +206,12 @@ void user_task() {
|
||||
}
|
||||
}
|
||||
|
||||
void vfs_tester() {
|
||||
VFSTester vfsTester;
|
||||
vfsTester.test();
|
||||
remove_self();
|
||||
}
|
||||
|
||||
void ktask_main() {
|
||||
GlobalTtyManager.add_tty(new SerialTty());
|
||||
|
||||
@@ -214,6 +224,8 @@ void ktask_main() {
|
||||
new_ktask(templates_tester, "templates_tester");
|
||||
new_ktask(templates_tester, "templates_tester2");
|
||||
new_ktask(stress_tester, "stress_tester");
|
||||
VFSGlobals::mounts.add_mount(new MemFs(&VFSGlobals::root));
|
||||
new_ktask(vfs_tester, "vfs_tester");
|
||||
|
||||
for (int i = 0; i < saved_modules_size; i++) {
|
||||
GlobalTtyManager.all_tty_putstr("Starting ");
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "memman.hpp"
|
||||
#include "misc.hpp"
|
||||
|
||||
#include "FDT.hpp"
|
||||
|
||||
// Returns a free page frame in HHDM
|
||||
static uint64_t *get_free_frame() {
|
||||
uint64_t *res = static_cast<uint64_t *>(get4k());
|
||||
@@ -160,6 +162,10 @@ int AddressSpace::unmap(void *virt) {
|
||||
invlpg((void *) ((uint64_t) virt & 0x000FFFFFFFFFF000ULL));
|
||||
return 1;
|
||||
}
|
||||
FDT *AddressSpace::getFdt() {
|
||||
if (!_fdt) _fdt = new FDT();
|
||||
return _fdt;
|
||||
}
|
||||
|
||||
static volatile struct limine_kernel_address_request kernel_address_request = {
|
||||
.id = LIMINE_KERNEL_ADDRESS_REQUEST,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "PointersCollection.hpp"
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define KERN_V2P(a) ((((uintptr_t) (a) + kernel_phys_base) & ~kernel_virt_base))
|
||||
@@ -18,6 +20,8 @@
|
||||
#define HHDM_V2P(a) ((((uintptr_t) (a)) & ~HHDM_BEGIN))
|
||||
#define HHDM_P2V(a) ((((uintptr_t) (a)) | HHDM_BEGIN))
|
||||
|
||||
class FDT;
|
||||
|
||||
class AddressSpace {
|
||||
public:
|
||||
AddressSpace();
|
||||
@@ -36,9 +40,13 @@ public:
|
||||
return (uint64_t *) HHDM_V2P(PML4);
|
||||
}
|
||||
|
||||
FDT *getFdt();
|
||||
|
||||
private:
|
||||
// Pointer to PML4 in HDDM
|
||||
uint64_t *PML4;
|
||||
|
||||
FDT *_fdt = nullptr;
|
||||
};
|
||||
|
||||
extern AddressSpace *KERN_AddressSpace;
|
||||
|
||||
@@ -2,4 +2,5 @@ target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_sources(kernel.elf PRIVATE mutex.cpp cppsupport.cpp Spinlock.cpp LockGuard.cpp rand.cpp VMA.cpp asserts.cpp TtyManager.cpp Tty.cpp cv.cpp)
|
||||
|
||||
add_subdirectory(templates)
|
||||
add_subdirectory(templates)
|
||||
add_subdirectory(vfs)
|
||||
@@ -60,6 +60,10 @@ public:
|
||||
size++;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return tail == nullptr;
|
||||
}
|
||||
|
||||
T &back() {
|
||||
if (tail != nullptr) {
|
||||
assert(size > 0);
|
||||
@@ -69,6 +73,15 @@ public:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
const T &back() const {
|
||||
if (tail != nullptr) {
|
||||
assert(size > 0);
|
||||
return tail->val;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
if (!head) {
|
||||
assert(size == 0);
|
||||
|
||||
@@ -26,11 +26,13 @@ public:
|
||||
UniquePtr &operator=(UniquePtr const &other) = delete;
|
||||
|
||||
UniquePtr(UniquePtr &&other) {
|
||||
delete ptr;
|
||||
ptr = other.ptr;
|
||||
other.ptr = nullptr;
|
||||
}
|
||||
|
||||
UniquePtr &operator=(UniquePtr &&other) {
|
||||
delete ptr;
|
||||
ptr = other.ptr;
|
||||
other.ptr = nullptr;
|
||||
return *this;
|
||||
|
||||
@@ -276,6 +276,7 @@ public:
|
||||
while (curL > 0 &&
|
||||
root->next[curL] == nullptr)
|
||||
curL--;
|
||||
cur->data = V();
|
||||
nodeAllocator.push(cur);
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -11,59 +11,62 @@
|
||||
class String {
|
||||
public:
|
||||
String() noexcept {
|
||||
data = static_cast<char *>(kmalloc(1 * sizeof(char)));
|
||||
_data = static_cast<char *>(kmalloc(1 * sizeof(char)));
|
||||
curLen = 0;
|
||||
data[0] = '\0';
|
||||
_data[0] = '\0';
|
||||
}
|
||||
|
||||
String(const char *in) noexcept {
|
||||
curLen = strlen(in);
|
||||
|
||||
data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
|
||||
data[0] = '\0';
|
||||
_data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
|
||||
_data[0] = '\0';
|
||||
|
||||
strcat(data, in);
|
||||
strcat(_data, in);
|
||||
}
|
||||
|
||||
String(String const &str) noexcept {
|
||||
curLen = str.curLen;
|
||||
|
||||
data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
|
||||
data[0] = '\0';
|
||||
_data = static_cast<char *>(kmalloc((curLen + 1) * sizeof(char)));
|
||||
_data[0] = '\0';
|
||||
|
||||
strcat(data, str.data);
|
||||
strcat(_data, str._data);
|
||||
}
|
||||
|
||||
String(String &&str) noexcept {
|
||||
data = str.data;
|
||||
_data = str._data;
|
||||
curLen = str.curLen;
|
||||
str.data = nullptr;
|
||||
|
||||
str._data = static_cast<char *>(kmalloc(1 * sizeof(char)));
|
||||
str.curLen = 0;
|
||||
str._data[0] = '\0';
|
||||
}
|
||||
|
||||
String &operator=(String str) noexcept {
|
||||
std::swap(data, str.data);
|
||||
std::swap(_data, str._data);
|
||||
std::swap(curLen, str.curLen);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~String() noexcept {
|
||||
if (data == nullptr) return;
|
||||
kfree(data);
|
||||
data = nullptr;
|
||||
if (_data == nullptr) return;
|
||||
kfree(_data);
|
||||
_data = nullptr;
|
||||
curLen = 0;
|
||||
}
|
||||
|
||||
String &operator+=(String const &rhs) {
|
||||
data = static_cast<char *>(krealloc(data, sizeof(char) * (curLen + rhs.curLen + 1)));
|
||||
assert(data != nullptr);
|
||||
_data = static_cast<char *>(krealloc(_data, sizeof(char) * (curLen + rhs.curLen + 1)));
|
||||
assert(_data != nullptr);
|
||||
|
||||
strcat(data, rhs.data);
|
||||
strcat(_data, rhs._data);
|
||||
curLen += rhs.curLen;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &operator+=(int value) {
|
||||
String &operator+=(unsigned long value) {
|
||||
char buf[20];
|
||||
itoa(value, buf, 10);
|
||||
|
||||
@@ -71,9 +74,31 @@ public:
|
||||
|
||||
return *this;
|
||||
}
|
||||
String &operator+=(unsigned long long value) {
|
||||
char buf[32];
|
||||
itoa(value, buf, 10);
|
||||
|
||||
*this += buf;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &operator+=(char c) {
|
||||
_data = static_cast<char *>(krealloc(_data, sizeof(char) * (curLen + 2)));
|
||||
assert(_data != nullptr);
|
||||
|
||||
_data[curLen] = c;
|
||||
_data[curLen + 1] = '\0';
|
||||
curLen++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const char *c_str() const {
|
||||
return data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
char *data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t length() const {
|
||||
@@ -85,28 +110,28 @@ public:
|
||||
}
|
||||
|
||||
bool operator==(String const &rhs) const {
|
||||
return strcmp(data, rhs.data) == 0;
|
||||
return strcmp(_data, rhs._data) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(String const &rhs) const {
|
||||
return strcmp(data, rhs.data) != 0;
|
||||
return strcmp(_data, rhs._data) != 0;
|
||||
}
|
||||
|
||||
bool operator<(String const &rhs) const {
|
||||
return strcmp(data, rhs.data) < 0;
|
||||
return strcmp(_data, rhs._data) < 0;
|
||||
}
|
||||
|
||||
bool operator<=(String const &rhs) const {
|
||||
return strcmp(data, rhs.data) <= 0;
|
||||
return strcmp(_data, rhs._data) <= 0;
|
||||
}
|
||||
|
||||
bool operator>(String const &rhs) const {
|
||||
return strcmp(data, rhs.data) > 0;
|
||||
return strcmp(_data, rhs._data) > 0;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t curLen = 0;
|
||||
char *data;
|
||||
char *_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -119,6 +119,25 @@ public:
|
||||
bool empty() const {
|
||||
return curSize == 0;
|
||||
}
|
||||
T &back() {
|
||||
assert(size() != 0);
|
||||
return data[size() - 1];
|
||||
}
|
||||
|
||||
const T &back() const {
|
||||
assert(size() != 0);
|
||||
return data[size() - 1];
|
||||
}
|
||||
|
||||
Vector subvector(size_t start, size_t end) const {
|
||||
Vector out;
|
||||
if (start >= size()) return out;
|
||||
end = end > size() ? size() : end;
|
||||
for (size_t i = start; i < end; i++) {
|
||||
out.emplace_back(data[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t capacity = 2;
|
||||
|
||||
14
src/kernel/vfs/CMakeLists.txt
Normal file
14
src/kernel/vfs/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
target_include_directories(kernel.elf PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
target_sources(kernel.elf PRIVATE
|
||||
Node.cpp
|
||||
MemFs.cpp
|
||||
Filesystem.cpp
|
||||
MountTable.cpp
|
||||
Path.cpp
|
||||
VFSTester.cpp
|
||||
VFSApi.cpp
|
||||
FDT.cpp
|
||||
VFSGlobals.cpp
|
||||
File.cpp
|
||||
)
|
||||
43
src/kernel/vfs/FDT.cpp
Normal file
43
src/kernel/vfs/FDT.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "FDT.hpp"
|
||||
|
||||
#include "File.hpp"
|
||||
#include "MountTable.hpp"
|
||||
#include "PointersCollection.hpp"
|
||||
#include "VFSGlobals.hpp"
|
||||
#include "paging.hpp"
|
||||
|
||||
FDT::FD FDT::open(const Path &p) {
|
||||
if (auto n = VFSGlobals::root.traverse(p)) {
|
||||
_files.add(_cur_fd++, UniquePtr<File>(new File(n)));
|
||||
return _cur_fd - 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void FDT::close(FDT::FD fd) {
|
||||
if (auto f = _files.find(fd))
|
||||
if (!f->end)
|
||||
if (f->key == fd) {
|
||||
_files.erase(fd);
|
||||
}
|
||||
}
|
||||
File *FDT::get(FDT::FD fd) {
|
||||
if (auto f = _files.find(fd))
|
||||
if (!f->end)
|
||||
if (f->key == fd)
|
||||
return f->data.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FDT *FDT::current() {
|
||||
return cur_task()->addressSpace->getFdt();
|
||||
}
|
||||
FDHandle::FDHandle(FDT::FD fd) : _fd(fd) {
|
||||
}
|
||||
FDHandle::~FDHandle() {
|
||||
FDT::current()->close(_fd);
|
||||
}
|
||||
45
src/kernel/vfs/FDT.hpp
Normal file
45
src/kernel/vfs/FDT.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_FDT_HPP
|
||||
#define OS2_FDT_HPP
|
||||
|
||||
#include "Path.hpp"
|
||||
#include "PointersCollection.hpp"
|
||||
#include "SkipList.hpp"
|
||||
#include "mutex.hpp"
|
||||
|
||||
class File;
|
||||
class Node;
|
||||
|
||||
class FDT {
|
||||
public:
|
||||
using FD = int64_t;
|
||||
FD open(const Path &p);
|
||||
void close(FD fd);
|
||||
File *get(FD fd);
|
||||
|
||||
static FDT *current();
|
||||
|
||||
private:
|
||||
SkipList<FD, UniquePtr<File>> _files;
|
||||
int64_t _cur_fd = 10;
|
||||
Mutex _mtx;
|
||||
};
|
||||
|
||||
class FDHandle {
|
||||
public:
|
||||
FDHandle(FDT::FD fd);
|
||||
~FDHandle();
|
||||
FDHandle(const File &f) = delete;
|
||||
FDHandle &operator=(const File &o) = delete;
|
||||
|
||||
FDT::FD get() { return _fd; }
|
||||
|
||||
private:
|
||||
FDT::FD _fd;
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_FDT_HPP
|
||||
37
src/kernel/vfs/File.cpp
Normal file
37
src/kernel/vfs/File.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 24.02.2024.
|
||||
//
|
||||
|
||||
#include "File.hpp"
|
||||
|
||||
#include "Node.hpp"
|
||||
|
||||
File::File(Node *node) : _n(node) {
|
||||
_n->lock();
|
||||
}
|
||||
File::~File() {
|
||||
_n->unlock();
|
||||
}
|
||||
Node *File::node() {
|
||||
return _n;
|
||||
}
|
||||
NodeDir *File::dir() {
|
||||
if (_n && _n->type() == Node::DIR) return static_cast<NodeDir *>(_n);
|
||||
return nullptr;
|
||||
}
|
||||
NodeFile *File::file() {
|
||||
if (_n && _n->type() == Node::FILE) return static_cast<NodeFile *>(_n);
|
||||
return nullptr;
|
||||
}
|
||||
uint64_t File::seek(uint64_t pos) {
|
||||
_pos = pos;
|
||||
}
|
||||
uint64_t File::read(char *buf, uint64_t size) {
|
||||
if (file()) return file()->read(buf, _pos, size);
|
||||
}
|
||||
uint64_t File::write(const char *buf, uint64_t size) {
|
||||
if (file()) return file()->write(buf, _pos, size);
|
||||
}
|
||||
uint64_t File::size() {
|
||||
if (file()) return file()->size();
|
||||
}
|
||||
35
src/kernel/vfs/File.hpp
Normal file
35
src/kernel/vfs/File.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 24.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_FILE_HPP
|
||||
#define OS2_FILE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class Node;
|
||||
class NodeDir;
|
||||
class NodeFile;
|
||||
|
||||
class File {
|
||||
public:
|
||||
File(Node *n);
|
||||
~File();
|
||||
File(const File &f) = delete;
|
||||
File &operator=(const File &o) = delete;
|
||||
|
||||
Node *node();
|
||||
NodeDir *dir();
|
||||
NodeFile *file();
|
||||
|
||||
uint64_t seek(uint64_t pos);
|
||||
uint64_t read(char *buf, uint64_t size);
|
||||
uint64_t write(const char *buf, uint64_t size);
|
||||
uint64_t size();
|
||||
|
||||
private:
|
||||
Node *_n;
|
||||
uint64_t _pos = 0;
|
||||
};
|
||||
|
||||
#endif//OS2_FILE_HPP
|
||||
11
src/kernel/vfs/Filesystem.cpp
Normal file
11
src/kernel/vfs/Filesystem.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "Filesystem.hpp"
|
||||
|
||||
Filesystem::~Filesystem() = default;
|
||||
Filesystem::Filesystem(NodeDir *mounted_on) : _mounted_on(mounted_on) {
|
||||
assert(_mounted_on->type() == Node::DIR);
|
||||
_mounted_on->set_mounted(this);
|
||||
}
|
||||
21
src/kernel/vfs/Filesystem.hpp
Normal file
21
src/kernel/vfs/Filesystem.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_FILESYSTEM_HPP
|
||||
#define OS2_FILESYSTEM_HPP
|
||||
|
||||
#include "Node.hpp"
|
||||
|
||||
class Filesystem {
|
||||
public:
|
||||
Filesystem(NodeDir *mounted_on);
|
||||
|
||||
virtual NodeDir *root() = 0;
|
||||
virtual ~Filesystem() = 0;
|
||||
|
||||
NodeDir *_mounted_on;
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_FILESYSTEM_HPP
|
||||
50
src/kernel/vfs/MemFs.cpp
Normal file
50
src/kernel/vfs/MemFs.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "MemFs.hpp"
|
||||
#include "LockGuard.hpp"
|
||||
Vector<Node *> MemFs::MemFsNodeDir::children() {
|
||||
// assert(_lock.owner() == cur_task());
|
||||
|
||||
Vector<Node *> out;
|
||||
for (auto c: _children) {
|
||||
out.emplace_back(c.data);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) {
|
||||
assert(_lock.owner() == cur_task());
|
||||
auto newnode = new MemFsNodeDir();
|
||||
newnode->_name = name;
|
||||
_children.add(name, newnode);
|
||||
return newnode;
|
||||
}
|
||||
NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) {
|
||||
assert(_lock.owner() == cur_task());
|
||||
auto newfile = new MemFsNodeFile(name);
|
||||
_children.add(name, newfile);
|
||||
return newfile;
|
||||
}
|
||||
bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
|
||||
assert(_lock.owner() == cur_task());
|
||||
if (start >= _bytes.size()) return false;
|
||||
if (start + num > _bytes.size()) return false;
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
buf[i] = _bytes[start + i];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
|
||||
assert(_lock.owner() == cur_task());
|
||||
// fixme
|
||||
while (_bytes.size() <= start + num) _bytes.emplace_back(0);
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
_bytes[start + i] = buf[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
size_t MemFs::MemFsNodeFile::size() {
|
||||
return _bytes.size();
|
||||
}
|
||||
47
src/kernel/vfs/MemFs.hpp
Normal file
47
src/kernel/vfs/MemFs.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_MEMFS_HPP
|
||||
#define OS2_MEMFS_HPP
|
||||
|
||||
#include "Filesystem.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
#include "SkipList.hpp"
|
||||
#include "Vector.hpp"
|
||||
|
||||
class MemFs : public Filesystem {
|
||||
struct MemFsNodeDir : public NodeDir {
|
||||
public:
|
||||
Vector<Node *> children() override;
|
||||
NodeDir *mkdir(const String &name) override;
|
||||
NodeFile *mkfile(const String &name) override;
|
||||
|
||||
private:
|
||||
SkipList<String, Node *> _children;
|
||||
};
|
||||
|
||||
struct MemFsNodeFile : public NodeFile {
|
||||
public:
|
||||
MemFsNodeFile(const String &name) { _name = name; }
|
||||
|
||||
bool read(char *buf, size_t start, size_t num) override;
|
||||
bool write(const char *buf, size_t start, size_t num) override;
|
||||
size_t size() override;
|
||||
|
||||
private:
|
||||
Vector<uint8_t> _bytes;
|
||||
};
|
||||
|
||||
public:
|
||||
MemFs(NodeDir *mounted_on) : Filesystem(mounted_on) {}
|
||||
|
||||
NodeDir *root() override { return &_rootNode; }
|
||||
|
||||
private:
|
||||
MemFsNodeDir _rootNode;
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_MEMFS_HPP
|
||||
8
src/kernel/vfs/MountTable.cpp
Normal file
8
src/kernel/vfs/MountTable.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "MountTable.hpp"
|
||||
void MountTable::add_mount(Filesystem *fs) {
|
||||
_mounts.emplace_front(fs);
|
||||
}
|
||||
23
src/kernel/vfs/MountTable.hpp
Normal file
23
src/kernel/vfs/MountTable.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_MOUNTTABLE_HPP
|
||||
#define OS2_MOUNTTABLE_HPP
|
||||
|
||||
#include "String.hpp"
|
||||
|
||||
#include "Filesystem.hpp"
|
||||
#include "Node.hpp"
|
||||
#include "Path.hpp"
|
||||
|
||||
class MountTable {
|
||||
public:
|
||||
void add_mount(Filesystem *fs);
|
||||
|
||||
private:
|
||||
List<Filesystem *> _mounts;
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_MOUNTTABLE_HPP
|
||||
33
src/kernel/vfs/Node.cpp
Normal file
33
src/kernel/vfs/Node.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "LockGuard.hpp"
|
||||
|
||||
#include "Filesystem.hpp"
|
||||
|
||||
Node::~Node() = default;
|
||||
Node *Node::traverse(const Path &path) {
|
||||
// lock
|
||||
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
|
||||
if (nodeDir._mount) return nodeDir._mount->root()->traverse(path);
|
||||
if (path.empty()) return this;
|
||||
|
||||
if (_type == DIR) {
|
||||
// Horribly inefficient
|
||||
auto children = nodeDir.children();
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
if (children[i]->name() == path[0]) {
|
||||
return children[i]->traverse(path.subvector(1, path.size()));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void NodeDir::set_mounted(Filesystem *mount) {
|
||||
assert(_type == DIR);
|
||||
assert(_mount == nullptr);
|
||||
_mount = mount;
|
||||
}
|
||||
67
src/kernel/vfs/Node.hpp
Normal file
67
src/kernel/vfs/Node.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_NODE_HPP
|
||||
#define OS2_NODE_HPP
|
||||
|
||||
#include "List.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
#include "Path.hpp"
|
||||
#include "mutex.hpp"
|
||||
|
||||
class Filesystem;
|
||||
|
||||
class Node {
|
||||
public:
|
||||
enum Type {
|
||||
FILE,
|
||||
DIR,
|
||||
INVALID
|
||||
};
|
||||
virtual ~Node() = 0;
|
||||
|
||||
Type type() const { return _type; }
|
||||
const String &name() const { return _name; }
|
||||
virtual Node *traverse(const Path &path);
|
||||
|
||||
void lock() { _lock.lock(); }
|
||||
void unlock() { _lock.unlock(); }
|
||||
|
||||
protected:
|
||||
Node(Type type) : _type(type) {}
|
||||
|
||||
Type _type = Type::INVALID;
|
||||
|
||||
// This is uuugly
|
||||
Mutex _lock;
|
||||
String _name;
|
||||
Filesystem *_mount = nullptr;
|
||||
};
|
||||
|
||||
class NodeFile;
|
||||
|
||||
class NodeDir : public Node {
|
||||
public:
|
||||
virtual Vector<Node *> children() = 0;
|
||||
virtual NodeDir *mkdir(const String &name) = 0;
|
||||
virtual NodeFile *mkfile(const String &name) = 0;
|
||||
virtual void set_mounted(Filesystem *mount);
|
||||
|
||||
protected:
|
||||
NodeDir() : Node(Type::DIR) {}
|
||||
};
|
||||
|
||||
class NodeFile : public Node {
|
||||
public:
|
||||
virtual bool read(char *buf, size_t start, size_t num) = 0;
|
||||
virtual bool write(const char *buf, size_t start, size_t num) = 0;
|
||||
virtual size_t size() = 0;
|
||||
|
||||
protected:
|
||||
NodeFile() : Node(Type::FILE) {}
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_NODE_HPP
|
||||
21
src/kernel/vfs/Path.cpp
Normal file
21
src/kernel/vfs/Path.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "Path.hpp"
|
||||
Path StrToPath(const String &str) {
|
||||
if (str.length() == 0) return Path();
|
||||
Path out;
|
||||
String buf;
|
||||
for (size_t i = 0; i < str.length(); i++) {
|
||||
if (str.c_str()[i] == '/') {
|
||||
if (buf.length() > 0)
|
||||
out.emplace_back(std::move(buf));
|
||||
} else {
|
||||
buf += str.c_str()[i];
|
||||
}
|
||||
}
|
||||
if (buf.length() > 0)
|
||||
out.emplace_back(std::move(buf));
|
||||
return out;
|
||||
}
|
||||
16
src/kernel/vfs/Path.hpp
Normal file
16
src/kernel/vfs/Path.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_PATH_HPP
|
||||
#define OS2_PATH_HPP
|
||||
|
||||
#include "List.hpp"
|
||||
#include "String.hpp"
|
||||
#include "Vector.hpp"
|
||||
|
||||
using Path = Vector<String>;
|
||||
|
||||
Path StrToPath(const String &str);
|
||||
|
||||
#endif//OS2_PATH_HPP
|
||||
37
src/kernel/vfs/VFSApi.cpp
Normal file
37
src/kernel/vfs/VFSApi.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "VFSApi.hpp"
|
||||
|
||||
#include "File.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
bool VFSApi::mkdir(const Path &path) {
|
||||
auto root = path.subvector(0, path.size() - 1);
|
||||
FDHandle root_fd = FDHandle(FDT::current()->open(root));
|
||||
if (root_fd.get() == -1) return false;
|
||||
File *root_f = FDT::current()->get(root_fd.get());
|
||||
if (!root_f->dir()) return false;
|
||||
root_f->dir()->mkdir(path.back());
|
||||
return true;
|
||||
}
|
||||
bool VFSApi::touch(const Path &path) {
|
||||
auto root = path.subvector(0, path.size() - 1);
|
||||
FDHandle root_fd = FDHandle(FDT::current()->open(root));
|
||||
if (root_fd.get() == -1) return false;
|
||||
File *root_f = FDT::current()->get(root_fd.get());
|
||||
if (!root_f->dir()) return false;
|
||||
root_f->dir()->mkfile(path.back());
|
||||
return true;
|
||||
}
|
||||
|
||||
FDT::FD VFSApi::open(const Path &path) {
|
||||
return FDT::current()->open(path);
|
||||
}
|
||||
void VFSApi::close(FDT::FD fd) {
|
||||
return FDT::current()->close(fd);
|
||||
}
|
||||
File *VFSApi::get(FDT::FD fd) {
|
||||
return FDT::current()->get(fd);
|
||||
}
|
||||
23
src/kernel/vfs/VFSApi.hpp
Normal file
23
src/kernel/vfs/VFSApi.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_VFSAPI_HPP
|
||||
#define OS2_VFSAPI_HPP
|
||||
|
||||
|
||||
#include "FDT.hpp"
|
||||
#include "Path.hpp"
|
||||
|
||||
namespace VFSApi {
|
||||
bool mkdir(const Path &path);
|
||||
bool touch(const Path &path);
|
||||
|
||||
FDT::FD open(const Path &path);
|
||||
File *get(FDT::FD fd);
|
||||
void close(FDT::FD fd);
|
||||
|
||||
};// namespace VFSApi
|
||||
|
||||
|
||||
#endif//OS2_VFSAPI_HPP
|
||||
21
src/kernel/vfs/VFSGlobals.cpp
Normal file
21
src/kernel/vfs/VFSGlobals.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 24.02.2024.
|
||||
//
|
||||
|
||||
#include "VFSGlobals.hpp"
|
||||
Vector<Node *> RootNode::children() {
|
||||
assert(false);
|
||||
return {};
|
||||
}
|
||||
NodeDir *RootNode::mkdir(const String &name) {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
NodeFile *RootNode::mkfile(const String &name) {
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
RootNode VFSGlobals::root;
|
||||
MountTable VFSGlobals::mounts;
|
||||
24
src/kernel/vfs/VFSGlobals.hpp
Normal file
24
src/kernel/vfs/VFSGlobals.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 24.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_VFSGLOBALS_HPP
|
||||
#define OS2_VFSGLOBALS_HPP
|
||||
|
||||
#include "MountTable.hpp"
|
||||
#include "Node.hpp"
|
||||
|
||||
class RootNode : public NodeDir {
|
||||
public:
|
||||
Vector<Node *> children() override;
|
||||
NodeDir *mkdir(const String &name) override;
|
||||
NodeFile *mkfile(const String &name) override;
|
||||
};
|
||||
|
||||
namespace VFSGlobals {
|
||||
extern RootNode root;
|
||||
extern MountTable mounts;
|
||||
};// namespace VFSGlobals
|
||||
|
||||
|
||||
#endif//OS2_VFSGLOBALS_HPP
|
||||
42
src/kernel/vfs/VFSTester.cpp
Normal file
42
src/kernel/vfs/VFSTester.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#include "VFSTester.hpp"
|
||||
|
||||
#include "File.hpp"
|
||||
#include "VFSApi.hpp"
|
||||
|
||||
void VFSTester::test() {
|
||||
VFSApi::mkdir(StrToPath("/hello"));
|
||||
VFSApi::mkdir(StrToPath("/hello/hellod2"));
|
||||
VFSApi::touch(StrToPath("/hellof"));
|
||||
VFSApi::touch(StrToPath("/hello/f2"));
|
||||
|
||||
FDT::FD a = VFSApi::open(StrToPath("/hello"));
|
||||
FDT::FD b = VFSApi::open(StrToPath("/hello/hellod2"));
|
||||
FDT::FD c = VFSApi::open(StrToPath("/hellof"));
|
||||
FDT::FD d = VFSApi::open(StrToPath("/hello/f2"));
|
||||
{
|
||||
String t("hello wooooorld");
|
||||
File *cf = VFSApi::get(c);
|
||||
cf->write(t.c_str(), t.length() + 1);
|
||||
}
|
||||
assert(a != -1);
|
||||
assert(b != -1);
|
||||
assert(c != -1);
|
||||
assert(d != -1);
|
||||
VFSApi::close(a);
|
||||
VFSApi::close(b);
|
||||
VFSApi::close(c);
|
||||
VFSApi::close(d);
|
||||
|
||||
c = VFSApi::open(StrToPath("/hellof"));
|
||||
assert(c != -1);
|
||||
{
|
||||
String t("aaaaaaaaaaaaaaaaaaaa");
|
||||
File *cf = VFSApi::get(c);
|
||||
cf->read(t.data(), cf->size());
|
||||
assert(t == "hello wooooorld");
|
||||
}
|
||||
}
|
||||
15
src/kernel/vfs/VFSTester.hpp
Normal file
15
src/kernel/vfs/VFSTester.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by Stepan Usatiuk on 23.02.2024.
|
||||
//
|
||||
|
||||
#ifndef OS2_VFSTESTER_HPP
|
||||
#define OS2_VFSTESTER_HPP
|
||||
|
||||
|
||||
class VFSTester {
|
||||
public:
|
||||
void test();
|
||||
};
|
||||
|
||||
|
||||
#endif//OS2_VFSTESTER_HPP
|
||||
Reference in New Issue
Block a user