BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / vfs / devfs / super.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 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 */
+}