diff options
author | dzwdz | 2021-09-09 21:14:26 +0200 |
---|---|---|
committer | dzwdz | 2021-09-09 21:14:26 +0200 |
commit | 80b2c1c2ab36b4ddb030e135bcacf1f30db362d2 (patch) | |
tree | 50eaf0a30fb296a21f24254575b4d6bbb52c95f1 | |
parent | 7192887ee27487d209b98b7192cb6798b036b824 (diff) |
basic _syscall_fs_wait() impl, doesn't pass the req yet
-rw-r--r-- | src/init/main.c | 14 | ||||
-rw-r--r-- | src/init/syscalls.c | 4 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 23 | ||||
-rw-r--r-- | src/kernel/vfs/backend.c | 12 | ||||
-rw-r--r-- | src/kernel/vfs/backend.h | 1 | ||||
-rw-r--r-- | src/shared/syscalls.h | 3 |
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); |