less insane vfs

This commit is contained in:
2024-02-29 22:49:20 +01:00
parent f46dd92d0b
commit 1e07603ac7
8 changed files with 72 additions and 24 deletions

View File

@@ -10,9 +10,9 @@
#include "VFSGlobals.hpp"
#include "paging.hpp"
FDT::FD FDT::open(const Path &p) {
FDT::FD FDT::open(const Path &p, File::OptsT opts) {
if (auto n = VFSGlobals::root.traverse(p)) {
_files.add(_cur_fd++, UniquePtr<File>(new File(n)));
_files.add(_cur_fd++, UniquePtr<File>(new File(n, opts)));
return _cur_fd - 1;
}
return -1;

View File

@@ -5,18 +5,17 @@
#ifndef OS2_FDT_HPP
#define OS2_FDT_HPP
#include "File.hpp"
#include "Node.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);
FD open(const Path &p, File::OptsT opts);
void close(FD fd);
File *get(FD fd);

View File

@@ -6,11 +6,18 @@
#include "Node.hpp"
File::File(Node *node) : _n(node) {
_n->lock();
File::File(Node *node, OptsT opts) : _n(node), _opts(opts) {
if (opts & (OptsT) Opts::W) assert(opts & (OptsT) Opts::R);
if (opts & (OptsT) Opts::W)
_n->lock_rw();
else
_n->lock_r();
}
File::~File() {
_n->unlock();
if (_opts & (OptsT) Opts::W)
_n->lock_rw();
else
_n->lock_r();
}
Node *File::node() {
return _n;
@@ -35,6 +42,7 @@ uint64_t File::read(char *buf, uint64_t size) {
}
}
uint64_t File::write(const char *buf, uint64_t size) {
assert(_opts & (OptsT) Opts::W);
if (file()) {
file()->write(buf, _pos, size);
_pos += size;

View File

@@ -13,7 +13,14 @@ class NodeFile;
class File {
public:
File(Node *n);
using OptsT = uint8_t;
enum Opts : uint8_t {
R = 1 << 1,// Read
W = 1 << 2,// Write
};
File(Node *n, OptsT opts);
~File();
File(const File &f) = delete;
File &operator=(const File &o) = delete;
@@ -30,6 +37,7 @@ public:
private:
Node *_n;
uint64_t _pos = 0;
OptsT _opts;
};
#endif//OS2_FILE_HPP

View File

@@ -4,8 +4,11 @@
#include "MemFs.hpp"
#include "LockGuard.hpp"
//FIXME: asserts on read also make sense
Vector<Node *> MemFs::MemFsNodeDir::children() {
assert(_lock.owner() == cur_task());
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
// assert(_lock.owner() == cur_task());
Vector<Node *> out;
for (auto c: _children) {
@@ -15,20 +18,21 @@ Vector<Node *> MemFs::MemFsNodeDir::children() {
}
NodeDir *MemFs::MemFsNodeDir::mkdir(const String &name) {
assert(_lock.owner() == cur_task());
assert(_rw_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());
assert(_rw_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());
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
// 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++) {
@@ -37,7 +41,7 @@ bool MemFs::MemFsNodeFile::read(char *buf, size_t start, size_t num) {
return false;
}
bool MemFs::MemFsNodeFile::write(const char *buf, size_t start, size_t num) {
assert(_lock.owner() == cur_task());
assert(_rw_lock.owner() == cur_task());
// fixme
while (_bytes.size() <= start + num) _bytes.emplace_back(0);
for (size_t i = 0; i < num; i++) {

View File

@@ -9,10 +9,7 @@
Node::~Node() = default;
Node *Node::traverse(const Path &path) {
LockGuardTry l(_lock);
// FIXME: This is bad
if (!l.locked() && _lock.owner() != cur_task())
l.lock();
lock_r();
NodeDir &nodeDir = static_cast<NodeDir &>(*this);
if (nodeDir._mount) return nodeDir._mount->root()->traverse(path);
@@ -23,11 +20,14 @@ Node *Node::traverse(const Path &path) {
auto children = nodeDir.children();
for (size_t i = 0; i < children.size(); i++) {
if (children[i]->name() == path[0]) {
unlock_r();
return children[i]->traverse(path.subvector(1, path.size()));
}
}
unlock_r();
return nullptr;
}
unlock_r();
return nullptr;
}
void NodeDir::set_mounted(Filesystem *mount) {
@@ -35,3 +35,27 @@ void NodeDir::set_mounted(Filesystem *mount) {
assert(_mount == nullptr);
_mount = mount;
}
bool Node::lock_r() {
LockGuard l(_lock);
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
_r_lock_count++;
return true;
}
bool Node::lock_rw() {
LockGuard l(_lock);
if (_rw_lock.test() && _rw_lock.owner() != cur_task()) return false;
_rw_lock.lock();
return true;
}
void Node::unlock_r() {
LockGuard l(_lock);
assert(!_rw_lock.test() || _rw_lock.owner() == cur_task());
assert(_r_lock_count > 0);
_r_lock_count--;
}
void Node::unlock_rw() {
LockGuard l(_lock);
assert(_rw_lock.test() && _rw_lock.owner() == cur_task());
_rw_lock.unlock();
}

View File

@@ -26,8 +26,10 @@ public:
const String &name() const { return _name; }
virtual Node *traverse(const Path &path);
void lock() { _lock.lock(); }
void unlock() { _lock.unlock(); }
bool lock_r();
bool lock_rw();
void unlock_r();
void unlock_rw();
protected:
Node(Type type) : _type(type) {}
@@ -36,6 +38,9 @@ protected:
// This is uuugly
Mutex _lock;
uint64_t _r_lock_count = 0;
Mutex _rw_lock;
String _name;
Filesystem *_mount = nullptr;
};

View File

@@ -9,7 +9,7 @@
bool VFSApi::mkdir(const Path &path) {
auto root = path.subvector(0, path.size() - 1);
FDHandle root_fd = FDHandle(FDT::current()->open(root));
FDHandle root_fd = FDHandle(FDT::current()->open(root, File::Opts::W | File::Opts::R));
if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get());
if (!root_f->dir()) return false;
@@ -18,7 +18,7 @@ bool VFSApi::mkdir(const Path &path) {
}
bool VFSApi::touch(const Path &path) {
auto root = path.subvector(0, path.size() - 1);
FDHandle root_fd = FDHandle(FDT::current()->open(root));
FDHandle root_fd = FDHandle(FDT::current()->open(root, File::Opts::W | File::Opts::R));
if (root_fd.get() == -1) return false;
File *root_f = FDT::current()->get(root_fd.get());
if (!root_f->dir()) return false;
@@ -27,7 +27,7 @@ bool VFSApi::touch(const Path &path) {
}
FDT::FD VFSApi::open(const Path &path) {
return FDT::current()->open(path);
return FDT::current()->open(path, File::Opts::W | File::Opts::R);
}
void VFSApi::close(FDT::FD fd) {
return FDT::current()->close(fd);