diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/core/kmain.c | 13 | ||||
-rw-r--r-- | src/kernel/include/nullfs.h | 1 | ||||
-rw-r--r-- | src/kernel/include/vfs.h | 1 | ||||
-rw-r--r-- | src/kernel/user/nullfs.c | 115 | ||||
-rw-r--r-- | src/kernel/user/vfs.c | 11 |
5 files changed, 129 insertions, 12 deletions
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index e5012b3..9b1cd12 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -271,9 +271,20 @@ void kernel_init_stage2(void* data) { (void*)mods[i].mod_start, mods[i].mod_end - mods[i].mod_start, false, - FM_READ)); + FM_READ | FM_MMAP)); } + // TEST : read /cmdline + dbg_printf("Trying to read /cmdline... "); + fs_handle_t *f = fs_open(devfs_fs, "/cmdline", FM_READ); + ASSERT(f != 0); + char buf[256]; + size_t l = file_read(f, 0, 255, buf); + ASSERT(l > 0); + buf[l] = 0; + unref_file(f); + dbg_printf("got '%s'.\n", buf); + //TODO : // - (OK) populate devfs with information regarding kernel command line & modules // - create user process with init module provided on command line diff --git a/src/kernel/include/nullfs.h b/src/kernel/include/nullfs.h index 045cc93..cfca023 100644 --- a/src/kernel/include/nullfs.h +++ b/src/kernel/include/nullfs.h @@ -12,7 +12,6 @@ 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); void (*close)(void* f); - void (*delete)(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 5f7a0d8..0a6a955 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -31,6 +31,7 @@ typedef struct { } fs_handle_ops_t; typedef struct fs_handle { + struct fs *fs; int refs; fs_handle_ops_t *ops; void* data; diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index 7aa2d24..5c6be94 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -116,11 +116,6 @@ void nullfs_i_shutdown(void* fs) { 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; -} - // Nullfs operations bool nullfs_i_open(void* fs, const char* file, int mode, fs_handle_t *s) { @@ -149,8 +144,13 @@ bool nullfs_i_delete(void* fs, const char* file) { nullfs_t *f = (nullfs_t*)fs; if (!f->can_delete) return false; - // TODO - return false; + + nullfs_item_t *x = (nullfs_item_t*)(hashtbl_find(f->items, file)); + if (x == 0) return false; + + hashtbl_remove(f->items, file); + nullfs_i_free_item(x); + return true; } size_t nullfs_i_read(void* f, size_t offset, size_t len, char* buf) { @@ -171,4 +171,105 @@ void nullfs_i_close(void* f) { free(h); } +// ====================================================== // +// THE FUNCTIONS FOR HAVING RAM FILES (nullfs as ramdisk) // +// ====================================================== // + +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 nullfs_node_ops_t nullfs_ram_ops = { + .open = nullfs_i_ram_open, + .read = nullfs_i_ram_read, + .write = nullfs_i_ram_write, + .close = 0, + .dispose = nullfs_i_ram_dispose +}; + +typedef struct { + void* data; + bool data_owned; + size_t size; + int ok_modes; +} nullfs_ram_file_t; + +bool nullfs_add_ram_file(nullfs_t *f, const char* name, void* data, size_t init_sz, bool copy, int ok_modes) { + nullfs_ram_file_t *x = (nullfs_ram_file_t*)malloc(sizeof(nullfs_ram_file_t)); + if (x == 0) return false; + + if (copy) { + x->data = malloc(init_sz); + if (x->data == 0) { + free(x); + return false; + } + memcpy(x->data, data, init_sz); + x->data_owned = true; + } else { + x->data = data; + x->data_owned = false; + } + x->size = init_sz; + x->ok_modes = ok_modes; + + if (!nullfs_add(f, name, x, &nullfs_ram_ops)) { + if (x->data_owned) free(x->data); + free(x); + return false; + } + return true; +} + +void* nullfs_i_ram_open(void* fi, int mode, fs_handle_t *h) { + nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi; + + if (mode & ~f->ok_modes) { + return 0; + } + + h->mode = mode; + return fi; +} + +size_t nullfs_i_ram_read(void* fi, size_t offset, size_t len, char* buf) { + nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi; + + if (offset >= f->size) return 0; + if (offset + len > f->size) len = f->size - offset; + + memcpy(buf, f->data + offset, len); + return len; +} + +size_t nullfs_i_ram_write(void* fi, size_t offset, size_t len, const char* buf) { + nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi; + + if (offset + len > f->size) { + // resize buffer (zero out new portion) + void* new_buffer = malloc(offset + len); + if (new_buffer == 0) return 0; + + memcpy(new_buffer, f->data, f->size); + if (offset > f->size) + memset(new_buffer + f->size, 0, offset - f->size); + free(f->data); + f->data = new_buffer; + f->size = offset + len; + } + + memcpy(f->data + offset, buf, len); + return len; +} + +void nullfs_i_ram_dispose(void* fi) { + nullfs_ram_file_t *f = (nullfs_ram_file_t*)fi; + + if (f->data_owned) free(f->data); + free(f); +} + + + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index 83f1377..32fcb03 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -94,6 +94,8 @@ fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { if (fs->ops->open(fs->data, file, mode, h)) { h->refs = 1; + h->fs = fs; + ref_fs(fs); return h; } else { free(h); @@ -105,9 +107,10 @@ void ref_file(fs_handle_t *file) { file->refs++; } -void unrefe_file(fs_handle_t *file) { +void unref_file(fs_handle_t *file) { file->refs--; if (file->refs == 0) { + unref_fs(file->fs); file->ops->close(file->data); free(file); } @@ -116,13 +119,15 @@ 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); + if (f->ops->read == 0) return 0; + return 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); + if (f->ops->write == 0) return 0; + return f->ops->write(f->data, offset, len, buf); } int file_get_mode(fs_handle_t *f) { |