From 493b5a2cf072c1f183d4724c9c0cc7b63d4771ae Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Thu, 12 Feb 2015 18:34:39 +0100 Subject: kmain.c is kind of an example of how the VFS should be used from the outside... --- src/kernel/core/kmain.c | 31 ++++++++++++++++++------------- src/kernel/include/vfs.h | 25 ++++++++++++++++++------- 2 files changed, 36 insertions(+), 20 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index 9b1cd12..c9a9d13 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -240,18 +240,23 @@ void kernel_init_stage2(void* data) { // Create devfs register_nullfs_driver(); - fs_t *devfs_fs = make_fs("nullfs", 0, ""); - ASSERT(devfs_fs != 0); - nullfs_t *devfs = as_nullfs(devfs_fs); + fs_t *devfs = make_fs("nullfs", 0, "cd"); ASSERT(devfs != 0); + nullfs_t *devfs_n = as_nullfs(devfs); + ASSERT(devfs_n != 0); // Add kernel command line to devfs - dbg_printf("Kernel command line: '%s'\n", (char*)mbd->cmdline); - ASSERT(nullfs_add_ram_file(devfs, "/cmdline", - (void*)mbd->cmdline, strlen((char*)mbd->cmdline), - false, FM_READ)); + { + dbg_printf("Kernel command line: '%s'\n", (char*)mbd->cmdline); + size_t len = strlen((char*)mbd->cmdline); + fs_handle_t* cmdline = fs_open(devfs, "/cmdline", FM_WRITE | FM_CREATE); + ASSERT(cmdline != 0); + ASSERT(file_write(cmdline, 0, len, (char*)mbd->cmdline) == len); + unref_file(cmdline); + } // Populate devfs with files for kernel modules + ASSERT(fs_create(devfs, "/mod", FT_DIR)); multiboot_module_t *mods = (multiboot_module_t*)mbd->mods_addr; for (unsigned i = 0; i < mbd->mods_count; i++) { char* modname = (char*)mods[i].string; @@ -267,16 +272,16 @@ void kernel_init_stage2(void* data) { dbg_printf("Adding module 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, - false, - FM_READ | FM_MMAP)); + size_t len = mods[i].mod_end - mods[i].mod_start; + fs_handle_t* mod_f = fs_open(devfs, name, FM_WRITE | FM_CREATE); + ASSERT(mod_f != 0); + ASSERT(file_write(mod_f, 0, len, (char*)mods[i].mod_start) == len); + unref_file(mod_f); } // TEST : read /cmdline dbg_printf("Trying to read /cmdline... "); - fs_handle_t *f = fs_open(devfs_fs, "/cmdline", FM_READ); + fs_handle_t *f = fs_open(devfs, "/cmdline", FM_READ); ASSERT(f != 0); char buf[256]; size_t l = file_read(f, 0, 255, buf); diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index 6dbbe5d..4efd0a2 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -6,11 +6,12 @@ #include // common header // How to use : -// - when using a filesystem : never call the operations in fs_*_ops_t directly, use -// the functions defined bellow -// - when programming a filesystem : don't worry about allocating the fs_handle_t and fs_t, +// - When using a filesystem : never call the operations in fs_*_ops_t directly, use +// the functions defined bellow in section "public functions"; +// Users of the VFS should not manipulate directly fs_node_t items, only fs_t and fs_handle_t +// - When programming a filesystem : don't worry about allocating the fs_handle_t and fs_t, // it is done automatically -// - the three types defined below (filesystem, fs node, file handle) are reference-counters to +// - The three types defined below (filesystem, fs node, file handle) are reference-counters to // some data managed by the underlying filesystem. The following types are aliases to void*, // but are used to disambiguate the different types of void* : fs_handle_ptr, fs_node_ptr, fs_ptr @@ -18,6 +19,7 @@ typedef void* fs_handle_ptr; typedef void* fs_node_ptr; typedef void* fs_ptr; +// ------------------------------------------- // Structure defining a handle to an open file typedef struct { @@ -38,17 +40,22 @@ typedef struct fs_handle { int mode; } fs_handle_t; +// ------------------------------------------- // Structure defining a filesystem node // In the future this is where FS-level cache may be implemented : calls to dispose() are not // executed immediately when refcount falls to zero but only when we need to free memory +// Remarks : +// - fs_node_t not to be used in public interface +// - nodes keep a reference to their parent +struct fs_node; typedef struct { bool (*open)(fs_node_ptr n, int mode, fs_handle_t *s); // open current node bool (*stat)(fs_node_ptr n, stat_t *st); - bool (*walk)(fs_node_ptr n, const char* file, struct fs_node *n); + bool (*walk)(fs_node_ptr n, const char* file, struct fs_node *node_d); bool (*delete)(fs_node_ptr n); bool (*create)(fs_node_ptr n, const char* name, int type); // create sub-node in directory - int (*ioctl)(fs_node_ptr n, int command, void* data) + int (*ioctl)(fs_node_ptr n, int command, void* data); void (*dispose)(fs_node_ptr n); } fs_node_ops_t; @@ -62,6 +69,7 @@ typedef struct fs_node { fs_node_ptr data; } fs_node_t; +// ------------------------------------------- // Structure defining a filesystem typedef struct { @@ -79,6 +87,7 @@ typedef struct fs { fs_node_t root; } fs_t; +// ------------------------------------------- // Structure defining a filesystem driver typedef struct { @@ -86,7 +95,8 @@ typedef struct { bool (*detect)(fs_handle_t *source); } fs_driver_ops_t; -// Common functions +// ------------------------------------------- +// Public functions void register_fs_driver(const char* name, fs_driver_ops_t *ops); @@ -96,6 +106,7 @@ void ref_fs(fs_t *fs); void unref_fs(fs_t *fs); bool fs_delete(fs_t *fs, const char* file); +bool fs_create(fs_t *fs, const char* file, int type); bool fs_rename(fs_t *fs, const char* from, const char* to); bool fs_stat(fs_t *fs, const char* file, stat_t *st); int fs_ioctl(fs_t *fs, const char* file, int command, void* data); -- cgit v1.2.3