Nucleus
Barry Device file system 88d672a (3 years, 3 months ago)
diff --git a/vfs/devfs/file.c b/vfs/devfs/file.c
new file mode 100644
index 0000000..a984c1d
--- /dev/null
+++ b/vfs/devfs/file.c
@@ -0,0 +1,75 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <nucleus/memory.h>
+#include <nucleus/vfs.h>
+
+size_t devfs_read(File *file, char *buf, size_t size, off_t offset);
+size_t devfs_write(File *file, char *buf, size_t size, off_t offset);
+int devfs_open(File *file);
+
+FileOps devfsFileOps = {
+ .read = devfs_read,
+ .write = devfs_write,
+ .open = devfs_open,
+};
+
+/* Read a file */
+size_t
+devfs_read(File *file, char *buf, size_t size, off_t offset)
+{
+ if (offset > file->inode->size)
+ return 0;
+ if (size + offset > file->inode->size)
+ size = file->inode->size - offset;
+
+ Page *page;
+ char *data;
+ size_t count = 0;
+ uint16_t min, indent = offset % PAGE_SIZE;
+ while (size) {
+ min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
+ page = find_page(file->inode->pages, offset);
+ if (!page)
+ break;
+ data = map_page(page);
+ memcpy(buf + count, data + indent, min);
+ size -= min;
+ count += min;
+ indent = 0;
+ }
+ return count;
+}
+
+/* Write a file */
+size_t
+devfs_write(File *file, char *buf, size_t size, off_t offset)
+{
+ if (size + offset > file->inode->size)
+ file->inode->size = size + offset;
+
+ Page *page;
+ char *data;
+ size_t count = 0;
+ uint16_t min, indent = offset % PAGE_SIZE;
+ while (size) {
+ min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
+ page = find_page(file->inode->pages, offset);
+ if (!page)
+ page = create_page(file->inode->pages, alloc_frame(),
+ offset);
+ data = map_page(page);
+ memcpy(data + indent, buf + count, min);
+ size -= min;
+ count += min;
+ indent = 0;
+ }
+ return count;
+}
+
+/* Open a file */
+int
+devfs_open(File *file)
+{
+ return 0;
+}
diff --git a/vfs/devfs/inode.c b/vfs/devfs/inode.c
new file mode 100644
index 0000000..3b60e38
--- /dev/null
+++ b/vfs/devfs/inode.c
@@ -0,0 +1,59 @@
+#include <nucleus/vfs.h>
+
+int devfs_create(Inode *inode, DirEntry *entry, mode_t mode);
+Inode *devfs_lookup(Inode *inode, const char *name);
+int devfs_mkdir(Inode *inode, DirEntry *entry, mode_t mode);
+int devfs_rmdir(Inode *inode, DirEntry *entry);
+int devfs_mknod(Inode *inode, DirEntry *entry, mode_t mode, dev_t dev);
+int devfs_rename(Inode *si, DirEntry *sde, Inode *di, DirEntry *dde);
+
+InodeOps devfsInodeOps = {
+ .create = devfs_create,
+ .lookup = devfs_lookup,
+ .mkdir = devfs_mkdir,
+ .rmdir = devfs_rmdir,
+ .mknod = devfs_mknod,
+ .rename = devfs_rename,
+};
+
+/* Create a file */
+int
+devfs_create(Inode *inode, DirEntry *entry, mode_t mode)
+{
+ return 0;
+}
+
+/* Look up a directory entry in a directory */
+Inode *
+devfs_lookup(Inode *inode, const char *name)
+{
+ return NULL;
+}
+
+/* Make a directory */
+int
+devfs_mkdir(Inode *inode, DirEntry *entry, mode_t mode)
+{
+ return 0;
+}
+
+/* Remove a directory */
+int
+devfs_rmdir(Inode *inode, DirEntry *entry)
+{
+ return 0;
+}
+
+/* Make a node */
+int
+devfs_mknod(Inode *inode, DirEntry *entry, mode_t mode, dev_t dev)
+{
+ return 0;
+}
+
+/* Rename/mode a directory entry */
+int
+devfs_rename(Inode *si, DirEntry *sde, Inode *di, DirEntry *dde)
+{
+ return 0;
+}
diff --git a/vfs/devfs/super.c b/vfs/devfs/super.c
new file mode 100644
index 0000000..bfab4e9
--- /dev/null
+++ b/vfs/devfs/super.c
@@ -0,0 +1,44 @@
+#include <sys/stat.h>
+#include <nucleus/vfs.h>
+
+extern InodeOps devfsInodeOps;
+extern FileOps devfsFileOps;
+
+Inode *devfs_alloc_inode(SuperBlock *sb);
+
+SuperOps devfsSuperOps = {
+ .alloc_inode = devfs_alloc_inode,
+};
+
+/* Mount a devfs instance */
+Inode *
+devfs_mount(FSType *type, int flags, const char *dev, void *data)
+{
+ static SuperBlock *super = NULL;
+ if (!super) {
+ super = new(&superBlockType);
+ super->type = get(type);
+ super->ops = &devfsSuperOps;
+ }
+
+ static Inode *inode = NULL;
+ if (!inode) {
+ Inode *inode = super_alloc_inode(super);
+ inode->mode = S_IFDIR | 0755;
+ super->root = inode;
+ }
+
+ return inode;
+}
+
+/* Allocate an inode */
+Inode *
+devfs_alloc_inode(SuperBlock *sb)
+{
+ Inode *inode = new(&inodeType);
+ inode->ops = &devfsInodeOps;
+ inode->fileOps = &devfsFileOps;
+ inode->super = get(sb);
+ inode->nlink = 1;
+ return inode;
+}