diff options
Diffstat (limited to 'Source/Kernel/VFS/VFS.ns.cpp')
-rw-r--r-- | Source/Kernel/VFS/VFS.ns.cpp | 123 |
1 files changed, 117 insertions, 6 deletions
diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp index e95b911..cf68653 100644 --- a/Source/Kernel/VFS/VFS.ns.cpp +++ b/Source/Kernel/VFS/VFS.ns.cpp @@ -1,19 +1,130 @@ #include "VFS.ns.h" #include <VFS/FileNode.class.h> +#include <Vector.class.h> +#include <VTManager/VirtualTerminal.proto.h> + +#include <VFS/Part.ns.h> +#include <FileSystems/RamFS/RamFS.class.h> +#include <FileSystems/FAT/FATFS.class.h> + +struct local_fs_t { + const char* name; + mount_callback_t cb; +} fileSystems[] = { + {"fat", FATFS::mount}, + {0, 0} +}; + +FileSystem::~FileSystem() { delete m_rootNode; } namespace VFS { -DirectoryNode *rootNode; +DirectoryNode *rootNode = 0; +Vector<FileSystem*> filesystems; + +DirectoryNode* getRootNode() { + return rootNode; +} + +void registerFilesystem(FileSystem* fs) { + unregisterFilesystem(fs); + filesystems.push(fs); + if (rootNode == 0) rootNode = fs->getRootNode(); +} -//TODO : mount stuff +void unregisterFilesystem(FileSystem* fs) { + for (u32int i = 0; i < filesystems.size(); i++) { + if (filesystems[i] == fs) { + filesystems[i] = filesystems.back(); + filesystems.pop(); + break; + } + } +} -bool setRootNode(DirectoryNode* node) { - rootNode = node; +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; } -DirectoryNode* getRootNode() { - return rootNode; +bool mount(String str, VirtualTerminal* vt, multiboot_info_t *mbd) { + Vector<String> fs = str.split(":"); + DirectoryNode* root; + if (fs[0] == "/") { + root = NULL; + } else { + FSNode* n = VFS::find(fs[0]); + if (n == NULL) { + *vt << "Mountpoint does not exist : " << fs[0] << "\n"; + return false; + } + if (n->type() != NT_DIRECTORY) { + *vt << "Mountpoint is not a directory : " << fs[0] << "\n"; + return false; + } + root = (DirectoryNode*)n; + } + if (fs[1] == "ramfs") { + if (fs.size() > 2) { + if (mbd != 0) { + module_t *mods = (module_t*)mbd->mods_addr; + if (fs[2].toInt() >= mbd->mods_count) { + *vt << "Invalid module number for filesystem to mount on " << fs[0] << "\n"; + return false; + } + FileSystem* wat = RamFS::mount((u8int*)mods[fs[2].toInt()].mod_start, 1024 * 1024, root); + if (wat != NULL) { + wat->setIdentifier(str); + return true; + } + return false; + } else { + *vt << "Cannot mount kernel modules outside of kernel command line.\n"; + return false; + } + } else { + FileSystem* wat = RamFS::mount(1024 * 1024, root); + if (wat != NULL) { + wat->setIdentifier(str); + return true; + } + return false; + } + } else { + if (fs.size() < 4) { + *vt << "Syntax: <mountpoint>:[<dev_class>]:<dev_id>:<part_id>[:<fs_type>[:[ro|rw]]]\n"; + return false; + } + if (fs.size() < 5) fs.push(""); + if (fs.size() < 6) fs.push("ro"); //By default, mount file systems read-only + BlockDevice* d = Part::dev(fs[1], fs[2].toInt()); + Partition* p = Part::part(d, fs[3].toInt()); + for (u32int i = 0; i < filesystems.size(); i++) { + if (filesystems[i]->getPart() == p) { + *vt << "Cannot mount " << str << " : partition already mounted.\n"; + return false; + } + } + for (u32int i = 0; fileSystems[i].cb != 0; i++) { + if (fs[4] == fileSystems[i].name or fs[4] == "") { + FileSystem* mounted = fileSystems[i].cb(p, root, (fs[5] == "rw")); + if (mounted != NULL) { + mounted->setIdentifier(str); + return true; + } else if (fs[4] != "") { + *vt << "Could not mount filesystem on " << fs[0] << "\n"; + if (root == NULL) PANIC("Error while mounting root filesystem."); + return false; + } + } + } + *vt << "Unknown filesystem type for filesystem to mount on " << fs[0] << "\n"; + if (root == NULL) PANIC("Unknown filesystem type for root file system."); + return false; + } } FSNode* find(const String& path, FSNode* start) { |