diff options
author | dzwdz | 2021-09-20 18:54:40 +0200 |
---|---|---|
committer | dzwdz | 2021-09-20 18:54:40 +0200 |
commit | 29bcaabe450e1bbd906111c5c83407d80abd584d (patch) | |
tree | e898b1f3994c67c157c834ee8bcd2e7bb7176b63 | |
parent | 7ba8059015fd08a952d48ab71bf91202ea4f06eb (diff) |
use a single struct for all fs_wait return values
-rw-r--r-- | src/init/syscalls.c | 5 | ||||
-rw-r--r-- | src/init/tar.c | 19 | ||||
-rw-r--r-- | src/kernel/proc.h | 5 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 11 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 14 | ||||
-rw-r--r-- | src/shared/syscalls.h | 7 |
6 files changed, 34 insertions, 27 deletions
diff --git a/src/init/syscalls.c b/src/init/syscalls.c index 549ff61..7d0fef9 100644 --- a/src/init/syscalls.c +++ b/src/init/syscalls.c @@ -38,8 +38,9 @@ handle_t _syscall_fs_create(handle_t __user *back) { return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0, 0); } -int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len, int __user *id) { - return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, (int)len, (int)id); +int _syscall_fs_wait(handle_t back, char __user *buf, int max_len, + struct fs_wait_response __user *res) { + return _syscall(_SYSCALL_FS_WAIT, back, (int)buf, max_len, (int)res); } int _syscall_fs_respond(char __user *buf, int ret) { diff --git a/src/init/tar.c b/src/init/tar.c index 43efe3b..74e4c83 100644 --- a/src/init/tar.c +++ b/src/init/tar.c @@ -3,6 +3,8 @@ #include <shared/syscalls.h> #include <stdint.h> +#define BUF_SIZE 64 + extern int tty_fd; // TODO struct tar @@ -12,20 +14,19 @@ static void *tar_find(const char *path, size_t path_len, void *base, size_t base static int oct_parse(char *str, size_t len); void tar_driver(handle_t back, void *base) { - static char buf[64]; - int len; - void *id; // IDs usually are integers, but here i'm using them as pointers - // to the metadata sectors + static char buf[BUF_SIZE]; + struct fs_wait_response res; for (;;) { - len = 64; - switch (_syscall_fs_wait(back, buf, &len, (int*)&id)) { + switch (_syscall_fs_wait(back, buf, BUF_SIZE, &res)) { case VFSOP_OPEN: - _syscall_fs_respond(NULL, tar_open(buf, len, base, ~0)); + _syscall_fs_respond(NULL, tar_open(buf, res.len, base, ~0)); break; - case VFSOP_READ: - _syscall_fs_respond(id + 512, tar_size(id)); + case VFSOP_READ: { + void *meta = (void*)res.id; + _syscall_fs_respond(meta + 512, tar_size(meta)); break; + } default: _syscall_fs_respond(NULL, -1); // unsupported diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 970c694..0e02d27 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -2,6 +2,7 @@ #include <kernel/arch/generic.h> #include <kernel/handle.h> #include <kernel/vfs/mount.h> +#include <shared/syscalls.h> enum process_state { PS_RUNNING, @@ -32,8 +33,8 @@ struct process { struct vfs_request pending_req; // PS_WAITS4FS struct { char __user *buf; - int __user *len; - int __user *id; + int max_len; + struct fs_wait_response __user *res; } awaited_req; // PS_WAITS4REQUEST }; struct vfs_request *handled_req; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 497aa7f..bc185bd 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -207,7 +207,8 @@ fail: return -1; } -int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len, int __user *id) { +int _syscall_fs_wait(handle_t back, char __user *buf, int max_len, + struct fs_wait_response __user *res) { struct handle *back_handle; if (back < 0 || back >= HANDLE_MAX) return -1; @@ -219,9 +220,9 @@ int _syscall_fs_wait(handle_t back, char __user *buf, int __user *len, int __use back_handle->fs.backend->handler = process_current; /* checking the validity of those pointers here would make * vfs_request_pass2handler simpler. TODO? */ - process_current->awaited_req.buf = buf; - process_current->awaited_req.len = len; - process_current->awaited_req.id = id; + process_current->awaited_req.buf = buf; + process_current->awaited_req.max_len = max_len; + process_current->awaited_req.res = res; if (back_handle->fs.backend->queue) { // handle queued requests @@ -293,7 +294,7 @@ int _syscall(int num, int a, int b, int c, int d) { case _SYSCALL_FS_CREATE: return _syscall_fs_create((userptr_t)a); case _SYSCALL_FS_WAIT: - return _syscall_fs_wait(a, (userptr_t)b, (userptr_t)c, (userptr_t)d); + return _syscall_fs_wait(a, (userptr_t)b, c, (userptr_t)d); case _SYSCALL_FS_RESPOND: return _syscall_fs_respond((userptr_t)a, b); case _SYSCALL_MEMFLAG: diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 2fd4689..dfeeb50 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -39,6 +39,7 @@ int vfs_request_create(struct vfs_request req_) { _Noreturn void vfs_request_pass2handler(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); @@ -46,9 +47,7 @@ _Noreturn void vfs_request_pass2handler(struct vfs_request *req) { handler->state = PS_RUNNING; handler->handled_req = req; - if (!virt_cpy_from(handler->pages, - &len, handler->awaited_req.len, sizeof len)) - goto fail; // can't read buffer length + len = handler->awaited_req.max_len; if (len > req->input.len) { // input bigger than buffer // TODO what should be done during e.g. open() calls? truncating doesn't seem right @@ -65,13 +64,12 @@ _Noreturn void vfs_request_pass2handler(struct vfs_request *req) { goto fail; // can't copy buffer } - if (!virt_cpy_to(handler->pages, - handler->awaited_req.len, &len, sizeof len)) - goto fail; // can't copy new length + res.len = len; + res.id = req->id; if (!virt_cpy_to(handler->pages, - handler->awaited_req.id, &req->id, sizeof req->id)) - goto fail; // can't copy id + handler->awaited_req.res, &res, sizeof res)) + goto fail; // can't copy response struct regs_savereturn(&handler->regs, req->type); process_switch(handler); diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h index 0b856e6..f6ee44f 100644 --- a/src/shared/syscalls.h +++ b/src/shared/syscalls.h @@ -51,7 +51,12 @@ 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 __user *id); +struct fs_wait_response { + int len; // how much was put in *buf + int id; // file id (returned by the open handler, passed to other calls) +}; +int _syscall_fs_wait(handle_t back, char __user *buf, int max_len, + struct fs_wait_response __user *res); int _syscall_fs_respond(char __user *buf, int ret); int _syscall_memflag(void __user *addr, size_t len, int flags); |