diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/syscalls.c | 10 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 34 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 3 |
3 files changed, 22 insertions, 25 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index b424bf1..b21eb5b 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -209,18 +209,12 @@ int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __us assert(!backend->handler); // TODO allow multiple processes to wait on the same backend backend->handler = process_current; /* checking the validity of those pointers here would make - * vfs_request_accept simpler. TODO? */ + * vfs_backend_accept simpler. TODO? */ process_current->awaited_req.buf = buf; process_current->awaited_req.max_len = max_len; process_current->awaited_req.res = res; - if (backend->queue) { - // handle queued requests - struct process *queued = backend->queue; - backend->queue = queued->waits4fs.queue_next; - return vfs_request_accept(&queued->waits4fs.req); - } - return -1; + return vfs_backend_accept(backend); } int _syscall_fs_respond(char __user *buf, int ret) { diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index ad72264..03d7853 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -20,34 +20,36 @@ int vfs_request_create(struct vfs_request req_) { switch (req->backend->type) { case VFS_BACK_ROOT: return vfs_root_handler(req); - case VFS_BACK_USER: - if (req->backend->handler) { - assert(req->backend->handler->state == PS_WAITS4REQUEST); - vfs_request_accept(req); - } else { - // backend isn't ready yet, join the queue - struct process **iter = &req->backend->queue; - while (*iter != NULL) - iter = &(*iter)->waits4fs.queue_next; - *iter = process_current; - } + case VFS_BACK_USER: { + struct process **iter = &req->backend->queue; + while (*iter != NULL) // find free spot in queue + iter = &(*iter)->waits4fs.queue_next; + *iter = req->caller; + + vfs_backend_accept(req->backend); return -1; // isn't passed to the caller process anyways + } default: panic_invalid_state(); } } -int vfs_request_accept(struct vfs_request *req) { - struct process *handler = req->backend->handler; +int vfs_backend_accept(struct vfs_backend *backend) { + struct vfs_request *req; + struct process *handler = backend->handler; struct fs_wait_response res = {0}; int len; - assert(handler); + + if (!backend->handler) return -1; assert(handler->state == PS_WAITS4REQUEST); assert(!handler->handled_req); - len = min(req->input.len, handler->awaited_req.max_len); + if (!backend->queue) return -1; + // TODO wouldn't it be better to directly store vfs_requests in the queue? + req = &backend->queue->waits4fs.req; + backend->queue = backend->queue->waits4fs.queue_next; - // wouldn't it be kinda nice to have a fake kernel "process"? + len = min(req->input.len, handler->awaited_req.max_len); if (!virt_cpy(handler->pages, handler->awaited_req.buf, req->input.kern ? NULL : req->caller->pages, req->input.buf, len)) goto fail; // can't copy buffer diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index 1e3ef60..c6f714d 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -45,7 +45,8 @@ struct vfs_request { /** Assigns the vfs_request to the caller, and dispatches the call */ int vfs_request_create(struct vfs_request); -int vfs_request_accept(struct vfs_request *); +/** Try to accept an enqueued request */ +int vfs_backend_accept(struct vfs_backend *); int vfs_request_finish(struct vfs_request *, int ret); void vfs_request_cancel(struct vfs_request *, int ret); |