summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authordzwdz2024-07-07 17:42:18 +0200
committerdzwdz2024-07-07 17:42:18 +0200
commit8138ba97608ff0cd4e443994390f277eca3d7b28 (patch)
tree59b6066071f50aa0e7dc209cc5f7ef3433db1987 /src/kernel
parenta4975c459dec3a37e1634ad9b25c05f4caa4f1b0 (diff)
kernel/vfs: split vfs_backend_refdown into two functions
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/handle.c5
-rw-r--r--src/kernel/proc.c2
-rw-r--r--src/kernel/vfs/mount.c2
-rw-r--r--src/kernel/vfs/request.c62
-rw-r--r--src/kernel/vfs/request.h8
5 files changed, 51 insertions, 28 deletions
diff --git a/src/kernel/handle.c b/src/kernel/handle.c
index 882a4fa..f216c13 100644
--- a/src/kernel/handle.c
+++ b/src/kernel/handle.c
@@ -39,8 +39,9 @@ void handle_close(Handle *h) {
if (h->req) vfsreq_finish_short(h->req, -1);
}
- if (h->backend)
- vfs_backend_refdown(h->backend, true);
+ if (h->backend) {
+ vfsback_userdown(h->backend);
+ }
// TODO sanity check to check if refcount is true. handle_sanity?
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index 194353a..fcb51c6 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -217,7 +217,7 @@ void proc_kill(Proc *p, int ret) {
assert(p->state == PS_WAITS4REQUEST);
p->controlled->user.handler = NULL;
}
- vfs_backend_refdown(p->controlled, false);
+ vfsback_provdown(p->controlled);
p->controlled = NULL;
}
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index adf9b8c..15d1382 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -61,7 +61,7 @@ void vfs_mount_remref(VfsMount *mnt) {
VfsMount *prev = mnt->prev;
if (mnt->backend) {
- vfs_backend_refdown(mnt->backend, true);
+ vfsback_userdown(mnt->backend);
}
if (mnt->prefix_owned) {
kfree((void*)mnt->prefix);
diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c
index e3f0316..8fe0114 100644
--- a/src/kernel/vfs/request.c
+++ b/src/kernel/vfs/request.c
@@ -80,11 +80,13 @@ void vfsreq_finish(VfsReq *req, char __user *stored, long ret,
assert((size_t)ret <= req->output.len);
}
- if (req->input.kern)
+ if (req->input.kern) {
kfree(req->input.buf_kern);
+ }
- if (req->backend)
- vfs_backend_refdown(req->backend, true);
+ if (req->backend) {
+ vfsback_userdown(req->backend);
+ }
if (req->caller) {
assert(req->caller->state == PS_WAITS4FS);
@@ -159,26 +161,28 @@ static void vfs_backend_user_accept(VfsReq *req) {
return;
}
-void vfs_backend_refdown(VfsBackend *b, bool use) {
- size_t *field = use ? &b->usehcnt : &b->provhcnt;
- assert(b);
- assert(0 < *field);
- *field -= 1;
-
- if (b->provhcnt == 0 && use == false) {
- VfsReq *q = b->queue;
- while (q) {
- VfsReq *q2 = q->queue_next;
- vfsreq_finish_short(q, -1);
- q = q2;
- }
- b->queue = NULL;
+static void
+vfsback_checkfree(VfsBackend *b)
+{
+ if (b->usehcnt == 0 && b->provhcnt == 0) {
+ assert(!b->queue);
+ kfree(b);
}
- if (b->usehcnt == 0 && use == true) {
+}
+
+void
+vfsback_userdown(VfsBackend *b)
+{
+ assert(b);
+ assert(0 < b->usehcnt);
+ b->usehcnt--;
+ if (b->usehcnt == 0) {
if (!b->is_user && b->kern.cleanup) {
b->kern.cleanup(b);
}
if (b->is_user && b->user.handler) {
+ /* tell the process that the filesystem won't receive any more
+ * requests */
Proc *p = b->user.handler;
b->user.handler = NULL;
assert(p->state == PS_WAITS4REQUEST);
@@ -186,8 +190,24 @@ void vfs_backend_refdown(VfsBackend *b, bool use) {
proc_setstate(p, PS_RUNNING);
}
}
- if (b->usehcnt == 0 && b->provhcnt == 0) {
- assert(!b->queue);
- kfree(b);
+ vfsback_checkfree(b);
+}
+
+void
+vfsback_provdown(VfsBackend *b)
+{
+ assert(b);
+ assert(0 < b->provhcnt);
+ b->provhcnt--;
+ if (b->provhcnt == 0) {
+ /* discard everything in the queue */
+ VfsReq *q = b->queue;
+ while (q) {
+ VfsReq *q2 = q->queue_next;
+ vfsreq_finish_short(q, -1);
+ q = q2;
+ }
+ b->queue = NULL;
}
+ vfsback_checkfree(b);
}
diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h
index 182202c..2bd8c61 100644
--- a/src/kernel/vfs/request.h
+++ b/src/kernel/vfs/request.h
@@ -74,6 +74,8 @@ static inline void vfsreq_finish_short(VfsReq *req, long ret) {
/** Try to accept an enqueued request */
void vfs_backend_tryaccept(VfsBackend *);
-// TODO the bool arg is confusing. maybe this should just be a function
-// that verified the refcount and potentially frees the backend
-void vfs_backend_refdown(VfsBackend *, bool use);
+/** Decrements the "user" reference count. */
+void vfsback_userdown(VfsBackend *);
+
+/** Decrements the "provider" reference count. */
+void vfsback_provdown(VfsBackend *);