diff options
Diffstat (limited to 'Source/Kernel/VFS')
-rw-r--r-- | Source/Kernel/VFS/BlockCache.class.cpp | 89 | ||||
-rw-r--r-- | Source/Kernel/VFS/BlockCache.class.h | 32 | ||||
-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/File.class.cpp | 3 | ||||
-rw-r--r-- | Source/Kernel/VFS/FileSystem.proto.h | 19 | ||||
-rw-r--r-- | Source/Kernel/VFS/Part.ns.cpp | 45 | ||||
-rw-r--r-- | Source/Kernel/VFS/Part.ns.h | 18 | ||||
-rw-r--r-- | Source/Kernel/VFS/Partition.class.cpp | 10 | ||||
-rw-r--r-- | Source/Kernel/VFS/Partition.class.h | 4 | ||||
-rw-r--r-- | Source/Kernel/VFS/VFS.ns.cpp | 123 | ||||
-rw-r--r-- | Source/Kernel/VFS/VFS.ns.h | 16 |
13 files changed, 395 insertions, 28 deletions
diff --git a/Source/Kernel/VFS/BlockCache.class.cpp b/Source/Kernel/VFS/BlockCache.class.cpp new file mode 100644 index 0000000..d505a99 --- /dev/null +++ b/Source/Kernel/VFS/BlockCache.class.cpp @@ -0,0 +1,89 @@ +#include <DeviceManager/Time.ns.h> + +template <typename T> +BlockCache<T>::BlockCache(T* dev) { + m_dev = dev; + m_count = 0; +} + +template <typename T> +BlockCache<T>::~BlockCache() { + sync(); + m_count = 0; + delete m_cache; + delete m_cacheInfo; +} + +template <typename T> +void BlockCache<T>::sync() { + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].dirty) m_dev->writeBlocks(m_cacheInfo[i].id, 1, m_cache + (i * m_dev->blockSize())); + } +} + +template <typename T> +void BlockCache<T>::init(u32int count) { + m_count = count; + m_cacheInfo = new cached_block_t[count]; + for (u32int i = 0; i < m_count; i++) { + m_cacheInfo[i].id = 0; + m_cacheInfo[i].lastuse = 0; + m_cacheInfo[i].dirty = false; + } + m_cache = (u8int*)Mem::alloc(m_count * m_dev->blockSize()); +} + +template <typename T> +bool BlockCache<T>::setCache(u64int block, u8int* data, bool dirty) { + u32int best = 0; + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].id == block) { + best = i; + break; + } + if (m_cacheInfo[i].lastuse < m_cacheInfo[best].lastuse) best = i; + } + if (best >= m_count) return false; + if (m_cacheInfo[best].dirty && (m_cacheInfo[best].id != block or !dirty)) + m_dev->writeBlocks(m_cacheInfo[best].id, 1, m_cache + (best * m_dev->blockSize())); + m_cacheInfo[best].id = block; + m_cacheInfo[best].lastuse = Time::uptime(); + m_cacheInfo[best].dirty = dirty; + memcpy(m_cache + (best * m_dev->blockSize()), data, m_dev->blockSize()); + return true; +} + +template <typename T> +bool BlockCache<T>::getCache(u64int block, u8int* data) { + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].id == block && m_cacheInfo[i].lastuse != 0) { + m_cacheInfo[i].lastuse = Time::uptime(); + memcpy(data, m_cache + (i * m_dev->blockSize()), m_dev->blockSize()); + return true; + } + } + return false; +} + +template <typename T> +bool BlockCache<T>::readBlocks(u64int startblock, u32int count, u8int* data) { + if (count == 1) { + if (getCache(startblock, data)) return true; + if (!m_dev->readBlocks(startblock, count, data)) return false; + setCache(startblock, data); + return true; + } else { + return m_dev->readBlocks(startblock, count, data); + } +} + +template <typename T> +bool BlockCache<T>::writeBlocks(u64int startblock, u32int count, u8int* data) { + if (m_dev->readOnly()) return false; + if (count == 1) { + if (!setCache(startblock, data, true)) return m_dev->writeBlocks(startblock, count, data); + return true; + } else { + return m_dev->writeBlocks(startblock, count, data); + } +} diff --git a/Source/Kernel/VFS/BlockCache.class.h b/Source/Kernel/VFS/BlockCache.class.h new file mode 100644 index 0000000..0b26180 --- /dev/null +++ b/Source/Kernel/VFS/BlockCache.class.h @@ -0,0 +1,32 @@ +#ifndef DEF_BLOCKCACHE_CLASS_H +#define DEF_BLOCKCACHE_CLASS_H + +template <typename T> +class BlockCache { + private: + T* m_dev; + u32int m_count; + struct cached_block_t { + u64int id; + u32int lastuse; + bool dirty; + } *m_cacheInfo; + u8int* m_cache; + + void sync(); + bool setCache(u64int block, u8int* data, bool dirty = false); + bool getCache(u64int block, u8int* data); + + public: + BlockCache(T* dev); + ~BlockCache(); + void init(u32int count); + + bool readBlocks(u64int startblock, u32int count, u8int* data); + bool writeBlocks(u64int startblock, u32int count, u8int* data); + +}; + +#include "BlockCache.class.cpp" + +#endif diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp index 74c1ff8..55365f0 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 == "/" && m_parent != NULL) ((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/File.class.cpp b/Source/Kernel/VFS/File.class.cpp index c5ddcd6..84561a5 100644 --- a/Source/Kernel/VFS/File.class.cpp +++ b/Source/Kernel/VFS/File.class.cpp @@ -33,7 +33,7 @@ bool File::open(String filename, u8int mode, FSNode* start, bool vrfyperm) { if (node == NULL){ if (mode == FM_READ) return false; node = VFS::createFile(filename, start, vrfyperm); - if (node == 0) return false; + if (node == NULL) return false; } if (node->type() != NT_FILE) return false; @@ -137,6 +137,7 @@ bool File::seek(u64int count, u8int mode) { } bool File::eof() { + if (!m_valid) return false; return m_position == m_file->getLength(); } diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h index a614c13..172c82c 100644 --- a/Source/Kernel/VFS/FileSystem.proto.h +++ b/Source/Kernel/VFS/FileSystem.proto.h @@ -5,17 +5,26 @@ 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*); + private: + String m_identifier; + 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; } @@ -34,6 +43,10 @@ class FileSystem { virtual FileNode* createFile(DirectoryNode* parent, String name) = 0; virtual DirectoryNode* createDirectory(DirectoryNode* parent, String name) = 0; virtual bool remove(DirectoryNode* parent, FSNode* node) = 0; + + virtual Partition* getPart() = 0; + void setIdentifier(String s) { m_identifier = s; } + String getIdentifier() { return m_identifier; } }; #endif diff --git a/Source/Kernel/VFS/Part.ns.cpp b/Source/Kernel/VFS/Part.ns.cpp index 6408dbd..415a150 100644 --- a/Source/Kernel/VFS/Part.ns.cpp +++ b/Source/Kernel/VFS/Part.ns.cpp @@ -1,5 +1,7 @@ #include "Part.ns.h" +#include <VTManager/SimpleVT.class.h> + namespace Part { Vector<BlockDevice*> devices; @@ -7,6 +9,21 @@ Vector<Partition*> partitions; void readPartitionTable(BlockDevice *dev) { //TODO : read partition table from device partitions.push(new Partition(dev, 0, 0, dev->blocks())); //Insert whole device as a partition + + u8int* mbr = (u8int*)Mem::alloc(dev->blockSize()); + if (!dev->readBlocks(0, 1, mbr)) return; + + mbr_entry_t* entries = (mbr_entry_t*)((u32int)mbr + 0x1BE); + + for (u32int i = 0; i < 4; i++) { + if ((entries[i].bootable == 0 or entries[i].bootable == 0x80) and entries[i].id != 0 + and entries[i].s_lba != 0 and entries[i].size != 0 + and entries[i].s_lba < dev->blocks() and entries[i].size < dev->blocks()) { + partitions.push(new Partition(dev, i + 1, entries[i].s_lba, entries[i].size)); + } + } + + Mem::free(mbr); } void registerDevice(BlockDevice *dev) { @@ -56,4 +73,32 @@ u32int getDeviceID(BlockDevice* dev) { return (u32int) - 1; } +BlockDevice* dev(String _class, u32int idx) { + if (_class.empty()) return devices[idx]; + for (u32int i = 0; i < devices.size(); i++) { + String devclass = devices[i]->getClass(); + if (devclass == _class or (devclass.size() > _class.size() and devclass.substr(0, _class.size()) == _class)) { + if (idx == 0) { + return devices[i]; + } else { + idx--; + } + } + } + return NULL; +} + +Partition* part(BlockDevice* dev, u32int idx) { + for (u32int i = 0; i < partitions.size(); i++) { + if (partitions[i]->getDevice() == dev && partitions[i]->getPartNumber() == idx) { + return partitions[i]; + } + } + return NULL; +} + +String partIdentifier(Partition* p) { + return String("d") += String::number(getDeviceID(p->getDevice())) += String("p") += String::number(p->getPartNumber()); +} + } diff --git a/Source/Kernel/VFS/Part.ns.h b/Source/Kernel/VFS/Part.ns.h index 40a0fb2..e6a358c 100644 --- a/Source/Kernel/VFS/Part.ns.h +++ b/Source/Kernel/VFS/Part.ns.h @@ -6,6 +6,19 @@ #include <VFS/Partition.class.h> namespace Part { + struct mbr_entry_t { + u8int bootable; /* 0 = no, 0x80 = bootable */ + u8int s_head; /* Starting head */ + u16int s_sector : 6; /* Starting sector */ + u16int s_cyl : 10; /* Starting cylinder */ + u8int id; /* System ID */ + u8int e_head; /* Ending head */ + u16int e_sector : 6; /* Ending sector */ + u16int e_cyl : 10; /* Ending cylinder */ + u32int s_lba; /* Starting sector (LBA value) */ + u32int size; /* Total sector number */ + } __attribute__ ((packed)); + extern Vector<BlockDevice*> devices; extern Vector<Partition*> partitions; @@ -13,6 +26,11 @@ namespace Part { void unregisterDevice(BlockDevice* dev); u32int getDeviceID(BlockDevice* dev); + + BlockDevice* dev(String _class, u32int idx); + Partition* part(BlockDevice* dev, u32int idx); + + String partIdentifier(Partition* p); //Simply to help recognize the partition } #endif diff --git a/Source/Kernel/VFS/Partition.class.cpp b/Source/Kernel/VFS/Partition.class.cpp index b62f33c..9da3461 100644 --- a/Source/Kernel/VFS/Partition.class.cpp +++ b/Source/Kernel/VFS/Partition.class.cpp @@ -2,21 +2,23 @@ using namespace CMem; //For memcpy -Partition::Partition(BlockDevice* dev, u8int partnumber, u64int startblock, u64int blockcount) { +Partition::Partition(BlockDevice* dev, u8int partnumber, u64int startblock, u64int blockcount) +: m_cache(dev) { m_device = dev; m_partnumber = partnumber; m_startblock = startblock; m_blockcount = blockcount; + m_cache.init(10 + (m_device->blocks() / 1000 > 100 ? 100 : m_device->blocks() / 1000)); } bool Partition::readBlocks(u64int startblock, u32int count, u8int *data) { if (startblock + count > m_startblock + m_blockcount) return false; - return m_device->readBlocks(startblock - m_startblock, count, data); + return m_cache.readBlocks(startblock + m_startblock, count, data); } bool Partition::writeBlocks(u64int startblock, u32int count, u8int *data) { if (startblock + count > m_startblock + m_blockcount) return false; - return m_device->writeBlocks(startblock - m_startblock, count, data); + return m_cache.writeBlocks(startblock + m_startblock, count, data); } bool Partition::read(u64int start, u32int length, u8int *data) { @@ -65,4 +67,4 @@ BlockDevice* Partition::getDevice() { return m_device; } u64int Partition::getStartBlock() { return m_startblock; } u64int Partition::getBlockCount() { return m_blockcount; } u8int Partition::getPartNumber() { return m_partnumber; } -u32int Partition::getBlockSize() { return m_device->blockSize(); } +u32int Partition::blockSize() { return m_device->blockSize(); } diff --git a/Source/Kernel/VFS/Partition.class.h b/Source/Kernel/VFS/Partition.class.h index 8df1c4f..eb0aafd 100644 --- a/Source/Kernel/VFS/Partition.class.h +++ b/Source/Kernel/VFS/Partition.class.h @@ -2,10 +2,12 @@ #define DEF_PARTITION_CLASS_H #include <Devices/BlockDevice.proto.h> +#include <VFS/BlockCache.class.h> class Partition { private: BlockDevice* m_device; + BlockCache<BlockDevice> m_cache; u64int m_startblock, m_blockcount; u8int m_partnumber; //Partition number in partition table of device @@ -24,7 +26,7 @@ class Partition { u64int getStartBlock(); u64int getBlockCount(); u8int getPartNumber(); - u32int getBlockSize(); + u32int blockSize(); inline u64int blocks() { return getBlockCount(); } }; 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) { diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h index f1d628f..eede728 100644 --- a/Source/Kernel/VFS/VFS.ns.h +++ b/Source/Kernel/VFS/VFS.ns.h @@ -1,17 +1,27 @@ #ifndef DEF_VFS_NS_H #define DEF_VFS_NS_H +#include <Core/multiboot.wtf.h> + #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, DirectoryNode* mountpoint, bool readwrite); 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); + + bool mount(String str, VirtualTerminal* logvt, multiboot_info_t* mbd = 0); + 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); |