summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-09-20 18:54:40 +0200
committerdzwdz2021-09-20 18:54:40 +0200
commit29bcaabe450e1bbd906111c5c83407d80abd584d (patch)
treee898b1f3994c67c157c834ee8bcd2e7bb7176b63
parent7ba8059015fd08a952d48ab71bf91202ea4f06eb (diff)
use a single struct for all fs_wait return values
-rw-r--r--src/init/syscalls.c5
-rw-r--r--src/init/tar.c19
-rw-r--r--src/kernel/proc.h5
-rw-r--r--src/kernel/syscalls.c11
-rw-r--r--src/kernel/vfs/request.c14
-rw-r--r--src/shared/syscalls.h7
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);