diff options
author | Marvin Borner | 2020-04-21 14:18:20 +0200 |
---|---|---|
committer | Marvin Borner | 2020-04-21 14:18:20 +0200 |
commit | 40b98b3eb3f897d3d12199c79b30e2fd9151baf9 (patch) | |
tree | 0f10c78c95bd24a4b5cef2a3948dd3abbc1a4eb7 /src/kernel/fs | |
parent | c83104329214bd618444d6e0242bb0317f52dbbc (diff) |
Added very basic vfs
Diffstat (limited to 'src/kernel/fs')
-rw-r--r-- | src/kernel/fs/ext2.c | 96 | ||||
-rw-r--r-- | src/kernel/fs/ext2.h | 5 | ||||
-rw-r--r-- | src/kernel/fs/vfs.c | 48 | ||||
-rw-r--r-- | src/kernel/fs/vfs.h | 66 |
4 files changed, 213 insertions, 2 deletions
diff --git a/src/kernel/fs/ext2.c b/src/kernel/fs/ext2.c index c95c134..ce8338a 100644 --- a/src/kernel/fs/ext2.c +++ b/src/kernel/fs/ext2.c @@ -7,6 +7,7 @@ #include <kernel/memory/alloc.h> #include <kernel/lib/lib.h> #include <kernel/lib/stdlib.h> +#include <kernel/fs/vfs.h> static struct ext2_superblock superblock; static struct bgd *bgdt; @@ -231,4 +232,97 @@ uint32_t ext2_look_up_path(char *path) return 0; return inode; -}
\ No newline at end of file +} + +// VFS Implementation + +void ext2_vfs_open(struct fs_node *node) +{ + node->inode = ext2_look_up_path(node->name); + + if (node->inode != 0) { + struct ext2_file *file = kmalloc(sizeof *file); + ext2_open_inode(node->inode, file); + + node->impl = file; + + // TODO: More file metadata + } +} + +static void ext2_vfs_close(struct fs_node *node) +{ + kfree(node->impl); +} + +static uint32_t ext2_vfs_read(struct fs_node *node, size_t offset, size_t size, char *buf) +{ + if (offset != ((struct ext2_file *)node->impl)->pos) { + panic("Seeking is currently unsupported for Ext2 files"); + return 0; + } + + return (uint32_t)ext2_read(node->impl, (uint8_t *)buf, size); +} + +static uint32_t ext2_vfs_write(struct fs_node *node, size_t offset, size_t size, char *buf) +{ + panic("Writing to Ext2 is currently unsupported"); + + return 0; +} + +static struct dir_entry *ext2_vfs_read_dir(struct fs_node *node, size_t index) +{ + struct ext2_dirent ext2_dir; + + if (ext2_next_dirent(node->impl, &ext2_dir)) { + struct dir_entry *dir = kmalloc(sizeof *dir); + + dir->inode = ext2_dir.inode_num; + strcpy(dir->name, (char *)ext2_dir.name); + + return dir; + } else { + return NULL; + } +} + +static struct fs_node *ext2_vfs_find_dir(struct fs_node *node, char *name) +{ + uint32_t inode = ext2_find_in_dir(node->inode, name); + if (inode == 0) { + return NULL; + } else { + struct fs_node *found = kmalloc(sizeof *found); + found->inode = inode; + + return found; + } +} + +void ext2_mount(struct fs_node *mountpoint) +{ + assert(mountpoint->node_ptr == NULL && (mountpoint->type & MOUNTPOINT_NODE) == 0); + assert((mountpoint->type & DIR_NODE) != 0); + + struct fs_node *ext2_root = (struct fs_node *)kmalloc(sizeof(struct fs_node)); + ext2_root->name[0] = '\0'; + ext2_root->permissions = 0; + ext2_root->uid = 0; + ext2_root->gid = 0; + ext2_root->inode = ROOT_INODE; + ext2_root->length = 0; + ext2_root->type = DIR_NODE; + ext2_root->read = ext2_vfs_read; + ext2_root->write = ext2_vfs_write; + ext2_root->open = ext2_vfs_open; + ext2_root->close = ext2_vfs_close; + ext2_root->read_dir = ext2_vfs_read_dir; + ext2_root->find_dir = ext2_vfs_find_dir; + ext2_root->node_ptr = NULL; + ext2_root->impl = NULL; + + mountpoint->type |= MOUNTPOINT_NODE; + mountpoint->node_ptr = ext2_root; +} diff --git a/src/kernel/fs/ext2.h b/src/kernel/fs/ext2.h index e5e0f1c..f3ea4a0 100644 --- a/src/kernel/fs/ext2.h +++ b/src/kernel/fs/ext2.h @@ -4,6 +4,7 @@ #include <stdint.h> #include <stddef.h> #include <stdbool.h> +#include <kernel/fs/vfs.h> #define ROOT_INODE 2 @@ -137,4 +138,6 @@ bool ext2_next_dirent(struct ext2_file *file, struct ext2_dirent *dir); uint32_t ext2_find_in_dir(uint32_t dir_inode, const char *name); uint32_t ext2_look_up_path(char *path); -#endif
\ No newline at end of file +void ext2_mount(struct fs_node *mountpoint); + +#endif diff --git a/src/kernel/fs/vfs.c b/src/kernel/fs/vfs.c new file mode 100644 index 0000000..075117e --- /dev/null +++ b/src/kernel/fs/vfs.c @@ -0,0 +1,48 @@ +#include <stddef.h> +#include <kernel/fs/vfs.h> + +struct fs_node *fs_root = NULL; + +uint32_t read_fs_node(struct fs_node *node, size_t offset, size_t size, char *buf) +{ + if (node->read != NULL) + return node->read(node, offset, size, buf); + else + return 0; +} + +uint32_t write_fs_node(struct fs_node *node, size_t offset, size_t size, char *buf) +{ + if (node->write != NULL) + return node->write(node, offset, size, buf); + else + return 0; +} + +void open_fs_node(struct fs_node *node, bool read, bool write) +{ + if (node->open != NULL) + node->open(node); +} + +void close_fs_node(struct fs_node *node) +{ + if (node->close != NULL) + node->close(node); +} + +struct dir_entry *read_dir_node(struct fs_node *node, size_t index) +{ + if ((node->type & DIR_NODE) != 0 && node->read_dir != NULL) + return node->read_dir(node, index); + else + return NULL; +} + +struct fs_node *find_dir_node(struct fs_node *node, char *name) +{ + if ((node->type & DIR_NODE) != 0 && node->find_dir != NULL) + return node->find_dir(node, name); + else + return NULL; +} diff --git a/src/kernel/fs/vfs.h b/src/kernel/fs/vfs.h new file mode 100644 index 0000000..41d80eb --- /dev/null +++ b/src/kernel/fs/vfs.h @@ -0,0 +1,66 @@ +#ifndef MELVIX_VFS_H +#define MELVIX_VFS_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#define MAX_NAME_LENGTH 128 + +enum node_type { + FILE_NODE = 1, + DIR_NODE, + CHAR_DEV_NODE, + BLOCK_DEV_NODE, + PIPE_NODE, + SYMLINK_NODE, + MOUNTPOINT_NODE = 8 +}; + +struct fs_node; +struct dir_entry; + +typedef uint32_t (*read)(struct fs_node *, size_t, size_t, char *); +typedef uint32_t (*write)(struct fs_node *, size_t, size_t, char *); +typedef void (*open)(struct fs_node *); +typedef void (*close)(struct fs_node *); + +typedef struct dir_entry *(*read_dir)(struct fs_node *, size_t); +typedef struct fs_node *(*find_dir)(struct fs_node *, char *); + +struct fs_node { + char name[MAX_NAME_LENGTH]; + uint32_t length; + uint32_t inode; + uint32_t permissions; + uint32_t uid; + uint32_t gid; + enum node_type type; + + struct fs_node *node_ptr; + + void *impl; + + read read; + write write; + open open; + close close; + read_dir read_dir; + find_dir find_dir; +}; + +struct dir_entry { + char name[MAX_NAME_LENGTH]; + uint32_t inode; +}; + +struct fs_node *fs_root; + +uint32_t read_fs_node(struct fs_node *node, size_t offset, size_t size, char *buf); +uint32_t write_fs_node(struct fs_node *node, size_t offset, size_t size, char *buf); +void open_fs_node(struct fs_node *node, bool read, bool write); +void close_fs_node(struct fs_node *node); +struct dir_entry *read_dir_node(struct fs_node *node, size_t index); +struct fs_node *find_dir_node(struct fs_node *node, char *name); + +#endif |