diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/handle.c | 5 | ||||
-rw-r--r-- | src/kernel/proc.c | 2 | ||||
-rw-r--r-- | src/kernel/vfs/mount.c | 2 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 62 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 8 |
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 *); |