/* * 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 #include #include #include #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 */ }