summaryrefslogtreecommitdiff
path: root/src/kernel/vfs
diff options
context:
space:
mode:
authordzwdz2024-07-14 19:40:31 +0200
committerdzwdz2024-07-14 19:40:31 +0200
commit881be872675e4cff153c27c641980451c4a3f479 (patch)
treea374913fc7f1fcbd1d380719d695bf5f67b83e56 /src/kernel/vfs
parent6fe8073de975ad7722043f9173fec068178e2eac (diff)
kernel: make the adhoc VfsQueue queues use ReqQueue instead
I'm still not sure if I should use sys/queue.h for this. But yeah, this is more consistent, and it will also let me switch over to O(1) insertions later on.
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r--src/kernel/vfs/mount.c1
-rw-r--r--src/kernel/vfs/procfs.c1
-rw-r--r--src/kernel/vfs/request.c58
-rw-r--r--src/kernel/vfs/request.h34
4 files changed, 39 insertions, 55 deletions
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index 15d1382..fa5d65b 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -15,7 +15,6 @@ void vfs_root_register(const char *path, void (*accept)(VfsReq *)) {
*backend = (VfsBackend) {
.is_user = false,
.usehcnt = 1,
- .provhcnt = 1,
.kern.accept = accept,
};
*mount = (VfsMount){
diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c
index 79dfdc0..86042cd 100644
--- a/src/kernel/vfs/procfs.c
+++ b/src/kernel/vfs/procfs.c
@@ -185,7 +185,6 @@ procfs_backend(Proc *proc)
VfsBackend *be = kzalloc(sizeof(VfsBackend), "kern fs");
*be = (VfsBackend) {
.is_user = false,
- .provhcnt = 1,
.usehcnt = 1,
.kern.accept = procfs_accept,
.kern.data = proc,
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index 8f44afb..58e2987 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -52,8 +52,7 @@ vfsreq_dispatchcopy(VfsReq tmpl)
vfsreq_finish_short(req, -EINVAL);
return;
}
- assert(req->queue_next == NULL);
- assert(req->postqueue_next == NULL);
+ assert(req->reqqueue_next == NULL);
if (backend == NULL) {
/* null mount - probably never had a real backend */
@@ -111,8 +110,7 @@ vfsreq_finish(VfsReq *req, char __user *stored, long ret, int flags, Proc *handl
vfsback_userdown(req->backend);
}
- assert(req->queue_next == NULL);
- assert(req->postqueue_next == NULL);
+ assert(req->reqqueue_next == NULL);
if (req->caller) {
assert(req->caller->state == PS_WAITS4FS);
@@ -134,17 +132,11 @@ vfsback_useraccept(VfsReq *req)
backend = req->backend;
assert(backend);
assert(backend->is_user);
- if (backend->provhcnt == 0) {
+ if (backend->user.provhcnt == 0) {
vfsreq_finish_short(req, -EPIPE);
return;
} else if (backend->user.handler == NULL) {
- /* queue the request up */
- // TODO use postqueue
- VfsReq **it = &backend->queue;
- while (*it != NULL) { /* find a free spot in queue */
- it = &(*it)->queue_next;
- }
- *it = req;
+ reqqueue_join(&backend->user.queue, req);
return;
}
@@ -194,8 +186,8 @@ vfsback_useraccept(VfsReq *req)
static void
vfsback_checkfree(VfsBackend *b)
{
- if (b->usehcnt == 0 && b->provhcnt == 0) {
- assert(!b->queue);
+ if (b->is_user && b->usehcnt == 0 && b->user.provhcnt == 0) {
+ assert(b->user.queue.head == NULL);
kfree(b);
}
}
@@ -227,54 +219,52 @@ void
vfsback_provdown(VfsBackend *b)
{
assert(b);
- assert(0 < b->provhcnt);
- b->provhcnt--;
- if (b->provhcnt == 0) {
+ assert(b->is_user);
+ assert(0 < b->user.provhcnt);
+ b->user.provhcnt--;
+ if (b->user.provhcnt == 0) {
+ assert(b->is_user);
/* discard everything in the queue */
- VfsReq *q = b->queue;
- while (q) {
- VfsReq *q2 = q->queue_next;
- q->queue_next = NULL;
+ VfsReq *q;
+ while ((q = reqqueue_pop(&b->user.queue))) {
vfsreq_finish_short(q, -EPIPE);
- q = q2;
}
- b->queue = NULL;
}
vfsback_checkfree(b);
}
void
-postqueue_init(ReqQueue *q)
+reqqueue_init(ReqQueue *q)
{
q->head = NULL;
}
void
-postqueue_join(ReqQueue *q, VfsReq *req)
+reqqueue_join(ReqQueue *q, VfsReq *req)
{
- if (req->postqueue_next)
+ if (req->reqqueue_next)
panic_invalid_state();
VfsReq **it = &q->head;
while (*it != NULL) {
- it = &(*it)->postqueue_next;
+ it = &(*it)->reqqueue_next;
}
*it = req;
}
VfsReq *
-postqueue_pop(ReqQueue *q)
+reqqueue_pop(ReqQueue *q)
{
VfsReq *req = q->head;
if (req) {
- q->head = req->postqueue_next;
- req->postqueue_next = NULL;
+ q->head = req->reqqueue_next;
+ req->reqqueue_next = NULL;
}
return req;
}
void
-postqueue_ringreadall(ReqQueue *q, ring_t *r)
+reqqueue_ringreadall(ReqQueue *q, ring_t *r)
{
VfsReq **queue = &q->head; /* whatever */
VfsReq *req;
@@ -283,15 +273,15 @@ postqueue_ringreadall(ReqQueue *q, ring_t *r)
if (ring_used(r) == 0) return;
/* read as much as the biggest request wants */
- for (req = *queue; req; req = req->postqueue_next)
+ for (req = *queue; req; req = req->reqqueue_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;
+ *queue = req->reqqueue_next;
+ req->reqqueue_next = NULL;
size_t ret = min(mlen, req->output.len);
assert(req->type == VFSOP_READ);
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index 616c044..6786e72 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -4,6 +4,10 @@
#include <stdbool.h>
#include <stddef.h>
+struct ReqQueue {
+ VfsReq *head;
+};
+
struct VfsBackend {
/* amount of using references
* VfsMount
@@ -11,17 +15,15 @@ struct VfsBackend {
* Handle
* once it reaches 0, it'll never increase */
size_t usehcnt; /* VfsMount */
- /* amount of providing references
- * Proc
- * 0 - orphaned, will never increase */
- // TODO move this into .user
- size_t provhcnt;
- VfsReq *queue;
bool is_user;
union {
struct {
Proc *handler;
+ ReqQueue queue; /* kernel backends keep their own queues */
+ /* amount of processes that control this backend
+ * won't ever increase if it becomes 0 */
+ size_t provhcnt;
} user;
struct {
void (*accept)(VfsReq *);
@@ -56,10 +58,7 @@ struct VfsReq {
Proc *caller;
VfsBackend *backend;
- VfsReq *queue_next;
- VfsReq *postqueue_next; /* used by kernel backends */
- /* only one of these queues is in use at a given moment, they could
- * be merged into a single field */
+ VfsReq *reqqueue_next;
};
/** Assigns the vfs_request to the caller, and dispatches the call */
@@ -79,13 +78,10 @@ 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);
+void reqqueue_init(ReqQueue *q);
+void reqqueue_join(ReqQueue *q, VfsReq *req);
+VfsReq *reqqueue_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);
+/** If there are any pending read requests, and the ring buffer isn't empty,
+ * fulfill them all with a single read. */
+void reqqueue_ringreadall(ReqQueue *q, ring_t *r);