summaryrefslogtreecommitdiff
path: root/src/kernel/vfs
diff options
context:
space:
mode:
authordzwdz2024-07-14 19:19:35 +0200
committerdzwdz2024-07-14 19:19:35 +0200
commit6fe8073de975ad7722043f9173fec068178e2eac (patch)
tree9427bb0368e25609eea66fa52567b57522b0e0aa /src/kernel/vfs
parentb3a86647b644db30f5fd70bd651c44f681962a9b (diff)
kernel: rework postqueue
Keeping its old name for now to make things easier for myself. This might just be replaced by sys/queue.h soon.
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r--src/kernel/vfs/request.c59
-rw-r--r--src/kernel/vfs/request.h12
2 files changed, 71 insertions, 0 deletions
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index d4ea16c..8f44afb 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -242,3 +242,62 @@ vfsback_provdown(VfsBackend *b)
}
vfsback_checkfree(b);
}
+
+void
+postqueue_init(ReqQueue *q)
+{
+ q->head = NULL;
+}
+
+void
+postqueue_join(ReqQueue *q, VfsReq *req)
+{
+ if (req->postqueue_next)
+ panic_invalid_state();
+
+ VfsReq **it = &q->head;
+ while (*it != NULL) {
+ it = &(*it)->postqueue_next;
+ }
+ *it = req;
+}
+
+VfsReq *
+postqueue_pop(ReqQueue *q)
+{
+ VfsReq *req = q->head;
+ if (req) {
+ q->head = req->postqueue_next;
+ req->postqueue_next = NULL;
+ }
+ return req;
+}
+
+void
+postqueue_ringreadall(ReqQueue *q, ring_t *r)
+{
+ VfsReq **queue = &q->head; /* whatever */
+ VfsReq *req;
+ char tmp[64];
+ size_t mlen = 0;
+ if (ring_used(r) == 0) return;
+
+ /* read as much as the biggest request wants */
+ for (req = *queue; req; req = req->postqueue_next)
+ mlen = max(mlen, req->output.len);
+ mlen = min(mlen, sizeof tmp);
+ mlen = ring_get(r, tmp, mlen);
+
+ while (*queue) {
+ req = *queue;
+ *queue = req->postqueue_next;
+ req->postqueue_next = NULL;
+
+ size_t ret = min(mlen, req->output.len);
+ assert(req->type == VFSOP_READ);
+ if (req->caller) {
+ pcpy_to(req->caller, req->output.buf, tmp, ret);
+ }
+ vfsreq_finish_short(req, ret);
+ }
+}
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index 06c46e7..616c044 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -1,5 +1,6 @@
#pragma once
#include <kernel/types.h>
+#include <shared/ring.h>
#include <stdbool.h>
#include <stddef.h>
@@ -77,3 +78,14 @@ void vfsback_userdown(VfsBackend *);
/** Decrements the "provider" reference count. */
void vfsback_provdown(VfsBackend *);
+
+struct ReqQueue {
+ VfsReq *head;
+};
+void postqueue_init(ReqQueue *q);
+void postqueue_join(ReqQueue *q, VfsReq *req);
+VfsReq *postqueue_pop(ReqQueue *q);
+
+/** If there are any pending read requests, and the ring buffer isn't empty, fulfill them
+ * all with a single read. */
+void postqueue_ringreadall(ReqQueue *q, ring_t *r);