diff options
author | dzwdz | 2021-09-12 12:47:51 +0200 |
---|---|---|
committer | dzwdz | 2021-09-12 12:47:51 +0200 |
commit | e65d58357aaff7c1d05c06753538383478c1b0e9 (patch) | |
tree | 524acff4943892d62cfcd33a26fc83cace6aef83 /src/kernel/vfs/request.c | |
parent | 8fe035d7d75d09f314f9e8aefe1dcaf1e10d1954 (diff) |
vfs request refactor pt1
Diffstat (limited to 'src/kernel/vfs/request.c')
-rw-r--r-- | src/kernel/vfs/request.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c new file mode 100644 index 0000000..1212aa4 --- /dev/null +++ b/src/kernel/vfs/request.c @@ -0,0 +1,67 @@ +#include <kernel/mem/alloc.h> +#include <kernel/panic.h> +#include <kernel/proc.h> +#include <kernel/vfs/request.h> +#include <kernel/vfs/root.h> + +// dispatches a VFS operation to the correct process +_Noreturn void vfs_request_create(struct vfs_request req) { + int ret; + switch (req.backend->type) { + case VFS_BACK_ROOT: + ret = vfs_root_handler(&req); + vfs_request_finish(&req, ret); + case VFS_BACK_USER: + process_current->state = PS_WAITS4FS; + 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; + process_switch_any(); + } else { + vfs_request_pass2handler(&req); + } + default: + panic(); + } +} + +_Noreturn void vfs_request_pass2handler(struct vfs_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_request_finish(struct vfs_request *req, int ret) { + struct process *caller = req->caller; + + if (req->type == VFSOP_OPEN && ret >= 0) { + // open() calls need special handling + // we need to wrap the id returned by the VFS in a handle passed to + // the client + handle_t handle = process_find_handle(req->caller); + if (handle < 0) panic(); + req->caller->handles[handle] = (struct handle){ + .type = HANDLE_FILE, + .file = { + .backend = req->backend, + .id = ret, + }, + }; + ret = handle; + } + + if (req->type == VFSOP_OPEN) + kfree(req->open.path); + + req->caller->state = PS_RUNNING; + regs_savereturn(&req->caller->regs, ret); + kfree(req); + process_switch(caller); +} |