diff options
author | Alexis211 <alexis211@gmail.com> | 2009-11-15 13:17:58 +0100 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-11-15 13:17:58 +0100 |
commit | 21bfca4ad4b84768f05eb4fa2bc0ad7a76b6c536 (patch) | |
tree | 7e68b92e80aadec75b5263bd9058c8336d29b77b | |
parent | e48f1166ae7402f973ea4aab8e53c7612459048c (diff) | |
download | Melon-21bfca4ad4b84768f05eb4fa2bc0ad7a76b6c536.tar.gz Melon-21bfca4ad4b84768f05eb4fa2bc0ad7a76b6c536.zip |
Mount points seem to work, mostly owing to dark magic.
-rw-r--r-- | Source/Kernel/Core/kmain.wtf.cpp | 5 | ||||
-rw-r--r-- | Source/Kernel/FileSystems/RamFS/RamFS.class.cpp | 11 | ||||
-rw-r--r-- | Source/Kernel/FileSystems/RamFS/RamFS.class.h | 4 | ||||
-rw-r--r-- | Source/Kernel/FileSystems/RamFS/RamFileNode.class.h | 2 | ||||
-rw-r--r-- | Source/Kernel/Shell/KernelShell.class.cpp | 47 | ||||
-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 |
11 files changed, 163 insertions, 30 deletions
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 0486702..d0751d1 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -182,11 +182,10 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //*************************************** MOUNT ROOT FILESYSTEM - FileSystem* fs = RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); + RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); DirectoryNode* cwd; - cwd = fs->getRootNode(); + cwd = VFS::getRootNode(); Task::currProcess()->setCwd(cwd); - VFS::setRootNode(cwd); if (keymap != "builtin") { if (!Kbd::loadKeymap(keymap)) *kvt << "\nWARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp index 5997841..e6370d0 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp @@ -1,30 +1,36 @@ #include "RamFS.class.h" #include <VFS/DirectoryNode.class.h> #include "RamFileNode.class.h" +#include <VFS/VFS.ns.h> RamFS::RamFS() { } RamFS::~RamFS() { - delete m_rootNode; } RamFS* RamFS::mount(u32int maxSize, DirectoryNode* mountpoint) { + if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); + if (mountpoint != 0) mountpoint->mount(rfs->m_rootNode); + VFS::registerFilesystem(rfs); return rfs; } RamFS* RamFS::mount(u8int *ptr, u32int maxSize, DirectoryNode* mountpoint, bool writable) { + if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); + if (mountpoint != 0) mountpoint->mount(rfs->m_rootNode); + VFS::registerFilesystem(rfs); union { u8int* c; @@ -81,7 +87,7 @@ RamFS* RamFS::mount(u8int *ptr, u32int maxSize, DirectoryNode* mountpoint, bool } bool RamFS::unmount() { - return m_rootNode->unmountable(); + return true; } bool RamFS::setName(FSNode* node, String name) { return true; } @@ -164,6 +170,7 @@ bool RamFS::remove(DirectoryNode* parent, FSNode* node) { if (node->type() == NT_FILE) { u8int *d = ((RamFileNode*)node)->m_data; if (d != 0) Mem::free(d); + ((RamFileNode*)node)->m_data = 0; } return true; } diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.h b/Source/Kernel/FileSystems/RamFS/RamFS.class.h index 1d60796..5ce85f1 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.h @@ -17,10 +17,10 @@ struct initrd_file_header { class RamFS : public FileSystem { private: - ~RamFS(); + virtual ~RamFS(); RamFS(const RamFS& other); RamFS(); - bool unmount(); //TO BE USED ONLY BY VFS::UNMOUNT (when will exist...) + bool unmount(); u32int m_maxSize; u32int m_usedSize; diff --git a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h index d600630..2abad64 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h @@ -11,6 +11,8 @@ class RamFileNode : public FileNode { u32int uid = 0, u32int gid = 0) : FileNode(name, fs, parent, 0, permissions, uid, gid), m_data(0) {} + ~RamFileNode() { if (m_data != 0) delete m_data; } + u8int *m_data; //We don't take care of allocation/freeing here, RamFS:: does that for us void setLength(u32int length) { m_length = length; } diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index d62d822..8f71b9f 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -4,6 +4,7 @@ #include <SimpleList.class.h> #include <MemoryManager/PhysMem.ns.h> #include <VFS/VFS.ns.h> +#include <FileSystems/RamFS/RamFS.class.h> #include <TaskManager/Task.ns.h> u32int KernelShell::m_instances = 0; @@ -92,6 +93,52 @@ u32int KernelShell::run() { } else if (tokens[0] == "exit") { if (tokens.size() == 1) return 0; return tokens[1].toInt(); + } else if (tokens[0] == "mount") { + if (tokens.size() == 1) { + for (u32int i = 0; i < VFS::filesystems.size(); i++) { + *m_vt << VFS::path(VFS::filesystems[i]->getRootNode()) << "\n"; + } + } else if (tokens.size() == 3) { + if (tokens[1] == "ramfs") { + FSNode* n = VFS::find(tokens[2], m_cwd); + if (n == 0) { + *m_vt << "No such directory.\n"; + } else if (n->type() != NT_DIRECTORY) { + *m_vt << "Not a directory.\n"; + } else { + if (RamFS::mount(100000, (DirectoryNode*)n) != 0) { + *m_vt << "Ok...\n"; + } else { + *m_vt << "Error !\n"; + } + } + } else { + *m_vt << "Not supported yet.\n"; + } + } else { + *m_vt << "Usage: mount [<device> <mountpoint>\n"; + } + } else if (tokens[0] == "unmount") { + if (tokens.size() == 2) { + FSNode* n = VFS::find(tokens[1], m_cwd); + bool ok = false; + if (n == 0) { + ok = false; + } else { + String p = VFS::path(n); + for (u32int i = 0; i < VFS::filesystems.size(); i++) { + if (VFS::path(VFS::filesystems[i]->getRootNode()) == p) { + VFS::unmount(VFS::filesystems[i]); + ok = true; + break; + } + } + } + if (ok) *m_vt << "Ok, filesystem unmounted.\n"; + else *m_vt << "Error.\n"; + } else { + *m_vt << "Usage: unmount <mountpoint>\n"; + } } else if (tokens[0] != "" or tokens.size() != 1) { u32int i = 0; bool found = false; 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); |