summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-04-16 20:04:52 +0200
committerdzwdz2022-04-16 20:04:52 +0200
commit749a079f9538c168c7a9adf03d919f00f09546fb (patch)
treeed85b3267cd921ecb02db76e61f3cb2834cd9e8d
parente55ace0f517ede6f3635341c8adadc7b90aa75c5 (diff)
kernel/vfs: refactor `vfs_request_accept` into `vfs_backend_accept`
handling the backend queue makes more sense here than in the syscall implementation. it's also just overall cleaner
-rw-r--r--src/kernel/syscalls.c10
-rw-r--r--src/kernel/vfs/request.c34
-rw-r--r--src/kernel/vfs/request.h3
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);