From e17137d8d74e65e3cce7c04263d73a111bae25c0 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 9 Apr 2022 18:55:22 +0200 Subject: kernel: `vfs_request_accept` now doesn't switch processes --- src/kernel/proc.c | 1 + src/kernel/syscalls.c | 4 ++-- src/kernel/vfs/request.c | 12 +++++++----- src/kernel/vfs/request.h | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/proc.c b/src/kernel/proc.c index e67af19..d20b0d3 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -58,6 +58,7 @@ struct process *process_fork(struct process *parent) { } void process_switch(struct process *proc) { + assert(proc->state == PS_RUNNING); process_current = proc; pagedir_switch(proc->pages); sysexit(proc->regs); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index daf7cac..855fad8 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -207,7 +207,7 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us process_current->state = PS_WAITS4REQUEST; backend->handler = process_current; /* checking the validity of those pointers here would make - * vfs_request_pass2handler simpler. TODO? */ + * vfs_request_accept simpler. TODO? */ process_current->awaited_req.buf = buf; process_current->awaited_req.max_len = max_len; process_current->awaited_req.res = res; @@ -216,7 +216,7 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us // handle queued requests struct process *queued = backend->queue; backend->queue = queued->waits4fs.queue_next; - vfs_request_pass2handler(&queued->waits4fs.req); + return vfs_request_accept(&queued->waits4fs.req); } else { process_switch_any(); } diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 761b619..ecd862a 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -28,7 +28,8 @@ int vfs_request_create(struct vfs_request req_) { if (req->backend->handler && req->backend->handler->state == PS_WAITS4REQUEST) { - vfs_request_pass2handler(req); + vfs_request_accept(req); + process_switch(req->backend->handler); } else { // backend isn't ready yet, join the queue struct process **iter = &req->backend->queue; @@ -42,18 +43,17 @@ int vfs_request_create(struct vfs_request req_) { } } -_Noreturn void vfs_request_pass2handler(struct vfs_request *req) { +int vfs_request_accept(struct vfs_request *req) { struct process *handler = req->backend->handler; struct fs_wait_response res = {0}; int len; assert(handler); assert(handler->state == PS_WAITS4REQUEST); // TODO currently callers have to ensure that the handler is in the correct state. should they? assert(!handler->handled_req); - handler->state = PS_RUNNING; - handler->handled_req = req; len = min(req->input.len, handler->awaited_req.max_len); + // TODO having to separately handle copying from kernel and userland stinks if (req->input.kern) { if (!virt_cpy_to(handler->pages, handler->awaited_req.buf, req->input.buf_kern, len)) @@ -74,8 +74,10 @@ _Noreturn void vfs_request_pass2handler(struct vfs_request *req) { handler->awaited_req.res, &res, sizeof res)) goto fail; // can't copy response struct + handler->state = PS_RUNNING; + handler->handled_req = req; regs_savereturn(&handler->regs, 0); - process_switch(handler); + return; fail: panic_unimplemented(); // TODO } diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 0e96db6..2bcaae6 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -41,7 +41,7 @@ struct vfs_request { }; /** Assigns the vfs_request to the caller, and calls the backend. Might not - * return - can switch processes! */ + * return - can switch processes! TODO no it can't*/ int vfs_request_create(struct vfs_request); -_Noreturn void vfs_request_pass2handler(struct vfs_request *); +int vfs_request_accept(struct vfs_request *); int vfs_request_finish(struct vfs_request *, int ret); -- cgit v1.2.3