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 */ +}