Orion
Barry Importing existing Orion kernel d41a53c (3 years, 2 months ago)
diff --git a/vfs/devfs/super.c b/vfs/devfs/super.c
new file mode 100644
index 0000000..e57d60b
--- /dev/null
+++ b/vfs/devfs/super.c
@@ -0,0 +1,85 @@
+/*
+ * This file controls the superblock for DevFS. It supports mounting new DevFS
+ * filesystems. The VFS will use the calls here when dealing directly with the
+ * filesystem structure.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "fs.h"
+#include "../vfs.h"
+#include "../super.h"
+#include "../inode.h"
+#include "../../mem/heap.h"
+
+Inode *devfs_mount(FileSystemType *type, int flags,
+ const char *dev, void *data);
+Inode *devfs_alloc_inode(SuperBlock *sb);
+
+FileSystemType devfsType = {
+ .name = "DevFS",
+ .mount = devfs_mount,
+// .kill_sb = devfs_kill_sb,
+};
+
+SuperOps devfsSuperOps = {
+ .alloc_inode = devfs_alloc_inode,
+// .free_inode = devfs_free_inode,
+// .write_inode = devfs_write_inode,
+// .delete_inode = devfs_delete_inode,
+};
+
+Inode devfsRoot = {
+ .mode = S_IFDIR | 0755,
+ .ops = &devfsInodeOps,
+ .fileOps = &devfsFileOps,
+ .size = 4096,
+};
+
+/* Mount a DevFS instance */
+Inode *
+devfs_mount(FileSystemType *type, int flags, const char *dev, void *data)
+{
+ if (type != &devfsType)
+ return NULL;
+
+ SuperBlock *super = kmalloc(sizeof(SuperBlock));
+
+ super->type = type;
+ super->ops = &devfsSuperOps;
+ init_lock(&super->lock);
+
+ /*
+ * DevFS is special - it has a globally unique root. This means that no
+ * matter where a DevFS instance is mounted, it will be mounted with
+ * this inode, meaning the contents are the same. It basically causes
+ * the mountpoint to act as a hard-link. This means you can mount a new
+ * DevFS instance in a chroot() environment, and not have to remake all
+ * the device nodes.
+ */
+ Inode *inode = &devfsRoot;
+ inode->nlink++;
+ inode->super = super;
+ /* FIXME: need an inode per super, or only one super */
+ super->root = inode;
+ /* Never free */
+ if (!inode->usage)
+ inode_get(inode);
+
+ return inode;
+}
+
+/* Allocate an inode */
+Inode *
+devfs_alloc_inode(SuperBlock *sb)
+{
+ Inode *inode = kmalloc(sizeof(Inode));
+ init_lock(&inode->lock);
+ inode->ops = &devfsInodeOps;
+ inode->fileOps = &devfsFileOps;
+ inode->super = sb;
+ inode->nlink = 1;
+ return inode_get(inode); /* This ensures that the inode is never free */
+}