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 /src/kernel/user/nullfs.c | |
parent | f90436dd7415354105a27846e587adefaea7ef63 (diff) | |
download | kogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.tar.gz kogata-8bfbc4b05b219950e3eb8ac377b8cb3020ddb9ab.zip |
Work on nullfs
Diffstat (limited to 'src/kernel/user/nullfs.c')
-rw-r--r-- | src/kernel/user/nullfs.c | 150 |
1 files changed, 143 insertions, 7 deletions
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 :*/ |