summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-09-12 17:53:48 +0200
committerdzwdz2021-09-12 17:53:48 +0200
commit3ea9657aaaf02709c8f216285b095af29e76491c (patch)
tree36dfe7038f2ff829791ccdaf18b0ee71744207a6
parent5090829984cd4b3238d3f42eaad2431f1fd5282b (diff)
implement part of `fs_respond`
-rw-r--r--src/init/main.c2
-rw-r--r--src/init/syscalls.c4
-rw-r--r--src/kernel/proc.c1
-rw-r--r--src/kernel/proc.h1
-rw-r--r--src/kernel/syscalls.c13
-rw-r--r--src/kernel/vfs/request.c28
-rw-r--r--src/shared/syscalls.h3
7 files changed, 40 insertions, 12 deletions
diff --git a/src/init/main.c b/src/init/main.c
index fa4fda7..de8a599 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -39,10 +39,12 @@ void fs_test(void) {
_syscall_fs_wait(back, buf, &len);
log("fs_wait returned. ");
_syscall_write(tty_fd, buf, len);
+ _syscall_fs_respond(0, NULL, 0);
} else {
// parent: accesses the fs
_syscall_mount(front, argify("/mnt"));
log("requesting file. ");
file = _syscall_open(argify("/mnt/test"));
+ log("open returned. ");
}
}
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 8d5ecf2..50d7067 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -45,6 +45,10 @@ int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len) {
return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len);
}
+int _syscall_fs_respond(int ret, char __user *buf, int len) {
+ return _syscall(_SYSCALL_FS_RESPOND, ret, (int)buf, len);
+}
+
int _syscall_memflag(void __user *addr, size_t len, int flags) {
return _syscall(_SYSCALL_MEMFLAG, (int)addr, len, flags);
}
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 21a1d54..e82971c 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -19,6 +19,7 @@ struct process *process_seed(void) {
proc->parent = NULL;
proc->mount = vfs_mount_seed();
proc->id = next_pid++;
+ proc->handled_req = NULL;
process_first = proc;
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 595d62c..73a6651 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -36,6 +36,7 @@ struct process {
int __user *len;
} awaited_req; // PS_WAITS4REQUEST
};
+ struct vfs_request *handled_req;
struct vfs_mount *mount;
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 1180197..b247619 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -222,6 +222,17 @@ int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len) {
}
}
+int _syscall_fs_respond(int ret, char __user *buf, int len) {
+ struct vfs_request *req = process_current->handled_req;
+ if (!req) return -1;
+
+ // TODO copy buffer
+
+ process_current->handled_req = NULL;
+ vfs_request_finish(req, ret);
+ return 0;
+}
+
int _syscall_memflag(void __user *addr, size_t len, int flags) {
userptr_t goal = addr + len;
struct pagedir *pages = process_current->pages;
@@ -263,6 +274,8 @@ int syscall_handler(int num, int a, int b, int c) {
return _syscall_fs_create((userptr_t)a);
case _SYSCALL_FS_WAIT:
return _syscall_fs_wait(a, (userptr_t)b, (userptr_t)c);
+ case _SYSCALL_FS_RESPOND:
+ return _syscall_fs_respond(a, (userptr_t)b, c);
case _SYSCALL_MEMFLAG:
return _syscall_memflag((userptr_t)a, b, c);
default:
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 2ff5d72..a8f2fc0 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -6,23 +6,27 @@
#include <kernel/vfs/root.h>
// dispatches a VFS operation to the correct process
-_Noreturn void vfs_request_create(struct vfs_request req) {
+_Noreturn void vfs_request_create(struct vfs_request req_) {
+ struct vfs_request *req;
int ret;
- switch (req.backend->type) {
+ process_current->state = PS_WAITS4FS;
+
+ // the request is owned by the caller
+ process_current->pending_req = req_;
+ req = &process_current->pending_req;
+
+ switch (req->backend->type) {
case VFS_BACK_ROOT:
- ret = vfs_root_handler(&req);
- vfs_request_finish(&req, ret);
+ ret = vfs_root_handler(req);
+ vfs_request_finish(req, ret);
case VFS_BACK_USER:
- process_current->state = PS_WAITS4FS;
- if (req.backend->handler == NULL) {
+ if (req->backend->handler == NULL) {
// backend isn't ready yet, join the queue
- assert(req.backend->queue == NULL); // TODO implement a proper queue
-
- req.backend->queue = process_current;
- process_current->pending_req = req;
+ assert(req->backend->queue == NULL); // TODO implement a proper queue
+ req->backend->queue = process_current;
process_switch_any();
} else {
- vfs_request_pass2handler(&req);
+ vfs_request_pass2handler(req);
}
default:
panic();
@@ -34,7 +38,9 @@ _Noreturn void vfs_request_pass2handler(struct vfs_request *req) {
int len;
assert(handler);
assert(handler->state == PS_WAITS4REQUEST);
+ assert(!handler->handled_req);
handler->state = PS_RUNNING;
+ handler->handled_req = req;
if (!virt_cpy_from(handler->pages,
&len, handler->awaited_req.len, sizeof len))
diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h
index d96c8a7..2b5a80e 100644
--- a/src/shared/syscalls.h
+++ b/src/shared/syscalls.h
@@ -22,6 +22,7 @@ enum {
_SYSCALL_FS_CREATE,
_SYSCALL_FS_WAIT,
+ _SYSCALL_FS_RESPOND,
_SYSCALL_MEMFLAG,
};
@@ -53,7 +54,7 @@ int _syscall_close(handle_t);
* @param back a pointer to a handle_t which will store the back pointer
*/
handle_t _syscall_fs_create(handle_t __user *back);
-
int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len);
+int _syscall_fs_respond(int ret, char __user *buf, int len);
int _syscall_memflag(void __user *addr, size_t len, int flags);