aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarvin Borner2020-05-03 01:11:54 +0200
committerMarvin Borner2020-05-03 01:11:54 +0200
commit5d88097b8d704f29a64ec5b41b5f28f8b24dd2ce (patch)
treed018dd16ee38de9b710072d01ac1ebc6494be3b1 /src
parente8f1c287a63f0f71fe463f7271834538b45f8c05 (diff)
Began linked vfs with file indexing
Diffstat (limited to 'src')
-rw-r--r--src/kernel/fs/dev.c6
-rw-r--r--src/kernel/fs/ext2.c73
-rw-r--r--src/kernel/fs/ext2.h10
-rw-r--r--src/kernel/fs/vfs.c153
-rw-r--r--src/kernel/fs/vfs.h7
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