aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-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
5 files changed, 159 insertions, 21 deletions
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);
}