diff options
Diffstat (limited to 'Source/Kernel/VFS')
-rw-r--r-- | Source/Kernel/VFS/DirectoryNode.class.cpp | 45 | ||||
-rw-r--r-- | Source/Kernel/VFS/DirectoryNode.class.h | 15 | ||||
-rw-r--r-- | Source/Kernel/VFS/FSNode.proto.h | 4 | ||||
-rw-r--r-- | Source/Kernel/VFS/FileSystem.proto.h | 13 | ||||
-rw-r--r-- | Source/Kernel/VFS/VFS.ns.cpp | 35 | ||||
-rw-r--r-- | Source/Kernel/VFS/VFS.ns.h | 12 |
6 files changed, 101 insertions, 23 deletions
diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp index 74c1ff8..7da6fe6 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.cpp +++ b/Source/Kernel/VFS/DirectoryNode.class.cpp @@ -6,6 +6,15 @@ call_t DirectoryNode::m_callTable[] = { CALL0(0, 0) }; +DirectoryNode::~DirectoryNode() { + if (m_contentLoaded) { + for (u32int i = 0; i < m_children.size(); i++) { + delete m_children[i]; + } + } + if (m_name == "/") ((DirectoryNode*)(m_parent))->unmount(); +} + u32int DirectoryNode::getIdxChildSC(u32int idx) { if (!runnable()) return (u32int) - 1; FSNode* n = getChild(idx); @@ -21,15 +30,29 @@ u32int DirectoryNode::getNameChildSC(u32int name) { return (u32int) - 1; } +u64int DirectoryNode::getLength() { + if (m_mounts != 0) return m_mounts->getLength(); + if (!m_contentLoaded) + if (!loadContent()) + return 0; + return m_length; +} + +FSNode* DirectoryNode::getParent() { + //if (m_name == "/" and m_parent != 0) return m_parent->getParent(); + return m_parent; +} + bool DirectoryNode::removable() { if (!m_contentLoaded) if (!loadContent()) return false; - return m_children.empty(); + return m_children.empty() && (m_mounts == 0); } bool DirectoryNode::unmountable() { if (!m_contentLoaded) return true; + if (m_mounts != 0) return false; for (u32int i = 0; i < m_children.size(); i++) { if (m_children[i]->type() == NT_DIRECTORY) { if (!((DirectoryNode*)m_children[i])->unmountable()) return false; @@ -40,7 +63,22 @@ bool DirectoryNode::unmountable() { return true; } +bool DirectoryNode::mountpointable() { + if (!m_contentLoaded) + if (!loadContent()) return false; + return m_children.empty(); +} + +void DirectoryNode::mount(DirectoryNode* childRoot) { + m_mounts = childRoot; +} + +void DirectoryNode::unmount() { + m_mounts = 0; +} + bool DirectoryNode::loadContent() { + if (m_mounts != 0) return m_mounts->loadContent(); if (m_contentLoaded) return true; bool b = m_fs->loadContents(this); if (!b) return false; @@ -50,6 +88,7 @@ bool DirectoryNode::loadContent() { } FSNode* DirectoryNode::getChild(u32int index) { + if (m_mounts != 0) return m_mounts->getChild(index); if (!m_contentLoaded) if (!loadContent()) return NULL; @@ -58,6 +97,7 @@ FSNode* DirectoryNode::getChild(u32int index) { } FSNode* DirectoryNode::getChild(const String& name) { + if (m_mounts != 0) return m_mounts->getChild(name); if (!m_contentLoaded) if (!loadContent()) return NULL; @@ -69,18 +109,21 @@ FSNode* DirectoryNode::getChild(const String& name) { } FileNode* DirectoryNode::createFile(const String& name) { + if (m_mounts != 0) return m_mounts->createFile(name); FileNode* n = m_fs->createFile(this, name); m_length = m_children.size(); return n; } DirectoryNode* DirectoryNode::createDirectory(const String& name) { + if (m_mounts != 0) return m_mounts->createDirectory(name); DirectoryNode* n = m_fs->createDirectory(this, name); m_length = m_children.size(); return n; } bool DirectoryNode::remove(FSNode* child) { + if (m_mounts != 0) return m_mounts->remove(child); //Check node is indeed one of our childs if (!m_contentLoaded) if (!loadContent()) diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h index 4d9b211..1fc4c52 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.h +++ b/Source/Kernel/VFS/DirectoryNode.class.h @@ -8,6 +8,7 @@ class DirectoryNode : public FSNode { protected: Vector<FSNode*> m_children; bool m_contentLoaded; + DirectoryNode* m_mounts; //Root node of the filesystem mounted here, null if none //Syscalls static call_t m_callTable[]; @@ -19,20 +20,20 @@ class DirectoryNode : public FSNode { u32int uid = 0, u32int gid = 0) : FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) { addCallTable(m_callTable); + m_mounts = 0; } - virtual ~DirectoryNode() { - if (m_contentLoaded) { - for (u32int i = 0; i < m_children.size(); i++) { - delete m_children[i]; - } - } - } + virtual ~DirectoryNode(); Vector<FSNode*> &getChildren() { return m_children; } //MUST BE USED ONLY BY FILESYSTEMS u8int type() { return NT_DIRECTORY; } + u64int getLength(); + FSNode* getParent(); bool removable(); bool unmountable(); + bool mountpointable(); + void mount(DirectoryNode* childRoot); + void unmount(); bool loadContent(); FSNode* getChild(u32int index); diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 0aafc8a..a46c79d 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -44,12 +44,12 @@ class FSNode : public Ressource { virtual bool used() { return false; } //True if file is read/written from/to const String& getName() { return m_name; } - u64int getLength() { return m_length; } + virtual u64int getLength() { return m_length; } u32int getPermissions() { return m_permissions; } u32int getUid() { return m_uid; } u32int getGid() { return m_gid; } FileSystem *getFS() { return m_fs; } - FSNode* getParent() { return m_parent; } + virtual FSNode* getParent() { return m_parent; } //Helper functions bool readable(User* user = 0); diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h index a614c13..93b37f8 100644 --- a/Source/Kernel/VFS/FileSystem.proto.h +++ b/Source/Kernel/VFS/FileSystem.proto.h @@ -5,17 +5,24 @@ class FSNode; class FileNode; class DirectoryNode; +class FileSystem; + +namespace VFS { + bool unmount(FileSystem*); +} //This abstract class describes a filesystem class FileSystem { + friend bool VFS::unmount(FileSystem*); + protected: - virtual ~FileSystem() {} + virtual ~FileSystem(); bool m_isWritable; //false = read only DirectoryNode* m_rootNode; - public: - bool unmount(); + virtual bool unmount() = 0; //Sync data with the disk + public: bool isWritable() { return m_isWritable; } DirectoryNode* getRootNode() { return m_rootNode; } diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp index e95b911..5ebb697 100644 --- a/Source/Kernel/VFS/VFS.ns.cpp +++ b/Source/Kernel/VFS/VFS.ns.cpp @@ -1,19 +1,40 @@ #include "VFS.ns.h" #include <VFS/FileNode.class.h> +#include <Vector.class.h> + +FileSystem::~FileSystem() { delete m_rootNode; } namespace VFS { -DirectoryNode *rootNode; +DirectoryNode *rootNode = 0; +Vector<FileSystem*> filesystems; -//TODO : mount stuff +DirectoryNode* getRootNode() { + return rootNode; +} -bool setRootNode(DirectoryNode* node) { - rootNode = node; - return true; +void registerFilesystem(FileSystem* fs) { + unregisterFilesystem(fs); + filesystems.push(fs); + if (rootNode == 0) rootNode = fs->getRootNode(); } -DirectoryNode* getRootNode() { - return rootNode; +void unregisterFilesystem(FileSystem* fs) { + for (u32int i = 0; i < filesystems.size(); i++) { + if (filesystems[i] == fs) { + filesystems[i] = filesystems.back(); + filesystems.pop(); + break; + } + } +} + +bool unmount(FileSystem* fs) { + if (!fs->getRootNode()->unmountable()) return false; + if (fs->getRootNode() == rootNode) return false; + if (!fs->unmount()) return false; + delete fs; //Will automatically delete the root node (destructor is in this file); + return true; } FSNode* find(const String& path, FSNode* start) { diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h index f1d628f..21a1e77 100644 --- a/Source/Kernel/VFS/VFS.ns.h +++ b/Source/Kernel/VFS/VFS.ns.h @@ -3,15 +3,21 @@ #include <VFS/DirectoryNode.class.h> #include <VFS/FileSystem.proto.h> +#include <Vector.class.h> -typedef FileSystem* (* mountcallback)(Partition* partition); +typedef FileSystem* (* mount_callback_t)(Partition* partition); namespace VFS { - void registerMountCallback(mountcallback mcb); + extern Vector<FileSystem*> filesystems; + + void registerMountCallback(mount_callback_t mcb); bool mount(Partition* partition, DirectoryNode *mountpoint); - bool setRootNode(DirectoryNode* root); DirectoryNode* getRootNode(); + void registerFilesystem(FileSystem* fs); + void unregisterFilesystem(FileSystem* fs); + bool unmount(FileSystem* fs); + FSNode* find(const String& path, FSNode* start = 0); FSNode* createFile(const String& path, FSNode* start = 0, bool vrfyperm = false); FSNode* createDirectory(const String& path, FSNode* start = 0, bool vrfyperm = false); |