diff --git a/repos/dde_rump/src/server/rump_fs/main.cc b/repos/dde_rump/src/server/rump_fs/main.cc index 6009ad42b..cd62ab90a 100644 --- a/repos/dde_rump/src/server/rump_fs/main.cc +++ b/repos/dde_rump/src/server/rump_fs/main.cc @@ -61,12 +61,6 @@ class File_system::Session_component : public Session_rpc_object { void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); - seek_off_t const offset = packet.position(); - - if (!content || (packet.length() > packet.size())) { - packet.succeeded(false); - return; - } /* resulting length */ size_t res_length = 0; @@ -74,13 +68,22 @@ class File_system::Session_component : public Session_rpc_object switch (packet.operation()) { case Packet_descriptor::READ: - res_length = node.read((char *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.read((char *)content, length, packet.position()); break; case Packet_descriptor::WRITE: - res_length = node.write((char const *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.write((char const *)content, length, packet.position()); break; + case Packet_descriptor::CONTENT_CHANGED: + _handle_registry.register_notify(*tx_sink(), packet.handle()); + /* notify_listeners may bounce the packet back*/ + node.notify_listeners(); + /* otherwise defer acknowledgement of this packet */ + return; + case Packet_descriptor::READ_READY: /* not supported */ break; @@ -88,6 +91,7 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); + tx_sink()->acknowledge_packet(packet); } void _process_packet() @@ -103,12 +107,6 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } catch (Invalid_handle) { Genode::error("Invalid_handle"); } - - /* - * The 'acknowledge_packet' function cannot block because we - * checked for 'ready_to_ack' in '_process_packets'. - */ - tx_sink()->acknowledge_packet(packet); } /** @@ -353,11 +351,6 @@ class File_system::Session_component : public Session_rpc_object throw Permission_denied(); } - void sigh(Node_handle node_handle, Signal_context_capability sigh) override - { - _handle_registry.sigh(node_handle, sigh); - } - void sync(Node_handle) override { rump_sys_sync(); } }; @@ -367,6 +360,8 @@ class File_system::Root : public Root_component Genode::Env &_env; + Genode::Attached_rom_dataspace _config { _env, "config" }; + protected: Session_component *_create_session(const char *args) @@ -408,7 +403,7 @@ class File_system::Root : public Root_component char tmp[MAX_PATH_LEN]; try { - Session_policy policy(label); + Session_policy policy(label, _config.xml()); /* determine policy root offset */ try { diff --git a/repos/libports/src/server/fuse_fs/fuse_fs_main.cc b/repos/libports/src/server/fuse_fs/fuse_fs_main.cc index 3b65e3820..f3eb1768a 100644 --- a/repos/libports/src/server/fuse_fs/fuse_fs_main.cc +++ b/repos/libports/src/server/fuse_fs/fuse_fs_main.cc @@ -63,12 +63,6 @@ class File_system::Session_component : public Session_rpc_object { void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); - seek_off_t const offset = packet.position(); - - if (!content || (packet.length() > packet.size())) { - packet.succeeded(false); - return; - } /* resulting length */ size_t res_length = 0; @@ -76,17 +70,22 @@ class File_system::Session_component : public Session_rpc_object switch (packet.operation()) { case Packet_descriptor::READ: - res_length = node.read((char *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.read((char *)content, length, packet.position()); break; case Packet_descriptor::WRITE: - /* session is read-only */ - if (!_writeable) - break; - - res_length = node.write((char const *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.write((char const *)content, length, packet.position()); break; + case Packet_descriptor::CONTENT_CHANGED: + _handle_registry.register_notify(*tx_sink(), packet.handle()); + /* notify_listeners may bounce the packet back*/ + node.notify_listeners(); + /* otherwise defer acknowledgement of this packet */ + return; + case Packet_descriptor::READ_READY: /* not supported */ break; @@ -94,6 +93,7 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); + tx_sink()->acknowledge_packet(packet); } void _process_packet() @@ -110,12 +110,6 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } catch (Invalid_handle) { Genode::error("Invalid_handle"); } - - /* - * The 'acknowledge_packet' function cannot block because we - * checked for 'ready_to_ack' in '_process_packets'. - */ - tx_sink()->acknowledge_packet(packet); } /** @@ -397,11 +391,6 @@ class File_system::Session_component : public Session_rpc_object } } - void sigh(Node_handle node_handle, Signal_context_capability sigh) - { - _handle_registry.sigh(node_handle, sigh); - } - void sync(Node_handle) override { Fuse::sync_fs(); diff --git a/repos/os/include/file_system/listener.h b/repos/os/include/file_system/listener.h index 0719a2c4c..4e2486833 100644 --- a/repos/os/include/file_system/listener.h +++ b/repos/os/include/file_system/listener.h @@ -8,36 +8,41 @@ #define _FILE_SYSTEM__LISTENER_H_ /* Genode includes */ -#include +#include #include #include #include namespace File_system { + typedef File_system::Session_rpc_object::Tx::Sink Sink; + class Listener : public Genode::List::Element { + private: - Genode::Lock _lock; - Genode::Signal_context_capability _sigh; - bool _marked_as_updated; + Genode::Lock _lock; + Sink *_sink = nullptr; + Node_handle _handle; + bool _marked_as_updated; public: Listener() : _marked_as_updated(false) { } - Listener(Genode::Signal_context_capability sigh) - : _sigh(sigh), _marked_as_updated(false) { } + Listener(Sink &sink, Node_handle handle) + : _sink(&sink), _handle(handle), _marked_as_updated(false) { } void notify() { Genode::Lock::Guard guard(_lock); - if (_marked_as_updated && _sigh.valid()) - Genode::Signal_transmitter(_sigh).submit(); - - _marked_as_updated = false; + if (_marked_as_updated && _sink && _sink->ready_to_ack()) { + _sink->acknowledge_packet(Packet_descriptor( + _handle, Packet_descriptor::CONTENT_CHANGED)); + _marked_as_updated = false; + } } void mark_as_updated() @@ -47,7 +52,7 @@ namespace File_system { _marked_as_updated = true; } - bool valid() const { return _sigh.valid(); } + bool valid() const { return _sink != nullptr; } }; } diff --git a/repos/os/include/file_system/node_handle_registry.h b/repos/os/include/file_system/node_handle_registry.h index 88715c695..c79f584a5 100644 --- a/repos/os/include/file_system/node_handle_registry.h +++ b/repos/os/include/file_system/node_handle_registry.h @@ -182,7 +182,7 @@ namespace File_system { /** * Register signal handler to be notified of node changes */ - void sigh(Node_handle handle, Genode::Signal_context_capability sigh) + void register_notify(Sink &sink, Node_handle handle) { Genode::Lock::Guard guard(_lock); @@ -193,9 +193,6 @@ namespace File_system { if (!node) throw Invalid_handle(); - node->lock(); - Node_lock_guard node_lock_guard(node); - Listener &listener = _listeners[handle.value]; /* @@ -208,7 +205,7 @@ namespace File_system { /* * Register new handler */ - listener = Listener(sigh); + listener = Listener(sink, handle); node->add_listener(&listener); } }; diff --git a/repos/os/include/file_system_session/client.h b/repos/os/include/file_system_session/client.h index 1c79ba832..dbb2846c9 100644 --- a/repos/os/include/file_system_session/client.h +++ b/repos/os/include/file_system_session/client.h @@ -112,11 +112,6 @@ class File_system::Session_client : public Genode::Rpc_client call(from_dir, from_name, to_dir, to_name); } - void sigh(Node_handle node, Genode::Signal_context_capability sigh) override - { - call(node, sigh); - } - void sync(Node_handle node) override { call(node); diff --git a/repos/os/include/file_system_session/file_system_session.h b/repos/os/include/file_system_session/file_system_session.h index 956475b86..8fc9d29a2 100644 --- a/repos/os/include/file_system_session/file_system_session.h +++ b/repos/os/include/file_system_session/file_system_session.h @@ -119,7 +119,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor { public: - enum Opcode { READ, WRITE, READ_READY }; + enum Opcode { READ, WRITE, CONTENT_CHANGED, READ_READY }; private: @@ -158,6 +158,19 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor _position(position), _length(length), _success(false) { } + /** + * Constructor + * + * This constructor provided for sending server-side + * notification packets. + */ + Packet_descriptor(Node_handle handle, Opcode op) + : + Genode::Packet_descriptor(0, 0), + _handle(handle), _op(op), + _position(0), _length(0), _success(true) + { } + Node_handle handle() const { return _handle; } Opcode operation() const { return _op; } seek_off_t position() const { return _position; } @@ -351,11 +364,6 @@ struct File_system::Session : public Genode::Session virtual void move(Dir_handle, Name const &from, Dir_handle, Name const &to) = 0; - /** - * Register handler that should be notified on node changes - */ - virtual void sigh(Node_handle, Genode::Signal_context_capability sigh) = 0; - /** * Synchronize file system * @@ -406,14 +414,11 @@ struct File_system::Session : public Genode::Session GENODE_TYPE_LIST(Invalid_handle, Invalid_name, Lookup_failed, Permission_denied), Dir_handle, Name const &, Dir_handle, Name const &); - GENODE_RPC_THROW(Rpc_sigh, void, sigh, - GENODE_TYPE_LIST(Invalid_handle), - Node_handle, Genode::Signal_context_capability); GENODE_RPC(Rpc_sync, void, sync, Node_handle); GENODE_RPC_INTERFACE(Rpc_tx_cap, Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node, Rpc_close, Rpc_status, Rpc_control, Rpc_unlink, - Rpc_truncate, Rpc_move, Rpc_sigh, Rpc_sync); + Rpc_truncate, Rpc_move, Rpc_sync); }; #endif /* _INCLUDE__FILE_SYSTEM_SESSION__FILE_SYSTEM_SESSION_H_ */ diff --git a/repos/os/run/fs_rom_update.run b/repos/os/run/fs_rom_update.run new file mode 100644 index 000000000..71a07e777 --- /dev/null +++ b/repos/os/run/fs_rom_update.run @@ -0,0 +1,121 @@ +if {[have_spec arm]} { + assert_spec arm_v7 +} + +# +# Build +# +set build_components { + core init + app/rom_logger + app/rom_to_file + drivers/timer + server/dynamic_rom + server/fs_rom + server/ram_fs +} + +build $build_components + +create_boot_directory + +# +# Generate config +# +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# +# Boot modules +# + +# generic modules +set boot_modules { + core ld.lib.so init + dynamic_rom + fs_rom + ram_fs + rom_logger + rom_to_file + test-libc_vfs + timer +} + +build_boot_image $boot_modules + +append qemu_args " -m 256 -nographic" + +run_genode_until {.*child "test-libc_vfs" exited with exit value 0.*} 60 diff --git a/repos/os/src/lib/vfs/fs_file_system.h b/repos/os/src/lib/vfs/fs_file_system.h index 42c89ba6c..69d82e1e0 100644 --- a/repos/os/src/lib/vfs/fs_file_system.h +++ b/repos/os/src/lib/vfs/fs_file_system.h @@ -263,6 +263,9 @@ class Vfs::Fs_file_system : public File_system handle.queued_write_packet = packet; handle.queued_write_state = Handle_state::Queued_state::ACK; break; + + case Packet_descriptor::CONTENT_CHANGED: + break; } _post_signal_hook.arm(handle.context); diff --git a/repos/os/src/server/fs_rom/main.cc b/repos/os/src/server/fs_rom/main.cc index ace911b46..281d08c66 100755 --- a/repos/os/src/server/fs_rom/main.cc +++ b/repos/os/src/server/fs_rom/main.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,17 +24,29 @@ #include #include - -using namespace Genode; - /***************** ** ROM service ** *****************/ +namespace Fs_rom { + using namespace Genode; + + struct Packet_handler; + + class Rom_session_component; + class Rom_root; + + typedef Genode::List Sessions; + + typedef File_system::Session_client::Tx::Source Tx_source; +} + + /** * A 'Rom_session_component' exports a single file of the file system */ -class Rom_session_component : public Genode::Rpc_object +class Fs_rom::Rom_session_component : + public Genode::Rpc_object, public Sessions::Element { private: @@ -59,6 +72,11 @@ class Rom_session_component : public Genode::Rpc_object */ File_system::file_size_t _file_size = 0; + /** + * Read offset of the file + */ + File_system::seek_off_t _file_seek = 0; + /** * Handle of currently watched compound directory * @@ -70,36 +88,13 @@ class Rom_session_component : public Genode::Rpc_object /** * Dataspace exposed as ROM module to the client */ - Genode::Ram_dataspace_capability _file_ds; + Genode::Attached_ram_dataspace _file_ds; /** * Signal destination for ROM file changes */ Genode::Signal_context_capability _sigh; - /** - * Signal-handling function called by the main thread the compound - * directory changed. - */ - void _dir_changed() - { - Genode::log("detected directory change"); - if (_sigh.valid()) - Genode::Signal_transmitter(_sigh).submit(); - } - - /** - * Handler that is called each time when the requested file is not - * yet available and the compound directory changes - * - * The change of the compound directory bears the chance that the - * requested file re-appears. So we inform the client about a ROM - * module change and thereby give it a chance to call 'dataspace()' in - * response. - */ - Genode::Signal_handler _dir_change_handler - { _env.ep(), *this, &Rom_session_component::_dir_changed }; - /** * Open compound directory of specified file * @@ -162,12 +157,15 @@ class Rom_session_component : public Genode::Rpc_object catch (Invalid_handle) { Genode::error(_file_path, ": Invalid_handle"); } catch (Invalid_name) { Genode::error(_file_path, ": invalid_name"); } catch (Lookup_failed) { Genode::error(_file_path, ": lookup_failed"); } + catch (...) { Genode::error(_file_path, ": unhandled error"); }; return file_handle; } void _register_for_compound_dir_changes() { + using namespace File_system; + /* forget about the previously watched compound directory */ if (_compound_dir_handle.valid()) _fs.close(_compound_dir_handle); @@ -176,7 +174,9 @@ class Rom_session_component : public Genode::Rpc_object /* register for changes in compound directory */ if (_compound_dir_handle.valid()) - _fs.sigh(_compound_dir_handle, _dir_change_handler); + _fs.tx()->submit_packet(File_system::Packet_descriptor( + _compound_dir_handle, + File_system::Packet_descriptor::CONTENT_CHANGED)); else Genode::warning("could not track compound dir, giving up"); } @@ -200,12 +200,11 @@ class Rom_session_component : public Genode::Rpc_object File_system::file_size_t const new_file_size = _fs.status(file_handle).size; - if (_file_ds.valid() && (new_file_size > _file_size)) { - _env.ram().free(_file_ds); - + if (_file_ds.size() && (new_file_size > _file_size)) { /* mark as invalid */ - _file_ds = Ram_dataspace_capability(); + _file_ds.realloc(&_env.ram(), 0); _file_size = 0; + _file_seek = 0; } } _fs.close(file_handle); @@ -225,8 +224,9 @@ class Rom_session_component : public Genode::Rpc_object _fs.close(_compound_dir_handle); /* register for file changes */ - if (_sigh.valid() && _file_handle.valid()) - _fs.sigh(_file_handle, _sigh); + if (_file_handle.valid()) + _fs.tx()->submit_packet(File_system::Packet_descriptor( + _file_handle, File_system::Packet_descriptor::CONTENT_CHANGED)); size_t const file_size = _file_handle.valid() ? _fs.status(_file_handle).size : 0; @@ -234,30 +234,37 @@ class Rom_session_component : public Genode::Rpc_object /* allocate new RAM dataspace according to file size */ if (file_size > 0) { try { - if (!_file_ds.valid()) { - _file_ds = _env.ram().alloc(file_size); - _file_size = file_size; - } + _file_seek = 0; + _file_ds.realloc(&_env.ram(), file_size); + _file_size = file_size; } catch (...) { - Genode::error("couldn't allocate memory for file, empty result"); - _file_ds = Ram_dataspace_capability(); + Genode::error("couldn't allocate memory for file, empty result");; return; } - } - - if (!_file_ds.valid()) { + } else { _register_for_compound_dir_changes(); return; } - /* map dataspace locally */ - void * const dst_addr = _env.rm().attach(_file_ds); - /* read content from file */ - read(_fs, _file_handle, dst_addr, file_size); + Tx_source &source = *_fs.tx(); + while (_file_seek < _file_size) { + /* if we cannot submit then process acknowledgements */ + if (source.ready_to_submit()) { + size_t chunk_size = min(_file_size - _file_seek, + source.bulk_buffer_size() / 2); + File_system::Packet_descriptor + packet(source.alloc_packet(chunk_size), + _file_handle, + File_system::Packet_descriptor::READ, + chunk_size, + _file_seek); + source.submit_packet(packet); + } - /* unmap dataspace */ - _env.rm().detach(dst_addr); + /* process ack at the global signal handler */ + _env.ep().wait_and_dispatch_one_io_signal(); + } } public: @@ -275,8 +282,10 @@ class Rom_session_component : public Genode::Rpc_object Rom_session_component(Genode::Env &env, File_system::Session &fs, const char *file_path) : - _env(env), _fs(fs), _file_path(file_path), - _file_handle(_open_file(_fs, _file_path)) + _env(env), _fs(fs), + _file_path(file_path), + _file_handle(_open_file(_fs, _file_path)), + _file_ds(env.ram(), env.rm(), 0) /* realloc later */ { if (!_file_handle.valid()) _register_for_compound_dir_changes(); @@ -293,9 +302,6 @@ class Rom_session_component : public Genode::Rpc_object if (_compound_dir_handle.valid()) _fs.close(_compound_dir_handle); - - /* close file */ - _env.ram().free(_file_ds); } /** @@ -304,20 +310,88 @@ class Rom_session_component : public Genode::Rpc_object Genode::Rom_dataspace_capability dataspace() { _update_dataspace(); - Genode::Dataspace_capability ds = _file_ds; + Genode::Dataspace_capability ds = _file_ds.cap(); return Genode::static_cap_cast(ds); } - void sigh(Genode::Signal_context_capability sigh) + void sigh(Genode::Signal_context_capability sigh) { + _sigh = sigh; } + + /** + * If packet corresponds to this session then process and return true. + * + * Called from the signal handler. + */ + bool process_packet(File_system::Packet_descriptor const packet) { - _sigh = sigh; - if (_file_handle.valid()) - _fs.sigh(_file_handle, _sigh); + switch (packet.operation()) { + + case File_system::Packet_descriptor::CONTENT_CHANGED: + if (_file_handle == packet.handle() || + _compound_dir_handle == packet.handle()) + { + if (_sigh.valid()) + Genode::Signal_transmitter(_sigh).submit(); + return true; + } + return false; + + case File_system::Packet_descriptor::READ: { + if (_file_handle != packet.handle()) + return false; + + if (packet.position() > _file_seek || _file_seek >= _file_size) { + error("bad packet seek position"); + _file_ds.realloc(&_env.ram(), 0); + return true; + } + + size_t const n = min(packet.length(), _file_size - _file_seek); + memcpy(_file_ds.local_addr()+_file_seek, + _fs.tx()->packet_content(packet), n); + _file_seek += n; + return true; + } + + default: + Genode::error("discarding strange packet acknowledgement"); + return true; + } + return false; } }; +struct Fs_rom::Packet_handler : Genode::Io_signal_handler +{ + Tx_source &source; -class Rom_root : public Genode::Root_component + /* list of open sessions */ + Sessions sessions; + + void handle_packets() + { + while (source.ack_avail()) { + File_system::Packet_descriptor pack = source.get_acked_packet(); + for (Rom_session_component *session = sessions.first(); + session; session = session->next()) + { + if (session->process_packet(pack)) + break; + } + source.release_packet(pack); + } + } + + Packet_handler(Genode::Entrypoint &ep, Tx_source &source) + : + Genode::Io_signal_handler( + ep, *this, &Packet_handler::handle_packets), + source(source) + { } +}; + + +class Fs_rom::Rom_root : public Genode::Root_component { private: @@ -328,7 +402,9 @@ class Rom_root : public Genode::Root_component /* open file-system session */ File_system::Connection _fs { _env, _fs_tx_block_alloc }; - Rom_session_component *_create_session(const char *args) + Packet_handler _packet_handler { _env.ep(), *_fs.tx() }; + + Rom_session_component *_create_session(const char *args) override { Genode::Session_label const label = label_from_args(args); Genode::Session_label const module_name = label.last_element(); @@ -336,8 +412,17 @@ class Rom_root : public Genode::Root_component Genode::log("request for ", label); /* create new session for the requested file */ - return new (md_alloc()) + Rom_session_component *session = new (md_alloc()) Rom_session_component(_env, _fs, module_name.string()); + + _packet_handler.sessions.insert(session); + return session; + } + + void _destroy_session(Rom_session_component *session) override + { + _packet_handler.sessions.remove(session); + Genode::destroy(md_alloc(), session); } public: @@ -354,6 +439,9 @@ class Rom_root : public Genode::Root_component Genode::Root_component(env.ep(), md_alloc), _env(env) { + /* Process CONTENT_CHANGED acknowledgement packets at the entrypoint */ + _fs.sigh_ack_avail(_packet_handler); + env.parent().announce(env.ep().manage(*this)); } }; @@ -361,6 +449,6 @@ class Rom_root : public Genode::Root_component void Component::construct(Genode::Env &env) { - static Sliced_heap sliced_heap(env.ram(), env.rm()); - static Rom_root inst(env, sliced_heap); + static Genode::Sliced_heap sliced_heap(env.ram(), env.rm()); + static Fs_rom::Rom_root inst(env, sliced_heap); } diff --git a/repos/os/src/server/lx_fs/main.cc b/repos/os/src/server/lx_fs/main.cc index 483ac1f6f..c5f4fdf4a 100644 --- a/repos/os/src/server/lx_fs/main.cc +++ b/repos/os/src/server/lx_fs/main.cc @@ -58,12 +58,6 @@ class File_system::Session_component : public Session_rpc_object { void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); - seek_off_t const offset = packet.position(); - - if (!content || (packet.length() > packet.size())) { - packet.succeeded(false); - return; - } /* resulting length */ size_t res_length = 0; @@ -71,13 +65,22 @@ class File_system::Session_component : public Session_rpc_object switch (packet.operation()) { case Packet_descriptor::READ: - res_length = node.read((char *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.read((char *)content, length, packet.position()); break; case Packet_descriptor::WRITE: - res_length = node.write((char const *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.write((char const *)content, length, packet.position()); break; + case Packet_descriptor::CONTENT_CHANGED: + _handle_registry.register_notify(*tx_sink(), packet.handle()); + /* notify_listeners may bounce the packet back*/ + node.notify_listeners(); + /* otherwise defer acknowledgement of this packet */ + return; + case Packet_descriptor::READ_READY: /* not supported */ break; @@ -85,6 +88,7 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); + tx_sink()->acknowledge_packet(packet); } void _process_packet() @@ -101,12 +105,6 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } catch (Invalid_handle) { Genode::error("Invalid_handle"); } - - /* - * The 'acknowledge_packet' function cannot block because we - * checked for 'ready_to_ack' in '_process_packets'. - */ - tx_sink()->acknowledge_packet(packet); } /** @@ -304,11 +302,6 @@ class File_system::Session_component : public Session_rpc_object Genode::error(__func__, " not implemented"); } - void sigh(Node_handle node_handle, Signal_context_capability sigh) - { - _handle_registry.sigh(node_handle, sigh); - } - /** * We could call sync(2) here but for now we forward just the * reminder because besides testing, there is currently no diff --git a/repos/os/src/server/ram_fs/main.cc b/repos/os/src/server/ram_fs/main.cc index 653d363be..af2e7d5e3 100644 --- a/repos/os/src/server/ram_fs/main.cc +++ b/repos/os/src/server/ram_fs/main.cc @@ -63,12 +63,6 @@ class File_system::Session_component : public Session_rpc_object { void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); - seek_off_t const offset = packet.position(); - - if (!content || (packet.length() > packet.size())) { - packet.succeeded(false); - return; - } /* resulting length */ size_t res_length = 0; @@ -76,13 +70,20 @@ class File_system::Session_component : public Session_rpc_object switch (packet.operation()) { case Packet_descriptor::READ: - res_length = node.read((char *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.read((char *)content, length, packet.position()); break; case Packet_descriptor::WRITE: - res_length = node.write((char const *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.write((char const *)content, length, packet.position()); break; + case Packet_descriptor::CONTENT_CHANGED: + _handle_registry.register_notify(*tx_sink(), packet.handle()); + node.notify_listeners(); + return; + case Packet_descriptor::READ_READY: /* not supported */ break; @@ -90,6 +91,7 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); + tx_sink()->acknowledge_packet(packet); } void _process_packet() @@ -106,12 +108,6 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } catch (Invalid_handle) { Genode::error("Invalid_handle"); } - - /* - * The 'acknowledge_packet' function cannot block because we - * checked for 'ready_to_ack' in '_process_packets'. - */ - tx_sink()->acknowledge_packet(packet); } void _process_packets() @@ -414,9 +410,11 @@ class File_system::Session_component : public Session_rpc_object node->notify_listeners(); } - void sigh(Node_handle node_handle, Signal_context_capability sigh) + void sync(Node_handle handle) override { - _handle_registry.sigh(node_handle, sigh); + Node *node = _handle_registry.lookup_and_lock(handle); + Node_lock_guard guard(node); + node->notify_listeners(); } }; diff --git a/repos/os/src/server/trace_fs/main.cc b/repos/os/src/server/trace_fs/main.cc index 1b08e67e6..e75c886d1 100644 --- a/repos/os/src/server/trace_fs/main.cc +++ b/repos/os/src/server/trace_fs/main.cc @@ -647,12 +647,6 @@ class File_system::Session_component : public Session_rpc_object { void * const content = tx_sink()->packet_content(packet); size_t const length = packet.length(); - seek_off_t const offset = packet.position(); - - if (!content || (packet.length() > packet.size())) { - packet.succeeded(false); - return; - } /* resulting length */ size_t res_length = 0; @@ -660,13 +654,22 @@ class File_system::Session_component : public Session_rpc_object switch (packet.operation()) { case Packet_descriptor::READ: - res_length = node.read((char *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.read((char *)content, length, packet.position()); break; case Packet_descriptor::WRITE: - res_length = node.write((char const *)content, length, offset); + if (content && (packet.length() <= packet.size())) + res_length = node.write((char const *)content, length, packet.position()); break; + case Packet_descriptor::CONTENT_CHANGED: + _handle_registry.register_notify(*tx_sink(), packet.handle()); + /* notify_listeners may bounce the packet back*/ + node.notify_listeners(); + /* otherwise defer acknowledgement of this packet */ + return; + case Packet_descriptor::READ_READY: /* not supported */ break; @@ -674,6 +677,7 @@ class File_system::Session_component : public Session_rpc_object packet.length(res_length); packet.succeeded(res_length > 0); + tx_sink()->acknowledge_packet(packet); } void _process_packet() @@ -689,12 +693,6 @@ class File_system::Session_component : public Session_rpc_object _process_packet_op(packet, *node); } catch (Invalid_handle) { Genode::error("Invalid_handle"); } - - /* - * The 'acknowledge_packet' function cannot block because we - * checked for 'ready_to_ack' in '_process_packets'. - */ - tx_sink()->acknowledge_packet(packet); } /** @@ -904,9 +902,6 @@ class File_system::Session_component : public Session_rpc_object } void move(Dir_handle, Name const &, Dir_handle, Name const &) { } - - void sigh(Node_handle node_handle, Signal_context_capability sigh) { - _handle_registry.sigh(node_handle, sigh); } }; @@ -921,6 +916,8 @@ class File_system::Root : public Root_component Directory &_root_dir; + Genode::Attached_rom_dataspace _config { _env, "config" }; + protected: Session_component *_create_session(const char *args) @@ -946,7 +943,7 @@ class File_system::Root : public Root_component Session_label const label = label_from_args(args); try { - Session_policy policy(label); + Session_policy policy(label, _config.xml()); /* * Override default settings with specific session settings by diff --git a/repos/os/src/server/vfs/main.cc b/repos/os/src/server/vfs/main.cc index 2eee9ac5d..66bcdc2b4 100644 --- a/repos/os/src/server/vfs/main.cc +++ b/repos/os/src/server/vfs/main.cc @@ -192,6 +192,10 @@ class Vfs_server::Session_component : public File_system::Session_rpc_object, catch (Dont_ack) { throw; } catch (...) { } break; + + case Packet_descriptor::CONTENT_CHANGED: + /* The VFS does not track file changes yet */ + throw Dont_ack(); } packet.length(res_length); @@ -570,8 +574,6 @@ class Vfs_server::Session_component : public File_system::Session_rpc_object, }); } - void sigh(Node_handle handle, Signal_context_capability sigh) override { } - /** * Sync the VFS and send any pending signals on the node. */