summaryrefslogtreecommitdiff
path: root/Source/Kernel/VFS
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/VFS')
-rw-r--r--Source/Kernel/VFS/DirectoryNode.class.cpp76
-rw-r--r--Source/Kernel/VFS/DirectoryNode.class.h47
-rw-r--r--Source/Kernel/VFS/FSNode.proto.h9
-rw-r--r--Source/Kernel/VFS/FileNode.class.h3
-rw-r--r--Source/Kernel/VFS/FileSystem.proto.h1
-rw-r--r--Source/Kernel/VFS/VFS.ns.h13
6 files changed, 104 insertions, 45 deletions
diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp
new file mode 100644
index 0000000..d624e97
--- /dev/null
+++ b/Source/Kernel/VFS/DirectoryNode.class.cpp
@@ -0,0 +1,76 @@
+#include "DirectoryNode.class.h"
+
+bool DirectoryNode::removable() {
+ if (!m_contentLoaded)
+ if (!loadContent())
+ return false;
+ return m_children.empty();
+}
+
+bool DirectoryNode::loadContent() {
+ if (m_contentLoaded) return true;
+ bool b = m_fs->loadContents(this);
+ if (!b) return false;
+ m_length = m_children.size();
+ m_contentLoaded = true;
+ return b;
+}
+
+FSNode* DirectoryNode::getChild(u32int index) {
+ if (!m_contentLoaded)
+ if (!loadContent())
+ return NULL;
+ if (index >= m_children.size()) return NULL;
+ return m_children[index];
+}
+
+FSNode* DirectoryNode::getChild(const String& name) {
+ if (!m_contentLoaded)
+ if (!loadContent())
+ return NULL;
+ for (u32int i = 0; i < m_children.size(); i++) {
+ if (name == m_children[i]->getName())
+ return m_children[i];
+ }
+ return NULL;
+}
+
+FileNode* DirectoryNode::createFile(const String& name) {
+ FileNode* n = m_fs->createFile(this, name);
+ m_length = m_children.size();
+ return n;
+}
+
+DirectoryNode* DirectoryNode::createDirectory(const String& name) {
+ DirectoryNode* n = m_fs->createDirectory(this, name);
+ m_length = m_children.size();
+ return n;
+}
+
+bool DirectoryNode::remove(FSNode* child) {
+ //Check node is indeed one of our childs
+ if (!m_contentLoaded)
+ if (!loadContent())
+ return false;
+ u32int idx = (u32int) - 1;
+ for (u32int i = 0; i < m_children.size(); i++) {
+ if (m_children[i] == child) {
+ idx = i;
+ break;
+ }
+ }
+ if (idx == (u32int) - 1) return false;
+
+ //Check if we can remove node
+ if (!m_children[idx]->removable()) return false;
+ if (m_fs != m_children[idx]->getFS()) return false; //We could !be on the same FS
+
+ //Ask FS to remove node
+ if (!m_fs->remove(this, child)) return false;
+
+ //Remove node from our children list
+ m_children[idx] = m_children.back();
+ m_children.pop();
+
+ return true;
+}
diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h
index cb1574c..5de523e 100644
--- a/Source/Kernel/VFS/DirectoryNode.class.h
+++ b/Source/Kernel/VFS/DirectoryNode.class.h
@@ -13,48 +13,19 @@ class DirectoryNode : public FSNode {
DirectoryNode(String name, FileSystem* fs, FSNode* parent, u32int permissions = 0777,
u32int uid = 0, u32int gid = 0) :
FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) {}
+ virtual ~DirectoryNode() {}
Vector<FSNode*> &getChildren() { return m_children; } //MUST BE USED ONLY BY FILESYSTEMS
u8int type() { return NT_DIRECTORY; }
-
- bool loadContent() {
- if (m_contentLoaded) return true;
- bool b = m_fs->loadContents(this);
- if (!b) return false;
- m_length = m_children.size();
- m_contentLoaded = true;
- return b;
- }
-
- FSNode* getChild(u32int index) {
- if (!m_contentLoaded)
- if (!loadContent())
- return NULL;
- if (index >= m_children.size()) return NULL;
- return m_children[index];
- }
-
- FSNode* getChild(String name) {
- if (!m_contentLoaded)
- if (!loadContent())
- return NULL;
- for (u32int i = 0; i < m_children.size(); i++) {
- if (name == m_children[i]->getName())
- return m_children[i];
- }
- return NULL;
- }
- FileNode* createFile(String name) {
- FileNode* n = m_fs->createFile(this, name);
- m_length = m_children.size();
- return n;
- }
- DirectoryNode* createDirectory(String name) {
- DirectoryNode* n = m_fs->createDirectory(this, name);
- m_length = m_children.size();
- return n;
- }
+ bool removable();
+
+ bool loadContent();
+ FSNode* getChild(u32int index);
+ FSNode* getChild(const String& name);
+ FileNode* createFile(const String& name);
+ DirectoryNode* createDirectory(const String& name);
+ bool remove(FSNode* child); //Removes a child node from this directory
};
#endif
diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h
index fb24a82..bcf9393 100644
--- a/Source/Kernel/VFS/FSNode.proto.h
+++ b/Source/Kernel/VFS/FSNode.proto.h
@@ -19,16 +19,17 @@ class FSNode {
u32int m_length;
u32int m_permissions, m_uid, m_gid;
FileSystem *m_fs;
- FSNode *m_parent;
-
+ FSNode *m_parent;
+
+ public:
FSNode(String name, FileSystem* fs, FSNode* parent, u32int length = 0, u32int permissions = 0777,
u32int uid = 0, u32int gid = 0) :
m_name(name), m_length(length), m_permissions(permissions),
m_uid(uid), m_gid(gid), m_fs(fs), m_parent(parent) {}
-
- public:
+ virtual ~FSNode() {}
virtual u8int type() = 0;
+ virtual bool removable() = 0; //True for files, false for non-empty directories, true otherwise
const String& getName() { return m_name; }
u32int getLength() { return m_length; }
diff --git a/Source/Kernel/VFS/FileNode.class.h b/Source/Kernel/VFS/FileNode.class.h
index 29fab45..b3a3f67 100644
--- a/Source/Kernel/VFS/FileNode.class.h
+++ b/Source/Kernel/VFS/FileNode.class.h
@@ -9,7 +9,10 @@ class FileNode : public FSNode {
u32int uid = 0, u32int gid = 0): FSNode(name, fs, parent, length, permissions, uid, gid) {}
public:
+ virtual ~FileNode() {}
+
u8int type() { return NT_FILE; }
+ bool removable() { return true; }
u32int read(u64int position, u32int max_length, u8int *data) {
return m_fs->read(this, position, max_length, data);
diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h
index 79bb84c..2f768a7 100644
--- a/Source/Kernel/VFS/FileSystem.proto.h
+++ b/Source/Kernel/VFS/FileSystem.proto.h
@@ -30,6 +30,7 @@ class FileSystem {
virtual bool loadContents(DirectoryNode* dir) = 0;
virtual FileNode* createFile(DirectoryNode* parent, String name) = 0;
virtual DirectoryNode* createDirectory(DirectoryNode* parent, String name) = 0;
+ virtual bool remove(DirectoryNode* parent, FSNode* node) = 0;
};
#endif
diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h
index 622d120..1021d7c 100644
--- a/Source/Kernel/VFS/VFS.ns.h
+++ b/Source/Kernel/VFS/VFS.ns.h
@@ -1,15 +1,22 @@
#ifndef DEF_VFS_NS_H
#define DEF_VFS_NS_H
-#include <VFS/FSNode.proto.h>
+#include <VFS/DirectoryNode.class.h>
#include <VFS/FileSystem.proto.h>
typedef FileSystem* (* mountcallback)(Partition* partition);
namespace VFS {
void registerMountCallback(mountcallback mcb);
- bool mount(Partition* partition);
- bool setRootNode(FSNode* root);
+ bool mount(Partition* partition, DirectoryNode mountpoint);
+ bool setRootNode(DirectoryNode* root);
+ DirectoryNode* getRootNode();
+
+ FSNode* find(const String& path, FSNode* start = 0);
+ FSNode* createFile(const String& path, FSNode* start = 0);
+ FSNode* createDirectory(const String& path, FSNode* start = 0);
+ bool remove(const String& path, FSNode* start = 0); //Returns false for non-empty directories
+ String path(FSNode* node); //Returns complete path for a node
}
#endif