diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/include/nullfs.h | 1 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 13 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 54 |
3 files changed, 53 insertions, 15 deletions
diff --git a/src/kernel/include/nullfs.h b/src/kernel/include/nullfs.h index cfca023..265d41b 100644 --- a/src/kernel/include/nullfs.h +++ b/src/kernel/include/nullfs.h @@ -11,6 +11,7 @@ typedef struct { void* (*open)(void* f, int mode, fs_handle_t *h); size_t (*read)(void* f, size_t offset, size_t len, char* buf); size_t (*write)(void* f, size_t offset, size_t len, const char* buf); + bool (*stat)(void* f, stat_t *st); void (*close)(void* f); void (*dispose)(void* f); } nullfs_node_ops_t; diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index 0a6a955..3ee4367 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -3,17 +3,7 @@ #include <stdbool.h> #include <malloc.h> -typedef struct { - // TODO - // (should also be moved to a user-visible header) -} stat_t; - -#define FM_READ (0x01) -#define FM_WRITE (0x02) -#define FM_MMAP (0x04) -#define FM_CREATE (0x10) -#define FM_TRUNC (0x20) -#define FM_APPEND (0x40) +#include <fs.h> // common header // How to use : // - when using a filesystem : never call the operations in fs_*_ops_t directly, use @@ -27,6 +17,7 @@ typedef struct { typedef struct { size_t (*read)(void* f, size_t offset, size_t len, char* buf); size_t (*write)(void* f, size_t offset, size_t len, const char* buf); + bool (*stat)(void* f, stat_t *st); void (*close)(void* f); } fs_handle_ops_t; diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index 79611ab..382e30b 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -1,5 +1,6 @@ #include <hashtbl.h> #include <string.h> +#include <debug.h> #include <nullfs.h> @@ -8,7 +9,9 @@ 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 bool nullfs_i_fs_stat(void* fs, const char* file, stat_t *st); +static bool nullfs_i_f_stat(void* f, stat_t *st); 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); @@ -22,7 +25,7 @@ static fs_ops_t nullfs_ops = { .open = nullfs_i_open, .delete = nullfs_i_delete, .rename = 0, - .stat = 0, + .stat = nullfs_i_fs_stat, .ioctl = 0, .add_source = 0, .shutdown = nullfs_i_shutdown @@ -31,7 +34,8 @@ static fs_ops_t nullfs_ops = { static fs_handle_ops_t nullfs_h_ops = { .read = nullfs_i_read, .write = nullfs_i_write, - .close = nullfs_i_close + .close = nullfs_i_close, + .stat = nullfs_i_f_stat }; // Internal nullfs structures @@ -122,8 +126,19 @@ 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. + if (x == 0) { + if (f->can_create) { + if (nullfs_add_ram_file(fs, file, 0, 0, false, + FM_READ | FM_WRITE | FM_APPEND | FM_TRUNC | FM_MMAP)) { + x = (nullfs_item_t*)(hashtbl_find(f->items, file)); + ASSERT(x != 0); + } else { + return false; + } + } else { + return false; + } + } nullfs_handle_t *h = (nullfs_handle_t*)malloc(sizeof(nullfs_handle_t)); if (h == 0) return false; @@ -140,6 +155,15 @@ bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) { return true; } +bool nullfs_i_fs_stat(void* fs, const char* file, stat_t *st) { + nullfs_t *f = (nullfs_t*)fs; + + nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file)); + if (x == 0) return false; + + return x->ops->stat && x->ops->stat(x->data, st); +} + bool nullfs_i_delete(void* fs, const char* file) { nullfs_t *f = (nullfs_t*)fs; @@ -153,6 +177,11 @@ bool nullfs_i_delete(void* fs, const char* file) { return true; } +bool nullfs_i_f_stat(void* f, stat_t *st) { + nullfs_handle_t *h = (nullfs_handle_t*)f; + return h->item->ops->stat && h->item->ops->stat(h->item->data, st); +} + 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; @@ -179,11 +208,13 @@ static void* nullfs_i_ram_open(void* f, int mode, fs_handle_t *h); static size_t nullfs_i_ram_read(void* f, size_t offset, size_t len, char* buf); static size_t nullfs_i_ram_write(void* f, size_t offset, size_t len, const char* buf); static void nullfs_i_ram_dispose(void* f); +static bool nullfs_i_ram_stat(void* f, stat_t *st); static nullfs_node_ops_t nullfs_ram_ops = { .open = nullfs_i_ram_open, .read = nullfs_i_ram_read, .write = nullfs_i_ram_write, + .stat = nullfs_i_ram_stat, .close = 0, .dispose = nullfs_i_ram_dispose }; @@ -228,6 +259,14 @@ void* nullfs_i_ram_open(void* fi, int mode, fs_handle_t *h) { if (mode & ~f->ok_modes) { return 0; } + mode &= ~FM_CREATE; + + if (mode & FM_TRUNC) { + if (f->data_owned) free(f->data); + f->data = 0; + f->size = 0; + f->data_owned = 0; + } h->mode = mode; return fi; @@ -272,6 +311,13 @@ void nullfs_i_ram_dispose(void* fi) { free(f); } +bool nullfs_i_ram_stat(void* fi, stat_t *st) { + nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi; + + st->size = f->size; + return true; +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ |