More reasonable pointers, file nodes

This commit is contained in:
2024-04-07 18:36:06 +02:00
parent 9e53a0de33
commit ad273d0a96
20 changed files with 364 additions and 110 deletions

2
run.sh
View File

@@ -2,7 +2,7 @@
POSITIONAL_ARGS=() POSITIONAL_ARGS=()
QEMU_OPTS=" -no-reboot " QEMU_OPTS=" -no-reboot -m 256M"
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in

View File

@@ -9,7 +9,7 @@
extern volatile struct limine_module_request module_request; extern volatile struct limine_module_request module_request;
static constexpr unsigned max_saved_modules = 2; static constexpr unsigned max_saved_modules = 4;
static constexpr unsigned max_saved_module_name = 256; static constexpr unsigned max_saved_module_name = 256;
void limine_modules_remap(); void limine_modules_remap();

View File

@@ -88,32 +88,12 @@ uint64_t syscall_close(uint64_t FD) {
//FIXME: //FIXME:
uint64_t syscall_read(uint64_t fd, char *buf, uint64_t len) { uint64_t syscall_read(uint64_t fd, char *buf, uint64_t len) {
if (fd == 0) {
auto c = buf;
while ((c - buf) < len) {
*c = GlobalTtyManager.get_tty(0)->readchar();
if (*c == '\r') {
*(c++) = '\n';
break;
}
c++;
}
return (c - buf);
}
auto f = FDT::current()->get(fd); auto f = FDT::current()->get(fd);
if (!f) return -1; if (!f) return -1;
return f->read(buf, len); return f->read(buf, len);
} }
uint64_t syscall_write(uint64_t fd, const char *buf, uint64_t len) { uint64_t syscall_write(uint64_t fd, const char *buf, uint64_t len) {
if (fd == 1) {
auto c = buf;
while (*c != '\0' && (c - buf) < len) {
GlobalTtyManager.all_tty_putchar(*c);
c++;
}
return len;
}
auto f = FDT::current()->get(fd); auto f = FDT::current()->get(fd);
if (!f) return -1; if (!f) return -1;
return f->write(buf, len); return f->write(buf, len);

View File

@@ -2,8 +2,10 @@
#define POINTERS_H #define POINTERS_H
#include <atomic> #include <atomic>
#include <optional>
#include <utility> #include <utility>
#include "asserts.hpp"
#include "kmem.hpp" #include "kmem.hpp"
class SharedPtrTester; class SharedPtrTester;
@@ -55,6 +57,78 @@ private:
T *ptr = nullptr; T *ptr = nullptr;
}; };
struct SharedPtr_Base {
struct UsesBlock {
int32_t _uses_ctl;
int32_t _uses_obj;
} __attribute__((packed));
std::atomic<UsesBlock> _uses;
static_assert(decltype(_uses)::is_always_lock_free);
// Increments control block use counter
void weak_lock() {
UsesBlock old_uses = _uses.load();
UsesBlock new_uses;
do {
assert(old_uses._uses_ctl >= 1);
new_uses = old_uses;
new_uses._uses_ctl++;
} while (!_uses.compare_exchange_weak(old_uses, new_uses));
}
// Decrements control block use counter
// Returns true if it was deleted
bool weak_release() {
UsesBlock old_uses = _uses.load();
UsesBlock new_uses;
do {
new_uses = old_uses;
new_uses._uses_ctl--;
} while (!_uses.compare_exchange_weak(old_uses, new_uses));
if (new_uses._uses_ctl == 0)
delete this;
return new_uses._uses_ctl == 0;
}
// Increments control and object use counter
// Returns false if the object was already deleted
bool strong_lock() {
UsesBlock old_uses = _uses.load();
UsesBlock new_uses;
do {
if (old_uses._uses_obj <= 0)
return false;
new_uses = old_uses;
new_uses._uses_ctl++;
new_uses._uses_obj++;
} while (!_uses.compare_exchange_weak(old_uses, new_uses));
assert(new_uses._uses_obj > 0);
assert(new_uses._uses_ctl >= new_uses._uses_obj);
return true;
}
// Decrements control and object use counter
// Returns true if the object is to be deleted (it was the last reference)
bool strong_release() {
UsesBlock old_uses = _uses.load();
UsesBlock new_uses;
do {
new_uses = old_uses;
new_uses._uses_obj--;
new_uses._uses_ctl--;
} while (!_uses.compare_exchange_weak(old_uses, new_uses));
if (new_uses._uses_ctl == 0)
delete this;
return new_uses._uses_obj == 0;
}
};
template<typename T> template<typename T>
class SharedPtr { class SharedPtr {
friend SharedPtrTester; friend SharedPtrTester;
@@ -62,51 +136,146 @@ class SharedPtr {
public: public:
SharedPtr() = default; SharedPtr() = default;
explicit SharedPtr(T *data) : ptr(data), uses(new std::atomic<int>(1)) {} explicit SharedPtr(T *data) : _ptr(data), _base(new SharedPtr_Base{SharedPtr_Base::UsesBlock{1, 1}}) {}
SharedPtr(std::nullptr_t a_nullptr) : _ptr(nullptr), _base(nullptr) {}
~SharedPtr() { ~SharedPtr() {
if (ptr == nullptr || uses == nullptr) return; unref();
if (uses->fetch_sub(1) == 1) {
delete ptr;
delete uses;
}
} }
SharedPtr(SharedPtr const &other) : ptr(other.ptr), uses(other.uses) { SharedPtr(SharedPtr const &other) : _base(other._base), _ptr(other._ptr) {
++(*uses); if (!_base) return;
_base->strong_lock();
} }
SharedPtr(SharedPtr &&other) { SharedPtr(SharedPtr &&other) {
if (ptr != nullptr && uses != nullptr) unref();
if (uses->fetch_sub(1) == 1) {
delete ptr; _base = other._base;
delete uses; _ptr = other._ptr;
} other._base = nullptr;
uses = other.uses; other._ptr = nullptr;
ptr = other.ptr;
other.uses = nullptr;
other.ptr = nullptr;
} }
SharedPtr &operator=(SharedPtr other) { SharedPtr &operator=(SharedPtr other) {
std::swap(ptr, other.ptr); std::swap(_base, other._base);
std::swap(uses, other.uses); std::swap(_ptr, other._ptr);
return *this; return *this;
} }
T *operator->() const { return ptr; } T *operator->() const {
return _ptr;
}
T &operator*() const { return *ptr; } T &operator*() const {
return *_ptr;
}
T *get() const noexcept { return ptr; } T *get() const noexcept {
return _ptr;
}
[[nodiscard]] int useCount() const { return *uses; } [[nodiscard]] int useCount() const {
if (!_base) return 0;
return _base->_uses.load()._uses_obj;
}
template<typename Tgt, template<class> class Ptr, typename Orig>
friend Ptr<Tgt> static_ptr_cast(const Ptr<Orig> &ptr);
private: private:
T *ptr = nullptr; template<typename U>
std::atomic<int> *uses = nullptr; friend class WeakPtr;
explicit SharedPtr(T *ptr, SharedPtr_Base *base) : _ptr(ptr), _base(base) {}
void unref() {
if (!_base) return;
if (_base->strong_release())
delete _ptr;
_ptr = nullptr;
_base = nullptr;
}
T *_ptr = nullptr;
SharedPtr_Base *_base = nullptr;
}; };
template<typename T>
class WeakPtr {
public:
WeakPtr() = default;
WeakPtr(const SharedPtr<T> &shared) : _base(shared._base), _ptr(shared._ptr) { _base->weak_lock(); }
WeakPtr(std::nullptr_t a_nullptr) : _ptr(nullptr), _base(nullptr) {}
~WeakPtr() {
unref();
}
WeakPtr(WeakPtr const &other) : _base(other._base), _ptr(other._ptr) {
if (!_base) return;
_base->weak_lock();
}
WeakPtr(WeakPtr &&other) {
unref();
_base = other._base;
_ptr = other._ptr;
other._base = nullptr;
other._ptr = nullptr;
}
WeakPtr &operator=(WeakPtr other) {
std::swap(_ptr, other._ptr);
std::swap(_base, other._base);
return *this;
}
std::optional<SharedPtr<T>> lock() {
if (!_base) return std::nullopt;
if (_base->strong_lock())
return SharedPtr(_ptr, _base);
else
return std::nullopt;
}
[[nodiscard]] int expired() const {
if (!_base) return true;
return _base->_uses.load()._uses_obj <= 0;
}
template<typename Tgt, template<class> class Ptr, typename Orig>
friend Ptr<Tgt> static_ptr_cast(const Ptr<Orig> &ptr);
private:
void unref() {
if (!_base) return;
_base->weak_release();
_base = nullptr;
_ptr = nullptr;
}
T *_ptr = nullptr;
SharedPtr_Base *_base = nullptr;
};
template<typename Tgt, template<class> class Ptr, typename Orig>
static Ptr<Tgt> static_ptr_cast(const Ptr<Orig> &ptr) {
static_assert(std::is_convertible_v<Orig *, Tgt *> || std::is_base_of_v<Orig, Tgt>);
if constexpr (std::is_same_v<Ptr<Tgt>, SharedPtr<Tgt>>) {
ptr._base->strong_lock();
} else if constexpr (std::is_same_v<Ptr<Tgt>, WeakPtr<Tgt>>) {
ptr._base->weak_lock();
} else {
static_assert(false);
}
return Ptr<Tgt>(static_cast<Tgt *>(ptr._ptr), ptr._base);
}
class COWTester; class COWTester;
template<typename T> template<typename T>

View File

@@ -11,4 +11,6 @@ target_sources(kernel.elf PRIVATE
FDT.cpp FDT.cpp
VFSGlobals.cpp VFSGlobals.cpp
File.cpp File.cpp
PipeFs.cpp
TtyPipe.cpp
) )

View File

@@ -7,12 +7,13 @@
#include "File.hpp" #include "File.hpp"
#include "MountTable.hpp" #include "MountTable.hpp"
#include "PointersCollection.hpp" #include "PointersCollection.hpp"
#include "TtyPipe.hpp"
#include "VFSApi.hpp" #include "VFSApi.hpp"
#include "VFSGlobals.hpp" #include "VFSGlobals.hpp"
#include "paging.hpp" #include "paging.hpp"
FDT::FD FDT::open(const Path &p, FileOpts opts) { FDT::FD FDT::open(const Path &p, FileOpts opts) {
if (auto n = VFSGlobals::root.traverse(p)) { if (auto n = VFSGlobals::root.traverse(p); n.get() != nullptr) {
LockGuard l(_mtx); LockGuard l(_mtx);
_files.add(_cur_fd++, UniquePtr<File>(new File(n, opts))); _files.add(_cur_fd++, UniquePtr<File>(new File(n, opts)));
return _cur_fd - 1; return _cur_fd - 1;
@@ -44,6 +45,10 @@ File *FDT::get(FDT::FD fd) const {
FDT *FDT::current() { FDT *FDT::current() {
return Scheduler::cur_task()->_addressSpace->getFdt(); return Scheduler::cur_task()->_addressSpace->getFdt();
} }
FDT::FDT() {
_files.add(0, UniquePtr(new File(static_ptr_cast<Node>(TtyPipe::create()), O_RDONLY)));
_files.add(1, UniquePtr(new File(static_ptr_cast<Node>(TtyPipe::create()), O_RDWR)));
}
FDHandle::FDHandle(FDT::FD fd) : _fd(fd) { FDHandle::FDHandle(FDT::FD fd) : _fd(fd) {
} }
FDHandle::~FDHandle() { FDHandle::~FDHandle() {

View File

@@ -14,6 +14,8 @@
class FDT { class FDT {
public: public:
FDT();
using FD = int64_t; using FD = int64_t;
FD open(const Path &p, FileOpts opts); FD open(const Path &p, FileOpts opts);
void close(FD fd); void close(FD fd);

View File

@@ -4,23 +4,25 @@
#include "File.hpp" #include "File.hpp"
#include <utility>
#include "Node.hpp" #include "Node.hpp"
File::File(Node *node, FileOpts opts) : _n(node), _opts(opts) { File::File(SharedPtr<Node> node, FileOpts opts) : _n(std::move(node)), _opts(opts) {
if (opts & FileOpts::O_WRONLY) if (opts & FileOpts::O_WRONLY)
assert(opts & FileOpts::O_RDONLY); assert(opts & FileOpts::O_RDONLY);
} }
File::~File() { File::~File() {
} }
Node *File::node() { SharedPtr<Node> File::node() const {
return _n; return _n;
} }
NodeDir *File::dir() { SharedPtr<NodeDir> File::dir() const {
if (_n && _n->type() == Node::DIR) return static_cast<NodeDir *>(_n); if (_n.get() && _n->type() == Node::DIR) return static_ptr_cast<NodeDir>(_n);
return nullptr; return nullptr;
} }
NodeFile *File::file() const { SharedPtr<NodeFile> File::file() const {
if (_n && _n->type() == Node::FILE) return static_cast<NodeFile *>(_n); if (_n.get() && _n->type() == Node::FILE) return static_ptr_cast<NodeFile>(_n);
return nullptr; return nullptr;
} }
uint64_t File::seek(uint64_t pos) { uint64_t File::seek(uint64_t pos) {
@@ -28,7 +30,7 @@ uint64_t File::seek(uint64_t pos) {
return pos; return pos;
} }
uint64_t File::read(char *buf, uint64_t size) { uint64_t File::read(char *buf, uint64_t size) {
if (file()) { if (file().get() != nullptr) {
file()->read(buf, _pos, size); file()->read(buf, _pos, size);
_pos += size; _pos += size;
return size; return size;
@@ -36,12 +38,12 @@ uint64_t File::read(char *buf, uint64_t size) {
} }
uint64_t File::write(const char *buf, uint64_t size) { uint64_t File::write(const char *buf, uint64_t size) {
if (!(_opts & FileOpts::O_WRONLY)) return -1; if (!(_opts & FileOpts::O_WRONLY)) return -1;
if (file()) { if (file().get() != nullptr) {
file()->write(buf, _pos, size); file()->write(buf, _pos, size);
_pos += size; _pos += size;
return size; return size;
} }
} }
uint64_t File::size() { uint64_t File::size() {
if (file()) return file()->size(); if (file().get() != nullptr) return file()->size();
} }

View File

@@ -6,6 +6,8 @@
#define FICUS_FILE_HPP #define FICUS_FILE_HPP
#include "FileOpts.h" #include "FileOpts.h"
#include "PointersCollection.hpp"
#include <cstdint> #include <cstdint>
class Node; class Node;
@@ -14,24 +16,24 @@ class NodeFile;
class File { class File {
public: public:
File(Node *n, FileOpts opts); File(SharedPtr<Node> n, FileOpts opts);
~File(); ~File();
File(const File &f) = delete; File(const File &f) = delete;
File &operator=(const File &o) = delete; File &operator=(const File &o) = delete;
Node *node(); SharedPtr<Node> node() const;
NodeDir *dir(); SharedPtr<NodeDir> dir() const;
NodeFile *file() const; SharedPtr<NodeFile> file() const;
uint64_t seek(uint64_t pos); uint64_t seek(uint64_t pos);
uint64_t read(char *buf, uint64_t size); uint64_t read(char *buf, uint64_t size);
uint64_t write(const char *buf, uint64_t size); uint64_t write(const char *buf, uint64_t size);
uint64_t size(); uint64_t size();
private: private:
Node *const _n; SharedPtr<Node> _n;
uint64_t _pos = 0; uint64_t _pos = 0;
FileOpts _opts; FileOpts _opts;
}; };
#endif //FICUS_FILE_HPP #endif //FICUS_FILE_HPP

View File

@@ -5,28 +5,27 @@
#include "MemFs.hpp" #include "MemFs.hpp"
#include "LockGuard.hpp" #include "LockGuard.hpp"
Vector<Node *> MemFs::MemFsNodeDir::children() { Vector<SharedPtr<Node>> MemFs::MemFsNodeDir::children() {
LockGuard l(_lock); LockGuard l(_lock);
Vector<Node *> out; Vector<SharedPtr<Node>> out;
for (auto c: _children) { for (auto c: _children) {
out.emplace_back(c.data); out.emplace_back(c.data);
} }
return out; return out;
} }
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) { SharedPtr<NodeDir> MemFs::MemFsNodeDir::mkdir(const String &name) {
LockGuard l(_lock); LockGuard l(_lock);
auto newnode = new MemFsNodeDir(); auto newnode = MemFsNodeDir::create(name);
newnode->_name = name; _children.add(name, static_ptr_cast<Node>(newnode));
_children.add(name, newnode); return static_ptr_cast<NodeDir>(newnode);
return newnode;
} }
NodeFile *MemFs::MemFsNodeDir::mkfile(const String &name) { SharedPtr<NodeFile> MemFs::MemFsNodeDir::mkfile(const String &name) {
LockGuard l(_lock); LockGuard l(_lock);
auto newfile = new MemFsNodeFile(name); auto newfile = MemFsNodeFile::create(name);
_children.add(name, newfile); _children.add(name, static_ptr_cast<Node>(newfile));
return newfile; return static_ptr_cast<NodeFile>(newfile);
} }
bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) { bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
LockGuard l(_lock); LockGuard l(_lock);

View File

@@ -14,33 +14,46 @@
class MemFs : public Filesystem { class MemFs : public Filesystem {
struct MemFsNodeDir : public NodeDir { struct MemFsNodeDir : public NodeDir {
public: public:
Vector<Node *> children() override; Vector<SharedPtr<Node>> children() override;
NodeDir *mkdir(const String &name) override; SharedPtr<NodeDir> mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override; SharedPtr<NodeFile> mkfile(const String &name) override;
static SharedPtr<MemFsNodeDir> create(const String &name) {
auto shared = SharedPtr(new MemFsNodeDir(name));
shared->_self_weak = static_ptr_cast<Node>(shared);
return shared;
}
private: private:
SkipList<String, Node *> _children; MemFsNodeDir(const String &name) { _name = name; }
SkipList<String, SharedPtr<Node>> _children;
}; };
struct MemFsNodeFile : public NodeFile { struct MemFsNodeFile : public NodeFile {
public: 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;
bool is_tty() override { return false; }
bool read(char *buf, size_t start, size_t num) override; static SharedPtr<MemFsNodeFile> create(const String &name) {
bool write(const char *buf, size_t start, size_t num) override; auto shared = SharedPtr(new MemFsNodeFile(name));
size_t size() override; shared->_self_weak = static_ptr_cast<Node>(shared);
return shared;
}
private: private:
MemFsNodeFile(const String &name) { _name = name; }
Vector<uint8_t> _bytes; Vector<uint8_t> _bytes;
}; };
public: public:
MemFs(NodeDir *mounted_on) : Filesystem(mounted_on) {} MemFs(NodeDir *mounted_on) : Filesystem(mounted_on) {}
NodeDir *root() override { return &_rootNode; } NodeDir *root() override { return _rootNode.get(); }
private: private:
MemFsNodeDir _rootNode; SharedPtr<MemFsNodeDir> _rootNode = MemFsNodeDir::create("");
}; };

View File

@@ -8,24 +8,25 @@
#include "Filesystem.hpp" #include "Filesystem.hpp"
Node::~Node() = default; Node::~Node() = default;
Node *Node::traverse(const Path &path) { SharedPtr<Node> Node::traverse(const Path &path) {
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
Filesystem *mnt; Filesystem *mnt;
{ {
LockGuard l(_lock); LockGuard l(_lock);
mnt = nodeDir._mount; mnt = _mount;
} }
if (mnt) return mnt->root()->traverse(path); if (mnt) return mnt->root()->traverse(path);
if (path.empty()) { if (path.empty()) {
return this; auto ret = _self_weak.lock();
assert(ret != std::nullopt);
return *ret;
} }
if (type() == DIR) { if (type() == DIR) {
// Horribly inefficient // Horribly inefficient
auto children = nodeDir.children(); auto children = static_cast<NodeDir *>(this)->children();
for (size_t i = 0; i < children.size(); i++) { for (size_t i = 0; i < children.size(); i++) {
if (children[i]->name() == path[0]) { if (children[i]->name() == path[0]) {
return children[i]->traverse(path.subvector(1, path.size())); return children[i]->traverse(path.subvector(1, path.size()));

View File

@@ -5,6 +5,8 @@
#ifndef FICUS_NODE_HPP #ifndef FICUS_NODE_HPP
#define FICUS_NODE_HPP #define FICUS_NODE_HPP
#include <utility>
#include "List.hpp" #include "List.hpp"
#include "LockGuard.hpp" #include "LockGuard.hpp"
#include "String.hpp" #include "String.hpp"
@@ -28,7 +30,7 @@ public:
LockGuard l(_lock); LockGuard l(_lock);
return _name; return _name;
} }
virtual Node *traverse(const Path &path); virtual SharedPtr<Node> traverse(const Path &path);
protected: protected:
Node(Type type) : _type(type) {} Node(Type type) : _type(type) {}
@@ -40,16 +42,17 @@ protected:
String _name; String _name;
Filesystem *_mount = nullptr; Filesystem *_mount = nullptr;
WeakPtr<Node> _self_weak = nullptr;
}; };
class NodeFile; class NodeFile;
class NodeDir : public Node { class NodeDir : public Node {
public: public:
virtual Vector<Node *> children() = 0; virtual Vector<SharedPtr<Node>> children() = 0;
virtual NodeDir *mkdir(const String &name) = 0; virtual SharedPtr<NodeDir> mkdir(const String &name) = 0;
virtual NodeFile *mkfile(const String &name) = 0; virtual SharedPtr<NodeFile> mkfile(const String &name) = 0;
virtual void set_mounted(Filesystem *mount); virtual void set_mounted(Filesystem *mount);
protected: protected:
NodeDir() : Node(Type::DIR) {} NodeDir() : Node(Type::DIR) {}
@@ -60,6 +63,7 @@ public:
virtual bool read(char *buf, size_t start, size_t num) = 0; 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 bool write(const char *buf, size_t start, size_t num) = 0;
virtual size_t size() = 0; virtual size_t size() = 0;
virtual bool is_tty() = 0;
protected: protected:
NodeFile() : Node(Type::FILE) {} NodeFile() : Node(Type::FILE) {}

View File

@@ -0,0 +1,5 @@
//
// Created by Stepan Usatiuk on 05.04.2024.
//
#include "PipeFs.hpp"

13
src/kernel/vfs/PipeFs.hpp Normal file
View File

@@ -0,0 +1,13 @@
//
// Created by Stepan Usatiuk on 05.04.2024.
//
#ifndef FICUS_PIPEFS_HPP
#define FICUS_PIPEFS_HPP
class PipeFs {
};
#endif //FICUS_PIPEFS_HPP

View File

@@ -0,0 +1,29 @@
//
// Created by Stepan Usatiuk on 05.04.2024.
//
#include "TtyPipe.hpp"
#include "TtyManager.hpp"
bool TtyPipe::read(char *buf, size_t start, size_t num) {
auto c = buf;
while ((c - buf) < num) {
*c = GlobalTtyManager.get_tty(0)->readchar();
if (*c == '\r') {
*(c++) = '\n';
break;
}
c++;
}
return (c - buf);
}
bool TtyPipe::write(const char *buf, size_t start, size_t num) {
auto c = buf;
while (*c != '\0' && (c - buf) < num) {
GlobalTtyManager.all_tty_putchar(*c);
c++;
}
return num;
}
size_t TtyPipe::size() {
return 0;
}

View File

@@ -0,0 +1,28 @@
//
// Created by Stepan Usatiuk on 05.04.2024.
//
#ifndef FICUS_TTYPIPE_HPP
#define FICUS_TTYPIPE_HPP
#include "Node.hpp"
class TtyPipe : public NodeFile {
public:
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;
bool is_tty() override { return true; }
static SharedPtr<TtyPipe> create() {
auto shared = SharedPtr(new TtyPipe());
shared->_self_weak = static_ptr_cast<Node>(shared);
return shared;
}
private:
TtyPipe() = default;
};
#endif //FICUS_TTYPIPE_HPP

View File

@@ -12,7 +12,7 @@ bool VFSApi::mkdir(const Path &path) {
FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR)); FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR));
if (root_fd.get() == -1) return false; if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get()); File *root_f = FDT::current()->get(root_fd.get());
if (!root_f->dir()) return false; if (root_f->dir().get() == nullptr) return false;
root_f->dir()->mkdir(path.back()); root_f->dir()->mkdir(path.back());
return true; return true;
} }
@@ -21,7 +21,7 @@ bool VFSApi::touch(const Path &path) {
FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR)); FDHandle root_fd = FDHandle(FDT::current()->open(root, O_RDWR));
if (root_fd.get() == -1) return false; if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get()); File *root_f = FDT::current()->get(root_fd.get());
if (!root_f->dir()) return false; if (root_f->dir().get() == nullptr) return false;
root_f->dir()->mkfile(path.back()); root_f->dir()->mkfile(path.back());
return true; return true;
} }

View File

@@ -3,15 +3,15 @@
// //
#include "VFSGlobals.hpp" #include "VFSGlobals.hpp"
Vector<Node *> RootNode::children() { Vector<SharedPtr<Node>> RootNode::children() {
assert(false); assert(false);
return {}; return {};
} }
NodeDir *RootNode::mkdir(const String &name) { SharedPtr<NodeDir> RootNode::mkdir(const String &name) {
assert(false); assert(false);
return nullptr; return nullptr;
} }
NodeFile *RootNode::mkfile(const String &name) { SharedPtr<NodeFile> RootNode::mkfile(const String &name) {
assert(false); assert(false);
return nullptr; return nullptr;
} }

View File

@@ -10,9 +10,9 @@
class RootNode : public NodeDir { class RootNode : public NodeDir {
public: public:
Vector<Node *> children() override; Vector<SharedPtr<Node>> children() override;
NodeDir *mkdir(const String &name) override; SharedPtr<NodeDir> mkdir(const String &name) override;
NodeFile *mkfile(const String &name) override; SharedPtr<NodeFile> mkfile(const String &name) override;
}; };
namespace VFSGlobals { namespace VFSGlobals {