aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-02 18:38:45 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-02 18:38:45 +0100
commit969c8cacc50e8c39ddbc19e05f3f5b98c34bde01 (patch)
tree1b137ea0e940e2dd422f1d56cb8e4b67cfc2d99c
parent1a5c518ee1536db50dccd8766ce78c3790aec059 (diff)
downloadkogata-969c8cacc50e8c39ddbc19e05f3f5b98c34bde01.tar.gz
kogata-969c8cacc50e8c39ddbc19e05f3f5b98c34bde01.zip
Fix VFS reference counting.
-rw-r--r--src/kernel/user/vfs.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index 15f37cc..710326a 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -83,8 +83,6 @@ fs_t *fs_subfs(fs_t *fs, const char* root, int ok_modes) {
subfs->root = new_root;
- ref_fs(fs);
-
return subfs;
}
@@ -99,9 +97,13 @@ void ref_fs(fs_t *fs) {
void unref_fs(fs_t *fs) {
fs->refs--;
if (fs->refs == 0) {
- unref_fs_node(fs->root);
+ if (fs->from_fs != 0) {
+ unref_fs_node(fs->root);
+ } else {
+ ASSERT(fs->root->refs == 1);
+ if (fs->root->ops->dispose) fs->root->ops->dispose(fs->root->data);
+ }
if (fs->ops->shutdown) fs->ops->shutdown(fs->data);
- if (fs->from_fs) unref_fs(fs->from_fs);
free(fs);
}
}
@@ -119,21 +121,18 @@ void unref_fs_node(fs_node_t *n) {
mutex_lock(&n->lock);
n->refs--;
if (n->refs == 0) {
- if (n != n->fs->root) {
- ASSERT(n->parent != 0);
- ASSERT(n->name != 0);
+ ASSERT (n != n->fs->root);
- mutex_lock(&n->parent->lock);
- hashtbl_remove(n->parent->children, n->name);
- if (n->ops->dispose) n->ops->dispose(n->data);
- mutex_unlock(&n->parent->lock);
+ ASSERT(n->parent != 0);
+ ASSERT(n->name != 0);
- unref_fs_node(n->parent);
- unref_fs(n->fs);
- } else {
- ASSERT(n->fs->refs == 0);
- if (n->ops->dispose) n->ops->dispose(n->data);
- }
+ mutex_lock(&n->parent->lock);
+ hashtbl_remove(n->parent->children, n->name);
+ if (n->ops->dispose) n->ops->dispose(n->data);
+ mutex_unlock(&n->parent->lock);
+
+ unref_fs_node(n->parent);
+ unref_fs(n->fs);
if (n->children != 0) {
ASSERT(hashtbl_count(n->children) == 0);