aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-09 21:28:11 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-09 21:28:11 +0100
commit8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab (patch)
treed6dc0ff3158e2531820d323ceb925c79b5d99425 /src
parentf90436dd7415354105a27846e587adefaea7ef63 (diff)
downloadkogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.tar.gz
kogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.zip
Work on nullfs
Diffstat (limited to 'src')
-rw-r--r--src/common/common.libbin35663 -> 35823 bytes
-rw-r--r--src/common/hashtbl.c17
-rw-r--r--src/common/include/hashtbl.h12
-rw-r--r--src/kernel/core/kmain.c13
-rw-r--r--src/kernel/include/devfs.h8
-rw-r--r--src/kernel/include/nullfs.h3
-rw-r--r--src/kernel/user/nullfs.c150
-rw-r--r--src/kernel/user/vfs.c6
8 files changed, 174 insertions, 35 deletions
diff --git a/src/common/common.lib b/src/common/common.lib
index 55de3ef..4eede87 100644
--- a/src/common/common.lib
+++ b/src/common/common.lib
Binary files differ
diff --git a/src/common/hashtbl.c b/src/common/hashtbl.c
index d034ff5..b87bcef 100644
--- a/src/common/hashtbl.c
+++ b/src/common/hashtbl.c
@@ -16,12 +16,12 @@ typedef struct hashtbl_item {
struct hashtbl {
key_eq_fun_t ef;
hash_fun_t hf;
- key_free_fun_t kff;
+ free_fun_t kff;
size_t size, nitems;
hashtbl_item_t **items;
};
-hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, key_free_fun_t kff, size_t initial_size) {
+hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, free_fun_t kff, size_t initial_size) {
hashtbl_t *ht = (hashtbl_t*)malloc(sizeof(hashtbl_t));
if (ht == 0) return 0;
@@ -43,11 +43,12 @@ hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, key_free_fun_t kff, si
return ht;
}
-void delete_hashtbl(hashtbl_t *ht) {
+void delete_hashtbl(hashtbl_t *ht, free_fun_t data_free_fun) {
// Free items
for (size_t i = 0; i < ht->size; i++) {
while (ht->items[i] != 0) {
hashtbl_item_t *n = ht->items[i]->next;
+ if (data_free_fun) data_free_fun(ht->items[i]->val);
if (ht->kff) ht->kff(ht->items[i]->key);
free(ht->items[i]);
ht->items[i] = n;
@@ -87,11 +88,11 @@ static void hashtbl_check_size(hashtbl_t *ht) {
}
}
-int hashtbl_add(hashtbl_t *ht, void* key, void* v) {
+bool hashtbl_add(hashtbl_t *ht, void* key, void* v) {
size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
hashtbl_item_t *i = (hashtbl_item_t*)malloc(sizeof(hashtbl_item_t));
- if (i == 0) return 1; // OOM
+ if (i == 0) return false; // OOM
// make sure item is not already present
hashtbl_remove(ht, key);
@@ -104,10 +105,10 @@ int hashtbl_add(hashtbl_t *ht, void* key, void* v) {
hashtbl_check_size(ht);
- return 0;
+ return true;
}
-void* hashtbl_find(hashtbl_t* ht, void* key) {
+void* hashtbl_find(hashtbl_t* ht, const void* key) {
size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) {
@@ -117,7 +118,7 @@ void* hashtbl_find(hashtbl_t* ht, void* key) {
return 0;
}
-void hashtbl_remove(hashtbl_t* ht, void* key) {
+void hashtbl_remove(hashtbl_t* ht, const void* key) {
size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
if (ht->items[slot] == 0) return;
diff --git a/src/common/include/hashtbl.h b/src/common/include/hashtbl.h
index 3b5a44d..ecac0a8 100644
--- a/src/common/include/hashtbl.h
+++ b/src/common/include/hashtbl.h
@@ -19,14 +19,14 @@ typedef struct hashtbl hashtbl_t;
typedef size_t hash_t;
typedef hash_t (*hash_fun_t)(const void*);
typedef bool (*key_eq_fun_t)(const void*, const void*);
-typedef void (*key_free_fun_t)(void*);
+typedef void (*free_fun_t)(void*);
-hashtbl_t* create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, key_free_fun_t ff, size_t initial_size); // 0 -> default size
-void delete_hashtbl(hashtbl_t* ht);
+hashtbl_t* create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, free_fun_t key_ff, size_t initial_size); // 0 -> default size
+void delete_hashtbl(hashtbl_t* ht, free_fun_t data_free_fun);
-int hashtbl_add(hashtbl_t* ht, void* key, void* v); // non-null on error (OOM for instance)
-void* hashtbl_find(hashtbl_t* ht, void* key); // null when not found
-void hashtbl_remove(hashtbl_t* ht, void* key);
+bool hashtbl_add(hashtbl_t* ht, void* key, void* v); // true = ok, false on error (OOM for instance)
+void* hashtbl_find(hashtbl_t* ht, const void* key); // null when not found
+void hashtbl_remove(hashtbl_t* ht, const void* key);
size_t hashtbl_count(hashtbl_t* ht);
hash_t id_hash_fun(const void* v);
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index 9ad8178..4ced0da 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -124,7 +124,7 @@ void test_hashtbl_1() {
dbg_printf("ht[test1] = %s\n", hashtbl_find(ht, "test1"));
dbg_printf("ht[test] = %s\n", hashtbl_find(ht, "test"));
dbg_printf("ht[test2] = %s\n", hashtbl_find(ht, "test2"));
- delete_hashtbl(ht);
+ delete_hashtbl(ht, 0);
}
void test_hashtbl_2() {
@@ -144,7 +144,7 @@ void test_hashtbl_2() {
dbg_printf("ht[12] = %s\n", hashtbl_find(ht, (void*)12));
dbg_printf("ht[144] = %s\n", hashtbl_find(ht, (void*)144));
dbg_printf("ht[777] = %s\n", hashtbl_find(ht, (void*)777));
- delete_hashtbl(ht);
+ delete_hashtbl(ht, 0);
}
void test_thread(void* a) {
@@ -254,14 +254,17 @@ void kernel_init_stage2(void* data) {
strcpy(name, "/mod/");
strcpy(name+5, modname);
- nullfs_add_ram_file(devfs, name,
+ dbg_printf("Adding model to VFS: %s\n", name);
+
+ ASSERT(nullfs_add_ram_file(devfs, name,
(void*)mods[i].mod_start,
mods[i].mod_end - mods[i].mod_start,
- FM_READ);
+ false,
+ FM_READ));
}
//TODO :
- // - populate devfs with information regarding kernel command line & modules
+ // - (OK) populate devfs with information regarding kernel command line & modules
// - create user process with init module provided on command line
// - give it rights to devfs
// - launch it
diff --git a/src/kernel/include/devfs.h b/src/kernel/include/devfs.h
deleted file mode 100644
index 0dee246..0000000
--- a/src/kernel/include/devfs.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include <vfs.h>
-
-fs_t* init_devfs();
-
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/include/nullfs.h b/src/kernel/include/nullfs.h
index 16fff87..045cc93 100644
--- a/src/kernel/include/nullfs.h
+++ b/src/kernel/include/nullfs.h
@@ -13,6 +13,7 @@ typedef struct {
size_t (*write)(void* f, size_t offset, size_t len, const char* buf);
void (*close)(void* f);
void (*delete)(void* f);
+ void (*dispose)(void* f);
} nullfs_node_ops_t;
void register_nullfs_driver();
@@ -20,6 +21,6 @@ void register_nullfs_driver();
nullfs_t* as_nullfs(fs_t *fs);
bool nullfs_add(nullfs_t *f, const char* name, void* data, nullfs_node_ops_t* ops);
-bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, int ok_modes);
+bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, bool copy, int ok_modes);
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c
index cb866c0..7aa2d24 100644
--- a/src/kernel/user/nullfs.c
+++ b/src/kernel/user/nullfs.c
@@ -1,16 +1,59 @@
+#include <hashtbl.h>
+#include <string.h>
+
#include <nullfs.h>
-bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d);
+static bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d);
+
+static bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s);
+static bool nullfs_i_delete(void* fs, const char* file);
+static void nullfs_i_shutdown(void* fs);
+
+static size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf);
+static size_t nullfs_i_write(void* f, size_t offset, size_t len, const char* buf);
+static void nullfs_i_close(void* f);
-fs_driver_ops_t nullfs_driver_ops = {
+static fs_driver_ops_t nullfs_driver_ops = {
.make = nullfs_i_make,
.detect = 0,
};
-fs_ops_t nullfs_ops = {
- 0 //TODO
+static fs_ops_t nullfs_ops = {
+ .open = nullfs_i_open,
+ .delete = nullfs_i_delete,
+ .rename = 0,
+ .stat = 0,
+ .ioctl = 0,
+ .add_source = 0,
+ .shutdown = nullfs_i_shutdown
+};
+
+static fs_handle_ops_t nullfs_h_ops = {
+ .read = nullfs_i_read,
+ .write = nullfs_i_write,
+ .close = nullfs_i_close
};
+// Internal nullfs structures
+
+typedef struct {
+ void* data;
+ nullfs_node_ops_t *ops;
+} nullfs_item_t;
+
+typedef struct {
+ nullfs_item_t *item;
+ void* data;
+} nullfs_handle_t;
+
+typedef struct nullfs {
+ hashtbl_t *items;
+ bool can_delete;
+ bool can_create;
+} nullfs_t;
+
+// Nullfs management
+
void register_nullfs_driver() {
register_fs_driver("nullfs", &nullfs_driver_ops);
}
@@ -21,18 +64,111 @@ nullfs_t *as_nullfs(fs_t *it) {
}
bool nullfs_i_make(fs_handle_t *source, char* opts, fs_t *d) {
- // TODO
- return false;
+ nullfs_t *fs = (nullfs_t*)malloc(sizeof(nullfs_t));
+ if (fs == 0) return false;
+
+ fs->items = create_hashtbl(str_key_eq_fun, str_hash_fun, free, 0);
+ if (fs->items == 0) {
+ free(fs);
+ return false;
+ }
+
+ fs->can_delete = (strchr(opts, 'd') != 0);
+ fs->can_create = (strchr(opts, 'c') != 0);
+
+ d->data = fs;
+ d->ops = &nullfs_ops;
+
+ return true;
}
bool nullfs_add(nullfs_t *f, const char* name, void* data, nullfs_node_ops_t *ops) {
+ nullfs_item_t *i = (nullfs_item_t*)malloc(sizeof(nullfs_item_t));
+ if (i == 0) return false;
+
+ char* n = strdup(name);
+ if (n == 0) {
+ free(i);
+ return false;
+ }
+
+ i->data = data;
+ i->ops = ops;
+ if (!hashtbl_add(f->items, n, i)) {
+ free(n);
+ free(i);
+ return false;
+ }
+
+ return true;
+}
+
+static void nullfs_i_free_item(void* x) {
+ nullfs_item_t *i = (nullfs_item_t*)x;
+ if (i->ops->dispose) i->ops->dispose(i->data);
+ free(i);
+}
+
+void nullfs_i_shutdown(void* fs) {
+ nullfs_t *f = (nullfs_t*)fs;
+
+ delete_hashtbl(f->items, nullfs_i_free_item);
+ free(f);
+}
+
+bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, bool copy, int ok_modes) {
// TODO
return false;
}
-bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, int ok_modes) {
+// Nullfs operations
+
+bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) {
+ nullfs_t *f = (nullfs_t*)fs;
+
+ nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file));
+ if (x == 0) return false;
+ // TODO : if null and can_create, then create.
+
+ nullfs_handle_t *h = (nullfs_handle_t*)malloc(sizeof(nullfs_handle_t));
+ if (h == 0) return false;
+
+ h->item = x;
+ h->data = x->ops->open(x->data, mode, s);
+ if (h->data == 0) {
+ free(h);
+ return false;
+ }
+
+ s->data = h;
+ s->ops = &nullfs_h_ops;
+ return true;
+}
+
+bool nullfs_i_delete(void* fs, const char* file) {
+ nullfs_t *f = (nullfs_t*)fs;
+
+ if (!f->can_delete) return false;
// TODO
return false;
}
+size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf) {
+ nullfs_handle_t *h = (nullfs_handle_t*)f;
+ if (!h->item->ops->read) return 0;
+ return h->item->ops->read(h->data, offset, len, buf);
+}
+
+size_t nullfs_i_write(void* f, size_t offset, size_t len, const char* buf) {
+ nullfs_handle_t *h = (nullfs_handle_t*)f;
+ if (!h->item->ops->write) return 0;
+ return h->item->ops->write(h->data, offset, len, buf);
+}
+
+void nullfs_i_close(void* f) {
+ nullfs_handle_t *h = (nullfs_handle_t*)f;
+ if (h->item->ops->close) h->item->ops->close(h->data);
+ free(h);
+}
+
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c
index ebd5808..83f1377 100644
--- a/src/kernel/user/vfs.c
+++ b/src/kernel/user/vfs.c
@@ -42,6 +42,7 @@ fs_t *make_fs(const char* drv_name, fs_handle_t *source, char* opts) {
if (fs == 0) return 0;
if (d->ops->make(source, opts, fs)) {
+ fs->refs = 1;
return fs;
} else {
free(fs);
@@ -92,6 +93,7 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) {
if (h == 0) return 0;
if (fs->ops->open(fs->data, file, mode, h)) {
+ h->refs = 1;
return h;
} else {
free(h);
@@ -112,10 +114,14 @@ void unrefe_file(fs_handle_t *file) {
}
size_t file_read(fs_handle_t *f, size_t offset, size_t len, char* buf) {
+ if (!(f->mode && FM_READ)) return 0;
+
return f->ops->read && f->ops->read(f->data, offset, len, buf);
}
size_t file_write(fs_handle_t *f, size_t offset, size_t len, const char* buf) {
+ if (!(f->mode && FM_WRITE)) return 0;
+
return f->ops->write && f->ops->write(f->data, offset, len, buf);
}