diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-09 21:28:11 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-09 21:28:11 +0100 |
commit | 8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab (patch) | |
tree | d6dc0ff3158e2531820d323ceb925c79b5d99425 | |
parent | f90436dd7415354105a27846e587adefaea7ef63 (diff) | |
download | kogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.tar.gz kogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.zip |
Work on nullfs
-rw-r--r-- | src/common/common.lib | bin | 35663 -> 35823 bytes | |||
-rw-r--r-- | src/common/hashtbl.c | 17 | ||||
-rw-r--r-- | src/common/include/hashtbl.h | 12 | ||||
-rw-r--r-- | src/kernel/core/kmain.c | 13 | ||||
-rw-r--r-- | src/kernel/include/devfs.h | 8 | ||||
-rw-r--r-- | src/kernel/include/nullfs.h | 3 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 150 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 6 |
8 files changed, 174 insertions, 35 deletions
diff --git a/src/common/common.lib b/src/common/common.lib Binary files differindex 55de3ef..4eede87 100644 --- a/src/common/common.lib +++ b/src/common/common.lib 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); } |