diff options
author | Marvin Borner | 2020-05-03 01:11:54 +0200 |
---|---|---|
committer | Marvin Borner | 2020-05-03 01:11:54 +0200 |
commit | 5d88097b8d704f29a64ec5b41b5f28f8b24dd2ce (patch) | |
tree | d018dd16ee38de9b710072d01ac1ebc6494be3b1 /src/kernel/fs | |
parent | e8f1c287a63f0f71fe463f7271834538b45f8c05 (diff) |
Began linked vfs with file indexing
Diffstat (limited to 'src/kernel/fs')
-rw-r--r-- | src/kernel/fs/dev.c | 6 | ||||
-rw-r--r-- | src/kernel/fs/ext2.c | 73 | ||||
-rw-r--r-- | src/kernel/fs/ext2.h | 10 | ||||
-rw-r--r-- | src/kernel/fs/vfs.c | 153 | ||||
-rw-r--r-- | src/kernel/fs/vfs.h | 7 |
5 files changed, 236 insertions, 13 deletions
diff --git a/src/kernel/fs/dev.c b/src/kernel/fs/dev.c index 52d8e01..b0e7619 100644 --- a/src/kernel/fs/dev.c +++ b/src/kernel/fs/dev.c @@ -25,11 +25,7 @@ void dev_make(char *name, read read, write write) strcpy(path, "/dev/"); strcpy(&path[strlen("/dev/")], name); - // TODO: Touch dev files in the vfs instead of opening it via ext2 - struct fs_node *node = (struct fs_node *)kmalloc(sizeof(struct fs_node)); - strcpy(node->name, path); - fs_open(node); - kfree(path); + struct fs_node *node = vfs_touch(fs_root, path); if (node->inode == 0) { warn("Couldn't resolve path"); diff --git a/src/kernel/fs/ext2.c b/src/kernel/fs/ext2.c index 3956fd4..77010bb 100644 --- a/src/kernel/fs/ext2.c +++ b/src/kernel/fs/ext2.c @@ -27,24 +27,24 @@ void ext2_init_fs() read_inode(&root_inode, ROOT_INODE); debug("Creation time: %d", root_inode.creation_time); debug("UID: %d", root_inode.uid); - debug("Type & perms: 0x%x", root_inode.type_and_permissions); + debug("Type & perms: 0x%x", root_inode.mode); debug("Size: %d", root_inode.size); fs_root = (struct fs_node *)kmalloc(sizeof(struct fs_node)); strcpy(fs_root->name, "root"); fs_root->type = DIR_NODE; ext2_mount(fs_root); + fs_root = fs_root->node_ptr; // why not? :) log("Files in /"); - ext2_root = fs_root->node_ptr; - fs_open(ext2_root); + fs_open(fs_root); struct dirent *dirent; int i = 0; - while ((dirent = fs_read_dir(ext2_root, i)) != NULL) { + while ((dirent = fs_read_dir(fs_root, i)) != NULL) { log("%s", dirent->name); i++; } - /* fs_close(ext2_root); */ + /* fs_close(fs_root); */ } static void read_block(uint32_t block_num, void *buf) @@ -238,10 +238,66 @@ uint32_t ext2_look_up_path(char *path) return inode; } +struct fs_node *ext2_index(char *dir) +{ + log("\n\n"); + struct fs_node *start = (struct fs_node *)kmalloc(sizeof(struct fs_node)); + ext2_node_init(start); + strcpy(start->name, dir); + start->inode = ext2_look_up_path(dir); + start->type = DIR_NODE; + fs_open(start); + log("%d", start->inode); + struct fs_node *parent = start; + + struct dirent *dirent; + int i = 0; + while ((dirent = fs_read_dir(start, i)) != NULL) { + i++; + if (dirent->name[0] == '.') + continue; + + char *name = dir; + strcat(name, "/"); + strcat(name, dirent->name); + log(name); + + struct fs_node *sub = fs_find_dir(start, dirent->name); + ext2_node_init(sub); + strcpy(sub->name, name); + fs_open(sub); + + if (sub->type == DIR_NODE) { + sub = ext2_index(name); + } else if (sub->type == FILE_NODE) { + sub = (struct fs_node *)kmalloc(sizeof(struct fs_node)); + ext2_node_init(sub); + strcpy(sub->name, name); + sub->inode = ext2_look_up_path(name); + } else if (sub->type == (enum node_type)NULL) { + warn("No node type!"); + } else { + warn("Unsupported node type!"); + } + + if (parent->node_ptr == NULL) { + parent->node_ptr = sub; + start = sub; + } else { + start->link = sub; + start = sub; + } + } + + return parent; +} + // Interface uint8_t *read_file(char *path) { + ext2_index("/."); + halt_loop(); uint32_t inode = ext2_look_up_path(path); struct ext2_file file; ext2_open_inode(inode, &file); @@ -268,6 +324,13 @@ void ext2_vfs_open(struct fs_node *node) ext2_node_init(node); ext2_open_inode(node->inode, file); node->impl = file; + + if (S_ISDIR(file->inode.mode)) + node->type = DIR_NODE; + else if (S_ISREG(file->inode.mode)) + node->type = FILE_NODE; + else // TODO: Add missing + warn("Unsupported filetype!"); } } diff --git a/src/kernel/fs/ext2.h b/src/kernel/fs/ext2.h index f98531e..2fd0e83 100644 --- a/src/kernel/fs/ext2.h +++ b/src/kernel/fs/ext2.h @@ -58,7 +58,7 @@ struct bgd { } __attribute__((packed)); struct ext2_inode { - uint16_t type_and_permissions; + uint16_t mode; uint16_t uid; uint32_t size; @@ -93,6 +93,14 @@ struct ext2_inode { #define S_IFLNK 0xA000 #define S_IFSOCK 0xC000 +#define S_ISDIR(m) ((m & 0170000) == 0040000) +#define S_ISCHR(m) ((m & 0170000) == 0020000) +#define S_ISBLK(m) ((m & 0170000) == 0060000) +#define S_ISREG(m) ((m & 0170000) == 0100000) +#define S_ISFIFO(m) ((m & 0170000) == 0010000) +#define S_ISLNK(m) ((m & 0170000) == 0120000) +#define S_ISSOCK(m) ((m & 0170000) == 0140000) + #define S_ISUID 04000 #define S_ISGID 02000 #define S_ISTICK 01000 diff --git a/src/kernel/fs/vfs.c b/src/kernel/fs/vfs.c index 2b4cda4..6d29eed 100644 --- a/src/kernel/fs/vfs.c +++ b/src/kernel/fs/vfs.c @@ -3,6 +3,8 @@ #include <kernel/fs/vfs.h> #include <kernel/fs/ext2.h> #include <kernel/lib/stdlib.h> +#include <kernel/memory/alloc.h> +#include <kernel/system.h> struct fs_node *fs_root = NULL; @@ -27,7 +29,7 @@ void fs_open(struct fs_node *node) if (node->open != NULL) node->open(node); else // TODO: Better ext2 default open workaround - ext2_root->open(node); + fs_root->open(node); } void fs_close(struct fs_node *node) @@ -35,7 +37,7 @@ void fs_close(struct fs_node *node) if (node->close != NULL) node->close(node); else - ext2_root->open(node); + fs_root->open(node); } struct dirent *fs_read_dir(struct fs_node *node, uint32_t index) @@ -52,4 +54,151 @@ struct fs_node *fs_find_dir(struct fs_node *node, char *name) return node->find_dir(node, name); else return (struct fs_node *)NULL; +} + +// TODO: This should be somewhere else ig +char *next_str(char *str) +{ + str = &str[strlen(str)]; + + int i = 0; + while (str[i] == 0) + i++; + + return &str[i]; +} + +// By far not the fastest algorithm +struct fs_node *fs_path(struct fs_node *node, char *name) +{ + if (name[0] == '/') + return node; + + char *cpy = (char *)kmalloc(strlen(name) + 2); + strcpy(cpy, name); + cpy[strlen(name) + 1] = 1; + + name = cpy; + char *end = &name[strlen(name)]; + + int len = strlen(name); + for (int i = 0; i < len; i++) + if (name[i] == '/') + name[i] = 0; + + if (strlen(name) == 0) + name = next_str(name); + + do { + node = node->node_ptr; + + while (node != NULL) { + if (strcmp(node->name, name) == 0) + break; + + node = node->link; + } + + if (node == NULL) { + kfree(cpy); + return NULL; + } + + name = next_str(name); + } while ((uint32_t)name < (uint32_t)end); + + kfree(cpy); + return node; +} + +void vfs_ls(char *path) +{ + struct fs_node *dir = fs_path(fs_root, path); + if (dir == NULL) { + warn("Invalid path"); + return; + } + + struct fs_node *link = dir->node_ptr; + + log("Listing for %s", path); + while (link != NULL) { + log(link->name); + link = link->link; + } +} + +struct fs_node *vfs_get_dir(struct fs_node *node, char *name) +{ + char *cpy = (char *)kmalloc(strlen(name) + 2); + char *ref = cpy; + strcpy(cpy, name); + cpy[strlen(name) + 1] = 1; + name = cpy; + + for (int i = strlen(name); i >= 0; i--) + if (name[i] == '/') { + name[i] = 0; + break; + } + + struct fs_node *output; + if (strlen(name) == 0) + output = fs_root; + else + output = fs_path(node, name); + + kfree(ref); + return output; +} + +char *basename(char *name) +{ + int i; + for (i = strlen(name); i >= 0; i--) + if (name[i] == '/') + return &name[i + 1]; + + return name; +} + +// TODO: Implement file touching in ext2 +struct fs_node *vfs_touch(struct fs_node *node, char *name) +{ + struct fs_node *dir = vfs_get_dir(node, name); + + if (dir == NULL) + return NULL; + + struct fs_node *file = (struct fs_node *)kmalloc(sizeof(struct fs_node)); + ext2_node_init(file); + file->type = FILE_NODE; + strcpy(file->name, basename(name)); + + //ext2_file *entry = ext2_new_file(); + //strcpy(file->name, entry->name); + + file->link = dir->node_ptr; + dir->node_ptr = file; + + return file; +} + +struct fs_node *vfs_mkdir(struct fs_node *node, char *name) +{ + struct fs_node *dir = vfs_get_dir(node, name); + if (dir == NULL) { + warn("Invalid path"); + return NULL; + } + + struct fs_node *file = (struct fs_node *)kmalloc(sizeof(struct fs_node)); + ext2_node_init(file); + file->type = DIR_NODE; + strcpy(file->name, basename(name)); + + file->link = dir->node_ptr; + dir->node_ptr = file; + + return file; }
\ No newline at end of file diff --git a/src/kernel/fs/vfs.h b/src/kernel/fs/vfs.h index 867fae2..26c34f9 100644 --- a/src/kernel/fs/vfs.h +++ b/src/kernel/fs/vfs.h @@ -36,6 +36,7 @@ struct fs_node { struct dev *dev; struct fs_node *node_ptr; + struct fs_node *link; void *impl; @@ -61,4 +62,10 @@ void fs_close(struct fs_node *node); struct dirent *fs_read_dir(struct fs_node *node, uint32_t index); struct fs_node *fs_find_dir(struct fs_node *node, char *name); +char *basename(char *name); +void vfs_ls(char *path); +struct fs_node *vfs_get_dir(struct fs_node *node, char *name); +struct fs_node *vfs_touch(struct fs_node *node, char *name); +struct fs_node *vfs_mkdir(struct fs_node *node, char *name); + #endif
\ No newline at end of file |