From 3bb7d4e67b3e48bb88deebaeb8be792e660749b6 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 7 Apr 2014 12:34:41 +0200 Subject: [PATCH] noux: Decouple Dir_file_system from file systems By introducing the new 'File_system_registry', we can remove the knowledge about the actual file-system implementations from the 'Dir_file_system'. Thereby the code becomes more generic, which is a precondition for using it as the basis for Genode's VFS library. Issue #999 --- ports/src/noux/block_file_system.h | 2 +- ports/src/noux/dataspace_registry.h | 1 + ports/src/noux/dir_file_system.h | 86 +++++---------------------- ports/src/noux/file_system.h | 7 --- ports/src/noux/file_system_registry.h | 55 +++++++++++++++++ ports/src/noux/fs_file_system.h | 2 +- ports/src/noux/main.cc | 41 ++++++++++++- ports/src/noux/null_file_system.h | 4 +- ports/src/noux/random_file_system.h | 6 +- ports/src/noux/stdio_file_system.h | 2 +- ports/src/noux/tar_file_system.h | 2 +- ports/src/noux/terminal_file_system.h | 2 +- ports/src/noux/zero_file_system.h | 4 +- 13 files changed, 124 insertions(+), 90 deletions(-) create mode 100644 ports/src/noux/file_system_registry.h diff --git a/ports/src/noux/block_file_system.h b/ports/src/noux/block_file_system.h index f2da91ced..8a7915689 100644 --- a/ports/src/noux/block_file_system.h +++ b/ports/src/noux/block_file_system.h @@ -271,7 +271,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "block"; } + static char const *name() { return "block"; } /******************************** diff --git a/ports/src/noux/dataspace_registry.h b/ports/src/noux/dataspace_registry.h index 38798d2ae..b82f82b2a 100644 --- a/ports/src/noux/dataspace_registry.h +++ b/ports/src/noux/dataspace_registry.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include namespace Noux { diff --git a/ports/src/noux/dir_file_system.h b/ports/src/noux/dir_file_system.h index b5b078f97..ebea72030 100644 --- a/ports/src/noux/dir_file_system.h +++ b/ports/src/noux/dir_file_system.h @@ -20,14 +20,8 @@ /* Noux includes */ #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include namespace Noux { @@ -69,7 +63,9 @@ namespace Noux { public: - Dir_file_system(Xml_node node) : _first_file_system(0) + Dir_file_system(Xml_node node, File_system_registry &fs_registry) + : + _first_file_system(0) { /* remember directory name */ if (node.has_type("fstab")) @@ -81,59 +77,22 @@ namespace Noux { Xml_node sub_node = node.sub_node(i); - if (sub_node.has_type("tar")) { - _append_file_system(new Tar_file_system(sub_node)); - continue; - } - - if (sub_node.has_type("fs")) { - _append_file_system(new Fs_file_system(sub_node)); - continue; - } - /* traverse into nodes */ if (sub_node.has_type("dir")) { - _append_file_system(new Dir_file_system(sub_node)); + _append_file_system(new Dir_file_system(sub_node, + fs_registry)); continue; } - if (sub_node.has_type("terminal")) { - _append_file_system(new Terminal_file_system(sub_node)); + File_system_registry::Entry *fs = fs_registry.lookup(sub_node); + if (fs) { + _append_file_system(fs->create(sub_node)); continue; } - if (sub_node.has_type("null")) { - _append_file_system(new Null_file_system()); - - continue; - } - - if (sub_node.has_type("zero")) { - _append_file_system(new Zero_file_system()); - - continue; - } - - if (sub_node.has_type("stdio")) { - _append_file_system(new Stdio_file_system(sub_node)); - continue; - } - - if (sub_node.has_type("random")) { - _append_file_system(new Random_file_system(0, 0)); - continue; - } - - if (sub_node.has_type("block")) { - _append_file_system(new Block_file_system(sub_node)); - continue; - } - - { - char type_name[64]; - sub_node.type_name(type_name, sizeof(type_name)); - PWRN("unknown fstab node type <%s>", type_name); - } + char type_name[64]; + sub_node.type_name(type_name, sizeof(type_name)); + PWRN("unknown fstab node type <%s>", type_name); } } @@ -660,26 +619,11 @@ namespace Noux { /** * Synchronize all file systems - * - * Only file system using the File_system_session interface are - * synchronized. */ void sync() { - for (File_system *fs = _first_file_system; fs; fs = fs->next) { - Fs_file_system *fs_fs = dynamic_cast(fs); - if (fs_fs) { - fs_fs->sync(); - continue; - } - - /* the directory might contain Fs_file_systems */ - Dir_file_system *dir_fs = dynamic_cast(fs); - if (dir_fs) { - dir_fs->sync(); - continue; - } - } + for (File_system *fs = _first_file_system; fs; fs = fs->next) + fs->sync(); } diff --git a/ports/src/noux/file_system.h b/ports/src/noux/file_system.h index 59ed17cb6..46a1a5461 100644 --- a/ports/src/noux/file_system.h +++ b/ports/src/noux/file_system.h @@ -36,13 +36,6 @@ namespace Noux { File_system() : next(0) { } - /** - * Return name of file system - * - * This function is used for debugging only. - */ - virtual char const *name() const = 0; - /** * Synchronize file system * diff --git a/ports/src/noux/file_system_registry.h b/ports/src/noux/file_system_registry.h new file mode 100644 index 000000000..75ad4cd82 --- /dev/null +++ b/ports/src/noux/file_system_registry.h @@ -0,0 +1,55 @@ +/* + * \brief Registry of file systems + * \author Norman Feske + * \date 2014-04-07 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _NOUX__FILE_SYSTEM_REGISTRY_H_ +#define _NOUX__FILE_SYSTEM_REGISTRY_H_ + +/* Noux includes */ +#include + +namespace Noux { + + class File_system_registry + { + public: + + struct Entry : List::Element + { + virtual File_system *create(Xml_node node) = 0; + + virtual bool matches(Xml_node node) = 0; + }; + + private: + + List _list; + + public: + + void insert(Entry &entry) + { + _list.insert(&entry); + } + + Entry *lookup(Xml_node node) + { + for (Entry *e = _list.first(); e; e = e->next()) + if (e->matches(node)) + return e; + + return 0; + } + }; +} + +#endif /* _NOUX__FILE_SYSTEM_REGISTRY_H_ */ diff --git a/ports/src/noux/fs_file_system.h b/ports/src/noux/fs_file_system.h index e2d94764d..135dee193 100644 --- a/ports/src/noux/fs_file_system.h +++ b/ports/src/noux/fs_file_system.h @@ -574,7 +574,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "fs"; } + static char const *name() { return "fs"; } void sync() { diff --git a/ports/src/noux/main.cc b/ports/src/noux/main.cc index 7c4adad59..662c51835 100644 --- a/ports/src/noux/main.cc +++ b/ports/src/noux/main.cc @@ -30,6 +30,17 @@ #include #include #include +#include + +/* supported file systems */ +#include +#include +#include +#include +#include +#include +#include +#include static const bool verbose_quota = false; @@ -993,6 +1004,23 @@ void *operator new (Genode::size_t size) { return Genode::env()->heap()->alloc(size); } +template +struct File_system_factory : Noux::File_system_registry::Entry +{ + Noux::File_system *create(Genode::Xml_node node) override + { + return new FILE_SYSTEM(node); + } + + bool matches(Genode::Xml_node node) override + { + char buf[100]; + node.type_name(buf, sizeof(buf)); + return node.has_type(FILE_SYSTEM::name()); + } +}; + + int main(int argc, char **argv) { using namespace Noux; @@ -1017,9 +1045,20 @@ int main(int argc, char **argv) verbose = config()->xml_node().attribute("verbose").has_value("yes"); } catch (Xml_node::Nonexistent_attribute) { } + /* register file systems */ + static File_system_registry fs_registry; + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + fs_registry.insert(*new File_system_factory()); + /* initialize virtual file system */ static Dir_file_system - root_dir(config()->xml_node().sub_node("fstab")); + root_dir(config()->xml_node().sub_node("fstab"), fs_registry); /* set user information */ try { diff --git a/ports/src/noux/null_file_system.h b/ports/src/noux/null_file_system.h index ec0098439..ad6ca8518 100644 --- a/ports/src/noux/null_file_system.h +++ b/ports/src/noux/null_file_system.h @@ -44,7 +44,7 @@ namespace Noux { public: - Null_file_system() { } + Null_file_system(Xml_node) { } /********************************* @@ -162,7 +162,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "null"; } + static char const *name() { return "null"; } /******************************** diff --git a/ports/src/noux/random_file_system.h b/ports/src/noux/random_file_system.h index 818b7c22d..c1a6067a8 100644 --- a/ports/src/noux/random_file_system.h +++ b/ports/src/noux/random_file_system.h @@ -250,8 +250,10 @@ namespace Noux { public: - Random_file_system(void *bytes, size_t nbytes) + Random_file_system(Xml_node node) { + void *bytes = 0; + size_t nbytes = 0; _arc4random = new (env()->heap()) Arc4random(bytes, nbytes); } @@ -376,7 +378,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "random"; } + static char const *name() { return "random"; } /******************************** diff --git a/ports/src/noux/stdio_file_system.h b/ports/src/noux/stdio_file_system.h index 74a4b4f19..9f3c1302c 100644 --- a/ports/src/noux/stdio_file_system.h +++ b/ports/src/noux/stdio_file_system.h @@ -179,7 +179,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "stdio"; } + static char const *name() { return "stdio"; } /******************************** diff --git a/ports/src/noux/tar_file_system.h b/ports/src/noux/tar_file_system.h index c35eef18d..36f29e322 100644 --- a/ports/src/noux/tar_file_system.h +++ b/ports/src/noux/tar_file_system.h @@ -606,7 +606,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "tar"; } + static char const *name() { return "tar"; } /******************************** diff --git a/ports/src/noux/terminal_file_system.h b/ports/src/noux/terminal_file_system.h index 378de17d3..d4e25baa9 100644 --- a/ports/src/noux/terminal_file_system.h +++ b/ports/src/noux/terminal_file_system.h @@ -190,7 +190,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "terminal"; } + static char const *name() { return "terminal"; } /******************************** diff --git a/ports/src/noux/zero_file_system.h b/ports/src/noux/zero_file_system.h index c3e748343..c5ab0eb4c 100644 --- a/ports/src/noux/zero_file_system.h +++ b/ports/src/noux/zero_file_system.h @@ -44,7 +44,7 @@ namespace Noux { public: - Zero_file_system() { } + Zero_file_system(Xml_node) { } /********************************* @@ -162,7 +162,7 @@ namespace Noux { ** File_system interface ** ***************************/ - char const *name() const { return "zero"; } + static char const *name() { return "zero"; } /********************************