summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-09-12 12:47:51 +0200
committerdzwdz2021-09-12 12:47:51 +0200
commite65d58357aaff7c1d05c06753538383478c1b0e9 (patch)
tree524acff4943892d62cfcd33a26fc83cace6aef83
parent8fe035d7d75d09f314f9e8aefe1dcaf1e10d1954 (diff)
vfs request refactor pt1
-rw-r--r--src/kernel/proc.h2
-rw-r--r--src/kernel/syscalls.c17
-rw-r--r--src/kernel/vfs/backend.h29
-rw-r--r--src/kernel/vfs/mount.h2
-rw-r--r--src/kernel/vfs/request.c (renamed from src/kernel/vfs/backend.c)35
-rw-r--r--src/kernel/vfs/request.h43
-rw-r--r--src/kernel/vfs/root.c12
-rw-r--r--src/kernel/vfs/root.h4
8 files changed, 78 insertions, 66 deletions
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 0628ebf..13e4125 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -30,7 +30,7 @@ struct process {
char __user *buf;
size_t len;
} death_msg;
- struct vfs_op_request *pending_req; // PS_WAITS4FS
+ struct vfs_request pending_req; // PS_WAITS4FS
};
struct vfs_mount *mount;
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index c1ba47a..fdf4b84 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -75,7 +75,7 @@ handle_t _syscall_open(const char __user *path, int len) {
return -1;
// copy the path to the kernel
- // path_buf gets freed in vfs_backend_finish
+ // path_buf gets freed in vfs_request_finish
path_buf = kmalloc(len);
if (!virt_cpy_from(process_current->pages, path_buf, path, len))
goto fail;
@@ -86,12 +86,15 @@ handle_t _syscall_open(const char __user *path, int len) {
mount = vfs_mount_resolve(process_current->mount, path_buf, len);
if (!mount) goto fail;
- vfs_backend_dispatch(mount->backend, (struct vfs_op) {
+ vfs_request_create((struct vfs_request) {
.type = VFSOP_OPEN,
.open = {
.path = &path_buf[mount->prefix_len],
.path_len = len - mount->prefix_len,
- }
+ },
+
+ .caller = process_current,
+ .backend = mount->backend,
});
// doesn't return / fallthrough to fail
@@ -141,13 +144,15 @@ int _syscall_write(handle_t handle_num, const char __user *buf, int len) {
struct handle *handle = &process_current->handles[handle_num];
if (handle_num < 0 || handle_num >= HANDLE_MAX) return -1;
if (handle->type != HANDLE_FILE) return -1;
- vfs_backend_dispatch(handle->file.backend, (struct vfs_op) {
+ vfs_request_create((struct vfs_request) {
.type = VFSOP_WRITE,
.rw = {
.buf = (userptr_t) buf,
.buf_len = len,
.id = handle->file.id,
- }
+ },
+ .caller = process_current,
+ .backend = handle->file.backend,
});
return -1;
}
@@ -206,7 +211,7 @@ int _syscall_fs_wait(handle_t back, void __user *info) {
// handle queued requests
struct process *queued = back_handle->fs.backend->queue;
back_handle->fs.backend->queue = NULL; // TODO get the next queued proc
- vfs_request_pass2handler(queued->pending_req);
+ vfs_request_pass2handler(&queued->pending_req);
} else {
process_switch_any();
}
diff --git a/src/kernel/vfs/backend.h b/src/kernel/vfs/backend.h
deleted file mode 100644
index bc0dc45..0000000
--- a/src/kernel/vfs/backend.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include <shared/vfs.h>
-
-enum vfs_backend_type {
- VFS_BACK_ROOT,
- VFS_BACK_USER,
-};
-
-// describes something which can act as an access function
-struct vfs_backend {
- enum vfs_backend_type type;
-
- // only used with VFS_BACK_USER
- struct process *handler;
- struct process *queue;
-};
-
-// describes an in-progress vfs call
-struct vfs_op_request {
- struct vfs_op op;
- struct process *caller;
- struct vfs_backend *backend;
-};
-
-
-// these can switch processes
-_Noreturn void vfs_backend_dispatch(struct vfs_backend *backend, struct vfs_op op);
-_Noreturn void vfs_request_pass2handler(struct vfs_op_request *);
-_Noreturn void vfs_backend_finish(struct vfs_op_request *, int ret);
diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h
index ac55184..5fb6d16 100644
--- a/src/kernel/vfs/mount.h
+++ b/src/kernel/vfs/mount.h
@@ -1,5 +1,5 @@
#pragma once
-#include <kernel/vfs/backend.h>
+#include <kernel/vfs/request.h>
#include <stddef.h>
struct vfs_mount {
diff --git a/src/kernel/vfs/backend.c b/src/kernel/vfs/request.c
index b9bc9af..1212aa4 100644
--- a/src/kernel/vfs/backend.c
+++ b/src/kernel/vfs/request.c
@@ -1,41 +1,34 @@
#include <kernel/mem/alloc.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
-#include <kernel/vfs/backend.h>
+#include <kernel/vfs/request.h>
#include <kernel/vfs/root.h>
// dispatches a VFS operation to the correct process
-_Noreturn void vfs_backend_dispatch(struct vfs_backend *backend, struct vfs_op op) {
- struct vfs_op_request *req = kmalloc(sizeof *req); // freed in vfs_backend_finish
+_Noreturn void vfs_request_create(struct vfs_request req) {
int ret;
- *req = (struct vfs_op_request) {
- .op = op,
- .caller = process_current,
- .backend = backend,
- };
-
- switch (backend->type) {
+ switch (req.backend->type) {
case VFS_BACK_ROOT:
- ret = vfs_root_handler(req);
- vfs_backend_finish(req, ret);
+ ret = vfs_root_handler(&req);
+ vfs_request_finish(&req, ret);
case VFS_BACK_USER:
process_current->state = PS_WAITS4FS;
- if (backend->handler == NULL) {
+ if (req.backend->handler == NULL) {
// backend isn't ready yet, join the queue
- assert(backend->queue == NULL); // TODO implement a proper queue
+ assert(req.backend->queue == NULL); // TODO implement a proper queue
- backend->queue = process_current;
+ req.backend->queue = process_current;
process_current->pending_req = req;
process_switch_any();
} else {
- vfs_request_pass2handler(req);
+ vfs_request_pass2handler(&req);
}
default:
panic();
}
}
-_Noreturn void vfs_request_pass2handler(struct vfs_op_request *req) {
+_Noreturn void vfs_request_pass2handler(struct vfs_request *req) {
assert(req->backend->handler);
assert(req->backend->handler->state == PS_WAITS4REQUEST);
@@ -45,10 +38,10 @@ _Noreturn void vfs_request_pass2handler(struct vfs_op_request *req) {
}
// returns from a VFS operation to the calling process
-_Noreturn void vfs_backend_finish(struct vfs_op_request *req, int ret) {
+_Noreturn void vfs_request_finish(struct vfs_request *req, int ret) {
struct process *caller = req->caller;
- if (req->op.type == VFSOP_OPEN && ret >= 0) {
+ if (req->type == VFSOP_OPEN && ret >= 0) {
// open() calls need special handling
// we need to wrap the id returned by the VFS in a handle passed to
// the client
@@ -64,8 +57,8 @@ _Noreturn void vfs_backend_finish(struct vfs_op_request *req, int ret) {
ret = handle;
}
- if (req->op.type == VFSOP_OPEN)
- kfree(req->op.open.path);
+ if (req->type == VFSOP_OPEN)
+ kfree(req->open.path);
req->caller->state = PS_RUNNING;
regs_savereturn(&req->caller->regs, ret);
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
new file mode 100644
index 0000000..3021c6f
--- /dev/null
+++ b/src/kernel/vfs/request.h
@@ -0,0 +1,43 @@
+#pragma once
+
+enum vfs_backend_type {
+ VFS_BACK_ROOT,
+ VFS_BACK_USER,
+};
+
+// describes something which can act as an access function
+struct vfs_backend {
+ enum vfs_backend_type type;
+
+ // only used with VFS_BACK_USER
+ struct process *handler;
+ struct process *queue;
+};
+
+enum vfs_operation {
+ VFSOP_OPEN,
+ VFSOP_WRITE,
+};
+
+// describes an in-process vfs call
+struct vfs_request {
+ enum vfs_operation type;
+ union {
+ struct {
+ char *path;
+ int path_len;
+ } open;
+ struct {
+ char __user *buf;
+ int buf_len;
+ int id; // filled in by the kernel
+ } rw;
+ };
+
+ struct process *caller;
+ struct vfs_backend *backend;
+};
+
+_Noreturn void vfs_request_create(struct vfs_request);
+_Noreturn void vfs_request_pass2handler(struct vfs_request *);
+_Noreturn void vfs_request_finish(struct vfs_request *, int ret);
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c
index 5b23555..29caf14 100644
--- a/src/kernel/vfs/root.c
+++ b/src/kernel/vfs/root.c
@@ -5,21 +5,21 @@
#include <kernel/util.h>
#include <kernel/vfs/root.h>
-int vfs_root_handler(struct vfs_op_request *req) {
- switch (req->op.type) {
+int vfs_root_handler(struct vfs_request *req) {
+ switch (req->type) {
case VFSOP_OPEN:
- if (req->op.open.path_len == 4
- && !memcmp(req->op.open.path, "/tty", 4)) {
+ if (req->open.path_len == 4
+ && !memcmp(req->open.path, "/tty", 4)) {
return 0;
}
return -1;
case VFSOP_WRITE:
- switch (req->op.rw.id) {
+ switch (req->rw.id) {
// every id corresponds to a special file type
// this is a shit way to do this but :shrug:
case 0: { // tty
struct virt_iter iter;
- virt_iter_new(&iter, req->op.rw.buf, req->op.rw.buf_len,
+ virt_iter_new(&iter, req->rw.buf, req->rw.buf_len,
req->caller->pages, true, false);
while (virt_iter_next(&iter))
tty_write(iter.frag, iter.frag_len);
diff --git a/src/kernel/vfs/root.h b/src/kernel/vfs/root.h
index 617ba1c..501185e 100644
--- a/src/kernel/vfs/root.h
+++ b/src/kernel/vfs/root.h
@@ -1,5 +1,5 @@
#pragma once
-#include <kernel/vfs/mount.h>
+#include <kernel/vfs/request.h>
// the VFS provided to init
-int vfs_root_handler(struct vfs_op_request *);
+int vfs_root_handler(struct vfs_request *);