diff options
author | dzwdz | 2021-08-22 15:51:45 +0200 |
---|---|---|
committer | dzwdz | 2021-08-22 15:51:45 +0200 |
commit | 2c0113cb72b63ba7177d14a60bcd9e51eee8e5cf (patch) | |
tree | 82d53fd92996da15bca3b9321a85e9f88f6e566c /src/kernel | |
parent | ac74cec51fa9c31e4c8cea2dd9f01b7b895d61b4 (diff) |
basic mount resolving
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/proc.c | 1 | ||||
-rw-r--r-- | src/kernel/proc.h | 3 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 55 | ||||
-rw-r--r-- | src/kernel/syscalls.h | 3 | ||||
-rw-r--r-- | src/kernel/vfs/mount.h | 7 |
5 files changed, 67 insertions, 2 deletions
diff --git a/src/kernel/proc.c b/src/kernel/proc.c index e1b650c..f826d8a 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -16,6 +16,7 @@ struct process *process_seed() { proc->sibling = NULL; proc->child = NULL; proc->parent = NULL; + proc->mount = NULL; proc->id = next_pid++; process_first = proc; diff --git a/src/kernel/proc.h b/src/kernel/proc.h index c2dfde4..ffc342a 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -1,5 +1,6 @@ #pragma once #include <kernel/arch/generic.h> +#include <kernel/vfs/mount.h> enum process_state { PS_RUNNING, @@ -25,6 +26,8 @@ struct process { // PS_WAITS4CHILDDEATH - buffer for said message void *saved_addr; size_t saved_len; + + struct vfs_mount *mount; }; extern struct process *process_first; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 13e0535..0a88c98 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -67,12 +67,13 @@ int _syscall_fork() { fd_t _syscall_fs_open(const char *path, size_t len) { struct virt_iter iter; - static char buffer[PATH_MAX]; // holds the simplified path + struct vfs_mount *mount = process_current->mount; + static char buffer[PATH_MAX]; // holds the path size_t pos = 0; if (len > PATH_MAX) return -1; - // copy the path to buffer + // copy the path to the kernel virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false); while (virt_iter_next(&iter)) { memcpy(buffer + pos, iter.frag, iter.frag_len); @@ -83,7 +84,55 @@ fd_t _syscall_fs_open(const char *path, size_t len) { len = path_simplify(buffer, buffer, len); if (len < 0) return -1; + // find mount + for (mount = process_current->mount; mount; mount = mount->prev) { + if (mount->prefix_len > len) + continue; + if (memcmp(mount->prefix, buffer, mount->prefix_len) == 0) + break; + } + tty_write(buffer, len); + tty_const(" from mount "); + if (mount) + tty_write(mount->prefix, mount->prefix_len); + else + tty_const("[none]"); + + return -1; +} + +int _syscall_mount(const char *path, int len, fd_t fd) { + struct virt_iter iter; + struct vfs_mount *mount; + char *path_buf; + size_t pos = 0; + + if (len > PATH_MAX) return -1; + + // copy the path to the kernel + virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false); + path_buf = kmalloc(len); + while (virt_iter_next(&iter)) { // TODO abstract away + memcpy(path_buf + pos, iter.frag, iter.frag_len); + pos += iter.frag_len; + } + if (iter.error) goto fail; + + // simplify it + len = path_simplify(path_buf, path_buf, len); + if (len < 0) goto fail; + // TODO remove trailing slash + + // append to mount list + mount = kmalloc(sizeof(struct vfs_mount)); + mount->prev = process_current->mount; + mount->prefix = path_buf; + mount->prefix_len = len; + process_current->mount = mount; + return 0; +fail: + kfree(path_buf); return -1; } @@ -109,6 +158,8 @@ int syscall_handler(int num, int a, int b, int c) { return _syscall_fork(); case _SYSCALL_FS_OPEN: return _syscall_fs_open((void*)a, b); + case _SYSCALL_MOUNT: + return _syscall_mount((void*)a, b, c); case _SYSCALL_DEBUGLOG: return _syscall_debuglog((void*)a, b); default: diff --git a/src/kernel/syscalls.h b/src/kernel/syscalls.h index 5f55454..c8dca05 100644 --- a/src/kernel/syscalls.h +++ b/src/kernel/syscalls.h @@ -3,6 +3,7 @@ #include <stddef.h> typedef int fd_t; +typedef int fs_handle_t; enum { // idc about stable syscall numbers just yet @@ -11,6 +12,7 @@ enum { _SYSCALL_FORK, _SYSCALL_FS_OPEN, + _SYSCALL_MOUNT, _SYSCALL_DEBUGLOG }; @@ -32,6 +34,7 @@ int _syscall_await(char *buf, int len); int _syscall_fork(); fd_t _syscall_fs_open(const char *path, size_t len); +int _syscall_mount(const char *path, int len, fd_t fd); /** Prints a message to the debug console. * @return the amount of bytes written (can be less than len) diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h new file mode 100644 index 0000000..b99f97e --- /dev/null +++ b/src/kernel/vfs/mount.h @@ -0,0 +1,7 @@ +#pragma once + +struct vfs_mount { + struct vfs_mount *prev; + char *prefix; + size_t prefix_len; +}; |