summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-04-09 18:55:22 +0200
committerdzwdz2022-04-09 18:55:22 +0200
commite17137d8d74e65e3cce7c04263d73a111bae25c0 (patch)
tree3b0113bd93d3b5d562c1bf84a86d4d7efcd4fe7a /src
parent6152d11ae205d4b4a9f03574cfcb0c24cb54b4b5 (diff)
kernel: `vfs_request_accept` now doesn't switch processes
Diffstat (limited to 'src')
-rw-r--r--src/kernel/proc.c1
-rw-r--r--src/kernel/syscalls.c4
-rw-r--r--src/kernel/vfs/request.c12
-rw-r--r--src/kernel/vfs/request.h4
4 files changed, 12 insertions, 9 deletions
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);