diff options
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r-- | src/kernel/vfs/backend.h | 29 | ||||
-rw-r--r-- | src/kernel/vfs/mount.h | 2 | ||||
-rw-r--r-- | src/kernel/vfs/request.c (renamed from src/kernel/vfs/backend.c) | 35 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 43 | ||||
-rw-r--r-- | src/kernel/vfs/root.c | 12 | ||||
-rw-r--r-- | src/kernel/vfs/root.h | 4 |
6 files changed, 66 insertions, 59 deletions
diff --git a/src/kernel/vfs/backend.h b/src/kernel/vfs/backend.h deleted file mode 100644 index bc0dc45..0000000 --- a/src/kernel/vfs/backend.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include <shared/vfs.h> - -enum vfs_backend_type { - VFS_BACK_ROOT, - VFS_BACK_USER, -}; - -// describes something which can act as an access function -struct vfs_backend { - enum vfs_backend_type type; - - // only used with VFS_BACK_USER - struct process *handler; - struct process *queue; -}; - -// describes an in-progress vfs call -struct vfs_op_request { - struct vfs_op op; - struct process *caller; - struct vfs_backend *backend; -}; - - -// 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/kernel/vfs/mount.h b/src/kernel/vfs/mount.h index ac55184..5fb6d16 100644 --- a/src/kernel/vfs/mount.h +++ b/src/kernel/vfs/mount.h @@ -1,5 +1,5 @@ #pragma once -#include <kernel/vfs/backend.h> +#include <kernel/vfs/request.h> #include <stddef.h> struct vfs_mount { diff --git a/src/kernel/vfs/backend.c b/src/kernel/vfs/request.c index b9bc9af..1212aa4 100644 --- a/src/kernel/vfs/backend.c +++ b/src/kernel/vfs/request.c @@ -1,41 +1,34 @@ #include <kernel/mem/alloc.h> #include <kernel/panic.h> #include <kernel/proc.h> -#include <kernel/vfs/backend.h> +#include <kernel/vfs/request.h> #include <kernel/vfs/root.h> // dispatches a VFS operation to the correct process -_Noreturn void vfs_backend_dispatch(struct vfs_backend *backend, struct vfs_op op) { - struct vfs_op_request *req = kmalloc(sizeof *req); // freed in vfs_backend_finish +_Noreturn void vfs_request_create(struct vfs_request req) { int ret; - *req = (struct vfs_op_request) { - .op = op, - .caller = process_current, - .backend = backend, - }; - - switch (backend->type) { + switch (req.backend->type) { case VFS_BACK_ROOT: - ret = vfs_root_handler(req); - vfs_backend_finish(req, ret); + ret = vfs_root_handler(&req); + vfs_request_finish(&req, ret); case VFS_BACK_USER: process_current->state = PS_WAITS4FS; - if (backend->handler == NULL) { + if (req.backend->handler == NULL) { // backend isn't ready yet, join the queue - assert(backend->queue == NULL); // TODO implement a proper queue + assert(req.backend->queue == NULL); // TODO implement a proper queue - backend->queue = process_current; + req.backend->queue = process_current; process_current->pending_req = req; process_switch_any(); } else { - vfs_request_pass2handler(req); + vfs_request_pass2handler(&req); } default: panic(); } } -_Noreturn void vfs_request_pass2handler(struct vfs_op_request *req) { +_Noreturn void vfs_request_pass2handler(struct vfs_request *req) { assert(req->backend->handler); assert(req->backend->handler->state == PS_WAITS4REQUEST); @@ -45,10 +38,10 @@ _Noreturn void vfs_request_pass2handler(struct vfs_op_request *req) { } // returns from a VFS operation to the calling process -_Noreturn void vfs_backend_finish(struct vfs_op_request *req, int ret) { +_Noreturn void vfs_request_finish(struct vfs_request *req, int ret) { struct process *caller = req->caller; - if (req->op.type == VFSOP_OPEN && ret >= 0) { + 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 @@ -64,8 +57,8 @@ _Noreturn void vfs_backend_finish(struct vfs_op_request *req, int ret) { ret = handle; } - if (req->op.type == VFSOP_OPEN) - kfree(req->op.open.path); + if (req->type == VFSOP_OPEN) + kfree(req->open.path); req->caller->state = PS_RUNNING; regs_savereturn(&req->caller->regs, ret); diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h new file mode 100644 index 0000000..3021c6f --- /dev/null +++ b/src/kernel/vfs/request.h @@ -0,0 +1,43 @@ +#pragma once + +enum vfs_backend_type { + VFS_BACK_ROOT, + VFS_BACK_USER, +}; + +// describes something which can act as an access function +struct vfs_backend { + enum vfs_backend_type type; + + // only used with VFS_BACK_USER + struct process *handler; + struct process *queue; +}; + +enum vfs_operation { + VFSOP_OPEN, + VFSOP_WRITE, +}; + +// describes an in-process vfs call +struct vfs_request { + enum vfs_operation type; + union { + struct { + char *path; + int path_len; + } open; + struct { + char __user *buf; + int buf_len; + int id; // filled in by the kernel + } rw; + }; + + struct process *caller; + struct vfs_backend *backend; +}; + +_Noreturn void vfs_request_create(struct vfs_request); +_Noreturn void vfs_request_pass2handler(struct vfs_request *); +_Noreturn void vfs_request_finish(struct vfs_request *, int ret); diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c index 5b23555..29caf14 100644 --- a/src/kernel/vfs/root.c +++ b/src/kernel/vfs/root.c @@ -5,21 +5,21 @@ #include <kernel/util.h> #include <kernel/vfs/root.h> -int vfs_root_handler(struct vfs_op_request *req) { - switch (req->op.type) { +int vfs_root_handler(struct vfs_request *req) { + switch (req->type) { case VFSOP_OPEN: - if (req->op.open.path_len == 4 - && !memcmp(req->op.open.path, "/tty", 4)) { + if (req->open.path_len == 4 + && !memcmp(req->open.path, "/tty", 4)) { return 0; } return -1; case VFSOP_WRITE: - switch (req->op.rw.id) { + switch (req->rw.id) { // every id corresponds to a special file type // this is a shit way to do this but :shrug: case 0: { // tty struct virt_iter iter; - virt_iter_new(&iter, req->op.rw.buf, req->op.rw.buf_len, + virt_iter_new(&iter, req->rw.buf, req->rw.buf_len, req->caller->pages, true, false); while (virt_iter_next(&iter)) tty_write(iter.frag, iter.frag_len); diff --git a/src/kernel/vfs/root.h b/src/kernel/vfs/root.h index 617ba1c..501185e 100644 --- a/src/kernel/vfs/root.h +++ b/src/kernel/vfs/root.h @@ -1,5 +1,5 @@ #pragma once -#include <kernel/vfs/mount.h> +#include <kernel/vfs/request.h> // the VFS provided to init -int vfs_root_handler(struct vfs_op_request *); +int vfs_root_handler(struct vfs_request *); |