summaryrefslogtreecommitdiff
path: root/src/kernel/vfs
diff options
context:
space:
mode:
authordzwdz2022-05-03 20:31:50 +0200
committerdzwdz2022-05-03 20:31:50 +0200
commit9692ed2f93777e1060837b97687509f8a22c2b60 (patch)
tree967dd6c85e7f07dbc9277bc0d2a534a49091de26 /src/kernel/vfs
parentbeb55e5fcaa5098943352bd07eb27cf8b00e336c (diff)
kernel: reference count mount objects, free them on process kills
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r--src/kernel/vfs/mount.c16
-rw-r--r--src/kernel/vfs/mount.h6
2 files changed, 21 insertions, 1 deletions
diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c
index 423bf10..3fe192d 100644
--- a/src/kernel/vfs/mount.c
+++ b/src/kernel/vfs/mount.c
@@ -1,4 +1,5 @@
#include <kernel/mem/alloc.h>
+#include <kernel/panic.h>
#include <kernel/vfs/mount.h>
#include <shared/mem.h>
@@ -9,9 +10,10 @@ struct vfs_mount *vfs_mount_seed(void) {
backend->potential_handlers = 1;
*mount = (struct vfs_mount){
.prev = NULL,
- .prefix = "",
+ .prefix = NULL,
.prefix_len = 0,
.backend = backend,
+ .refs = 1, // never to be freed
};
return mount;
}
@@ -36,3 +38,15 @@ struct vfs_mount *vfs_mount_resolve(
}
return top;
}
+
+void vfs_mount_remref(struct vfs_mount *mnt) {
+ assert(mnt);
+ assert(mnt->refs > 0);
+ if (--(mnt->refs) > 0) return;
+
+ struct vfs_mount *prev = mnt->prev;
+ kfree(mnt->prefix);
+ kfree(mnt);
+
+ if (prev) vfs_mount_remref(prev);
+}
diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h
index 5fb6d16..96a2d7b 100644
--- a/src/kernel/vfs/mount.h
+++ b/src/kernel/vfs/mount.h
@@ -7,9 +7,15 @@ struct vfs_mount {
char *prefix;
size_t prefix_len;
struct vfs_backend *backend;
+ size_t refs; /* counts all references, atm from:
+ * - struct vfs_mount
+ * - struct proc
+ */
};
// prepares init's filesystem view
struct vfs_mount *vfs_mount_seed(void);
struct vfs_mount *vfs_mount_resolve(
struct vfs_mount *top, const char *path, size_t path_len);
+/** Decrements the reference count, potentially freeing the mount. */
+void vfs_mount_remref(struct vfs_mount *mnt);