From 150dd5f860a5f22a8c3bcc1bf3a1f2e36dcf6fd8 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 24 Feb 2015 16:58:33 +0100 Subject: Change VFS a bit : the root directory of a fs is now a pointer. Fix tests. --- menu_cdrom.lst | 8 +++- src/common/libc/string.c | 1 + src/kernel/core/kmain.c | 8 ++-- src/kernel/fs/iso9660.c | 12 ++---- src/kernel/include/vfs.h | 3 +- src/kernel/user/nullfs.c | 9 ++-- src/kernel/user/vfs.c | 86 ++++++++++++++++++++++----------------- src/tests/utests/fs1/test.c | 3 +- src/tests/utests/run_qemu_test.sh | 2 +- 9 files changed, 72 insertions(+), 60 deletions(-) diff --git a/menu_cdrom.lst b/menu_cdrom.lst index cc9f50d..f055427 100644 --- a/menu_cdrom.lst +++ b/menu_cdrom.lst @@ -1,5 +1,11 @@ timeout 10 +default 1 -title Macroscope + +title kogata OS kernel /kernel.bin root=io:/atapi0 init=root:/init.bin +title kogata OS without root +kernel /kernel.bin init=io:/mod/init.bin +module /init.bin + diff --git a/src/common/libc/string.c b/src/common/libc/string.c index e5f7a53..82c290f 100644 --- a/src/common/libc/string.c +++ b/src/common/libc/string.c @@ -64,6 +64,7 @@ int strncmp(const char *s1, const char *s2, size_t n) { s2++; i++; } + if (i == n) return 0; return (*(unsigned char*)s1 - *(unsigned char*)s2); } diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index eb5eb16..7bdf27d 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -152,7 +152,8 @@ void kernel_init_stage2(void* data) { // Parse command line btree_t *cmdline = parse_cmdline((const char*)mbd->cmdline); - fs_t *rootfs = setup_rootfs(cmdline, iofs); + fs_t *rootfs = 0; + if (btree_find(cmdline, "root") != 0) rootfs = setup_rootfs(cmdline, iofs); launch_init(cmdline, iofs, rootfs); @@ -264,7 +265,7 @@ fs_t *setup_rootfs(btree_t *cmdline, fs_t *iofs) { void launch_init(btree_t *cmdline, fs_t *iofs, fs_t *rootfs) { fs_t *init_fs = rootfs; char* init_file = btree_find(cmdline, "init"); - if (init_file != 0) PANIC("No init specified on kernel command line."); + if (init_file == 0) PANIC("No init specified on kernel command line."); dbg_printf("Launching init %s...\n", init_file); @@ -276,10 +277,9 @@ void launch_init(btree_t *cmdline, fs_t *iofs, fs_t *rootfs) { } else if (strncmp(init_file, "root:", 5) == 0) { init_fs = rootfs; init_file = init_file + 5; - } else { - PANIC("Invalid init file specification."); } } + if (init_fs == 0) PANIC("Invalid file system specification for init file."); // Launch INIT fs_handle_t *init_bin = fs_open(init_fs, init_file, FM_READ); diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c index 60e9a81..b17a975 100644 --- a/src/kernel/fs/iso9660.c +++ b/src/kernel/fs/iso9660.c @@ -3,16 +3,14 @@ #include static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t); -static bool iso9660_detect(fs_handle_t *source); static fs_driver_ops_t iso9660_driver_ops = { .make = iso9660_make, - .detect = iso9660_detect, }; void register_iso9660_driver() { - ASSERT(sizeof(iso9660_vdt_entry_t) == 2048); - ASSERT(sizeof(iso9660_dr_t) == 34); + //ASSERT(sizeof(iso9660_vdt_entry_t) == 2048); + //ASSERT(sizeof(iso9660_dr_t) == 34); register_fs_driver("iso9660", &iso9660_driver_ops); } @@ -21,7 +19,7 @@ void register_iso9660_driver() { // FILESYSTEM DETECTION AND SETUP // // ============================== // -static bool iso9660_detect(fs_handle_t *source) { +static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t) { stat_t st; if (!file_stat(source, &st)) return false; if ((st.type & FT_BLOCKDEV) != 0) return false; @@ -32,8 +30,4 @@ static bool iso9660_detect(fs_handle_t *source) { return false; // TODO } -static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t) { - return false; // TODO -} - /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index 82b02f4..0890663 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -128,7 +128,7 @@ typedef struct fs { fs_ops_t *ops; fs_ptr data; // Filled by both according to what is specified for fs_node_t - fs_node_t root; + fs_node_t *root; } fs_t; // ------------------------------------------- @@ -136,7 +136,6 @@ typedef struct fs { typedef struct { bool (*make)(fs_handle_t *source, const char* opts, fs_t *d); - bool (*detect)(fs_handle_t *source); } fs_driver_ops_t; // ------------------------------------------- diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index a925ab5..a44e4b3 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -37,7 +37,6 @@ static void nullfs_fh_close(fs_handle_ptr f); // VTables that go with it static fs_driver_ops_t nullfs_driver_ops = { .make = nullfs_fs_make, - .detect = 0, }; static fs_ops_t nullfs_ops = { @@ -134,6 +133,8 @@ void register_nullfs_driver() { } bool nullfs_fs_make(fs_handle_t *source, const char* opts, fs_t *fs_s) { + if (source != 0) return false; + nullfs_t *fs = (nullfs_t*)malloc(sizeof(nullfs_t)); if (fs == 0) return false; @@ -159,8 +160,8 @@ bool nullfs_fs_make(fs_handle_t *source, const char* opts, fs_t *fs_s) { fs_s->ops = &nullfs_ops; fs_s->data = fs; - fs_s->root.ops = &nullfs_d_ops; - fs_s->root.data = root; + fs_s->root->ops = &nullfs_d_ops; + fs_s->root->data = root; return true; } @@ -173,7 +174,7 @@ void nullfs_fs_shutdown(fs_ptr fs) { bool nullfs_add_node(fs_t *fs, const char* name, fs_node_ptr data, fs_node_ops_t *ops) { char file_name[DIR_MAX]; - fs_node_t *n = fs_walk_path_except_last(&fs->root, name, file_name); + fs_node_t *n = fs_walk_path_except_last(fs->root, name, file_name); if (n == 0) return false; if (n->ops != &nullfs_d_ops) return false; diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index c20caa0..1c841f7 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -29,31 +29,35 @@ void register_fs_driver(const char* name, fs_driver_ops_t *ops) { // ================================== // fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) { - // Look for driver - fs_driver_t *d = 0; - for(fs_driver_t *i = drivers; i != 0; i = i->next) { - if (drv_name != 0 && strcmp(i->name, drv_name) == 0) d = i; - if (drv_name == 0 && source != 0 && i->ops->detect && i->ops->detect(source)) d = i; - if (d != 0) break; - } - if (d == 0) return 0; // driver not found - // Open file system fs_t *fs = (fs_t*)malloc(sizeof(fs_t)); - if (fs == 0) return 0; + if (fs == 0) goto fail; + + fs->root = (fs_node_t*)malloc(sizeof(fs_node_t)); + if (fs->root == 0) goto fail; fs->refs = 1; - fs->root.refs = 1; // root node is never disposed of (done by fs->shutdown) - fs->root.fs = fs; - fs->root.parent = 0; - fs->root.children = 0; + fs->root->refs = 1; + fs->root->fs = fs; + fs->root->parent = 0; + fs->root->children = 0; - if (d->ops->make(source, opts, fs)) { - return fs; - } else { - free(fs); - return 0; + // Look for driver + for(fs_driver_t *i = drivers; i != 0; i = i->next) { + if ((drv_name != 0 && strcmp(i->name, drv_name) == 0) || (drv_name == 0 && source != 0)) { + if (i->ops->make(source, opts, fs)) { + return fs; + } else { + goto fail; + } + } } + + +fail: + if (fs && fs->root) free(fs->root); + if (fs) free(fs); + return 0; } bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts) { @@ -67,8 +71,7 @@ void ref_fs(fs_t *fs) { void unref_fs(fs_t *fs) { fs->refs--; if (fs->refs == 0) { - // don't unref root node, don't call dispose on it - // (done by fs->shutdown) + unref_fs_node(fs->root); fs->ops->shutdown(fs->data); free(fs); } @@ -87,19 +90,26 @@ void unref_fs_node(fs_node_t *n) { mutex_lock(&n->lock); n->refs--; if (n->refs == 0) { - ASSERT(n != &n->fs->root); - ASSERT(n->parent != 0); - ASSERT(n->name != 0); + if (n != n->fs->root) { + ASSERT(n->parent != 0); + ASSERT(n->name != 0); - mutex_lock(&n->parent->lock); - hashtbl_remove(n->parent->children, n->name); - if (n->ops->dispose) n->ops->dispose(n->data); - mutex_unlock(&n->parent->lock); + mutex_lock(&n->parent->lock); + hashtbl_remove(n->parent->children, n->name); + if (n->ops->dispose) n->ops->dispose(n->data); + mutex_unlock(&n->parent->lock); - unref_fs_node(n->parent); - unref_fs(n->fs); + unref_fs_node(n->parent); + unref_fs(n->fs); + } else { + ASSERT(n->fs->refs == 0); + if (n->ops->dispose) n->ops->dispose(n->data); + } - if (n->children != 0) delete_hashtbl(n->children); + if (n->children != 0) { + ASSERT(hashtbl_count(n->children) == 0); + delete_hashtbl(n->children); + } free(n->name); free(n); } else { @@ -251,7 +261,7 @@ fs_node_t* fs_walk_path_except_last(fs_node_t* from, const char* path, char* las bool fs_create(fs_t *fs, const char* file, int type) { char name[DIR_MAX]; - fs_node_t *n = fs_walk_path_except_last(&fs->root, file, name); + fs_node_t *n = fs_walk_path_except_last(fs->root, file, name); if (n == 0) return false; mutex_lock(&n->lock); @@ -265,7 +275,7 @@ bool fs_create(fs_t *fs, const char* file, int type) { bool fs_delete(fs_t *fs, const char* file) { char name[DIR_MAX]; - fs_node_t* n = fs_walk_path_except_last(&fs->root, file, name); + fs_node_t* n = fs_walk_path_except_last(fs->root, file, name); if (n == 0) return false; if (n->children != 0) { @@ -283,11 +293,11 @@ bool fs_delete(fs_t *fs, const char* file) { bool fs_move(fs_t *fs, const char* from, const char* to) { char old_name[DIR_MAX]; - fs_node_t *old_parent = fs_walk_path_except_last(&fs->root, from, old_name); + fs_node_t *old_parent = fs_walk_path_except_last(fs->root, from, old_name); if (old_parent == 0) return false; char new_name[DIR_MAX]; - fs_node_t *new_parent = fs_walk_path_except_last(&fs->root, to, new_name); + fs_node_t *new_parent = fs_walk_path_except_last(fs->root, to, new_name); if (new_parent == 0) { unref_fs_node(old_parent); return false; @@ -343,7 +353,7 @@ end: } bool fs_stat(fs_t *fs, const char* file, stat_t *st) { - fs_node_t* n = fs_walk_path(&fs->root, file); + fs_node_t* n = fs_walk_path(fs->root, file); if (n == 0) return false; mutex_lock(&n->lock); @@ -359,10 +369,10 @@ bool fs_stat(fs_t *fs, const char* file, stat_t *st) { // =================== // fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { - fs_node_t *n = fs_walk_path(&fs->root, file); + fs_node_t *n = fs_walk_path(fs->root, file); if (n == 0 && (mode & FM_CREATE)) { if (fs_create(fs, file, FT_REGULAR)) { - n = fs_walk_path(&fs->root, file); + n = fs_walk_path(fs->root, file); } } if (n == 0) return 0; diff --git a/src/tests/utests/fs1/test.c b/src/tests/utests/fs1/test.c index 247373d..7d6afd6 100644 --- a/src/tests/utests/fs1/test.c +++ b/src/tests/utests/fs1/test.c @@ -8,8 +8,9 @@ int main(int argc, char **argv) { dbg_print("Hello, world! from user process.\n"); - fd_t f = open("dev:/", FM_READDIR); + fd_t f = open("io:/", FM_READDIR); dbg_printf("openned /: %d\n", f); + ASSERT(f != 0); dirent_t x; while (readdir(f, &x)) { dbg_printf("- '%s' %p %d\n", x.name, x.st.type, x.st.size); diff --git a/src/tests/utests/run_qemu_test.sh b/src/tests/utests/run_qemu_test.sh index 68cf498..ea5166e 100755 --- a/src/tests/utests/run_qemu_test.sh +++ b/src/tests/utests/run_qemu_test.sh @@ -9,7 +9,7 @@ if [ $1 = 'watchdog' ]; then exit 0 fi -(qemu-system-i386 -kernel ../../../kernel/kernel.bin -initrd init.bin -serial stdio -m 16 -display none & echo $! >pid & +(qemu-system-i386 -kernel ../../../kernel/kernel.bin -append 'init=io:/mod/init.bin' -initrd init.bin -serial stdio -m 16 -display none & echo $! >pid & $0 watchdog) \ | tee >(grep -m 1 "TEST-" >result; kill -INT `cat pid`; kill -TERM `cat pid2`) \ -- cgit v1.2.3