mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
less insane vfs
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user