summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-09-09 21:14:26 +0200
committerdzwdz2021-09-09 21:14:26 +0200
commit80b2c1c2ab36b4ddb030e135bcacf1f30db362d2 (patch)
tree50eaf0a30fb296a21f24254575b4d6bbb52c95f1
parent7192887ee27487d209b98b7192cb6798b036b824 (diff)
basic _syscall_fs_wait() impl, doesn't pass the req yet
-rw-r--r--src/init/main.c14
-rw-r--r--src/init/syscalls.c4
-rw-r--r--src/kernel/syscalls.c23
-rw-r--r--src/kernel/vfs/backend.c12
-rw-r--r--src/kernel/vfs/backend.h1
-rw-r--r--src/shared/syscalls.h3
6 files changed, 53 insertions, 4 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 41f51d3..8d677af 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -30,8 +30,18 @@ int main(void) {
void fs_test(void) {
handle_t front, back, file;
front = _syscall_fs_create((void*)&back); // TODO change user_ptr to void*
- _syscall_mount(front, argify("/mnt"));
- file = _syscall_open(argify("/mnt/test"));
+
+ if (_syscall_fork()) {
+ // child: is the fs server
+ log("fs_wait started. ");
+ _syscall_fs_wait(back, NULL);
+ log("fs_wait returned. ");
+ } else {
+ // parent: accesses the fs
+ _syscall_mount(front, argify("/mnt"));
+ log("requesting file. ");
+ file = _syscall_open(argify("/mnt/test"));
+ }
}
void misc_tests(void) {
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 4c645c2..c091247 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -40,3 +40,7 @@ int _syscall_close(handle_t handle) {
handle_t _syscall_fs_create(user_ptr back) {
return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0);
}
+
+int _syscall_fs_wait(handle_t back, user_ptr info) {
+ return _syscall(_SYSCALL_FS_WAIT, back, info, 0);
+}
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 0b557fb..fcd3c1e 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -200,6 +200,27 @@ fail:
return -1;
}
+int _syscall_fs_wait(handle_t back, user_ptr info) {
+ struct handle *back_handle;
+
+ if (back < 0 || back >= HANDLE_MAX) return -1;
+ back_handle = &process_current->handles[back];
+ if (back_handle->type != HANDLE_FS_BACK)
+ return -1;
+
+ process_current->state = PS_WAITS4REQUEST;
+ back_handle->fs.backend->handler = process_current;
+
+ if (back_handle->fs.backend->queue) {
+ // 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);
+ } else {
+ process_switch_any();
+ }
+}
+
int syscall_handler(int num, int a, int b, int c) {
switch (num) {
case _SYSCALL_EXIT:
@@ -220,6 +241,8 @@ int syscall_handler(int num, int a, int b, int c) {
return _syscall_close(a);
case _SYSCALL_FS_CREATE:
return _syscall_fs_create(a);
+ case _SYSCALL_FS_WAIT:
+ return _syscall_fs_wait(a, b);
default:
tty_const("unknown syscall ");
panic();
diff --git a/src/kernel/vfs/backend.c b/src/kernel/vfs/backend.c
index 7e53e51..4b22104 100644
--- a/src/kernel/vfs/backend.c
+++ b/src/kernel/vfs/backend.c
@@ -27,14 +27,22 @@ _Noreturn void vfs_backend_dispatch(struct vfs_backend *backend, struct vfs_op o
process_current->pending_req = req;
process_switch_any();
} else {
- assert(backend->handler->state == PS_WAITS4REQUEST);
- panic(); // TODO
+ vfs_request_pass2handler(req);
}
default:
panic();
}
}
+_Noreturn void vfs_request_pass2handler(struct vfs_op_request *req) {
+ assert(req->backend->handler);
+ assert(req->backend->handler->state == PS_WAITS4REQUEST);
+
+ req->backend->handler->state = PS_RUNNING;
+ // TODO pass the request to the process
+ process_switch(req->backend->handler);
+}
+
// returns from a VFS operation to the calling process
_Noreturn void vfs_backend_finish(struct vfs_op_request *req, int ret) {
struct process *caller = req->caller;
diff --git a/src/kernel/vfs/backend.h b/src/kernel/vfs/backend.h
index bf16ee7..bc0dc45 100644
--- a/src/kernel/vfs/backend.h
+++ b/src/kernel/vfs/backend.h
@@ -25,4 +25,5 @@ struct vfs_op_request {
// 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/shared/syscalls.h b/src/shared/syscalls.h
index 29836b0..7b130c1 100644
--- a/src/shared/syscalls.h
+++ b/src/shared/syscalls.h
@@ -21,6 +21,7 @@ enum {
_SYSCALL_CLOSE,
_SYSCALL_FS_CREATE,
+ _SYSCALL_FS_WAIT,
};
/** Kills the current process.
@@ -50,3 +51,5 @@ int _syscall_close(handle_t);
* @param back a pointer to a handle_t which will store the back pointer
*/
handle_t _syscall_fs_create(user_ptr back);
+
+int _syscall_fs_wait(handle_t back, user_ptr info);