File_system: replace per-handle signals with notification packets

Replace registration and signaling of per-handle signal capabilities
with CONTENT_CHANGED notification packets.

Fix #2397
This commit is contained in:
Emery Hemingway 2017-04-20 12:02:43 -05:00 committed by Christian Helmuth
parent 29b3fff5eb
commit 24a9537a27
13 changed files with 382 additions and 194 deletions

View File

@ -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<Session_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<Session_component>
char tmp[MAX_PATH_LEN];
try {
Session_policy policy(label);
Session_policy policy(label, _config.xml());
/* determine policy root offset */
try {

View File

@ -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();

View File

@ -8,36 +8,41 @@
#define _FILE_SYSTEM__LISTENER_H_
/* Genode includes */
#include <file_system_session/file_system_session.h>
#include <file_system_session/rpc_object.h>
#include <util/list.h>
#include <base/lock.h>
#include <base/signal.h>
namespace File_system {
typedef File_system::Session_rpc_object::Tx::Sink Sink;
class Listener : public Genode::List<Listener>::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; }
};
}

View File

@ -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);
}
};

View File

@ -112,11 +112,6 @@ class File_system::Session_client : public Genode::Rpc_client<Session>
call<Rpc_move>(from_dir, from_name, to_dir, to_name);
}
void sigh(Node_handle node, Genode::Signal_context_capability sigh) override
{
call<Rpc_sigh>(node, sigh);
}
void sync(Node_handle node) override
{
call<Rpc_sync>(node);

View File

@ -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_ */

View File

@ -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 {
<config>
<parent-provides>
<service name="CPU"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="IRQ"/>
<service name="LOG"/>
<service name="PD"/>
<service name="RAM"/>
<service name="RM"/>
<service name="ROM"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="ram_fs">
<resource name="RAM" quantum="10M"/>
<provides><service name="File_system"/></provides>
<config>
<policy label_prefix="rom_to_file" root="/" writeable="yes"/>
<policy label_prefix="fs_rom" root="/" writeable="no"/>
</config>
</start>
<start name="dynamic_rom">
<resource name="RAM" quantum="4M"/>
<provides><service name="ROM"/></provides>
<config verbose="yes">
<rom name="dynamic_rom">
<inline description="iteration 1">
<config iteration="1" />
</inline>
<sleep milliseconds="2000" />
<inline description="iteration 2">
<config iteration="2" />
</inline>
<sleep milliseconds="2000" />
<inline description="iteration 3">
<config iteration="3" />
</inline>
<sleep milliseconds="2000" />
<inline description="iteration 4">
<config iteration="4" />
</inline>
<sleep milliseconds="2000" />
</rom>
</config>
</start>
<start name="rom_to_file">
<resource name="RAM" quantum="2M"/>
<config rom="dynamic_rom"/>
<route>
<service name="ROM" label="dynamic_rom"> <child name="dynamic_rom"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="fs_rom">
<resource name="RAM" quantum="2M"/>
<provides><service name="ROM"/></provides>
</start>
<start name="rom_logger">
<resource name="RAM" quantum="1M"/>
<config rom="dynamic_rom"/>
<route>
<service name="ROM" label="dynamic_rom"> <child name="fs_rom"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</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

View File

@ -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);

View File

@ -16,6 +16,7 @@
#include <file_system_session/connection.h>
#include <file_system/util.h>
#include <os/path.h>
#include <base/attached_ram_dataspace.h>
#include <root/component.h>
#include <base/component.h>
#include <base/session_label.h>
@ -23,17 +24,29 @@
#include <base/heap.h>
#include <base/log.h>
using namespace Genode;
/*****************
** ROM service **
*****************/
namespace Fs_rom {
using namespace Genode;
struct Packet_handler;
class Rom_session_component;
class Rom_root;
typedef Genode::List<Rom_session_component> 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<Genode::Rom_session>
class Fs_rom::Rom_session_component :
public Genode::Rpc_object<Genode::Rom_session>, public Sessions::Element
{
private:
@ -59,6 +72,11 @@ class Rom_session_component : public Genode::Rpc_object<Genode::Rom_session>
*/
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<Genode::Rom_session>
/**
* 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<Rom_session_component> _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<Genode::Rom_session>
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<Genode::Rom_session>
/* 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<Genode::Rom_session>
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<Genode::Rom_session>
_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<Genode::Rom_session>
/* 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<Genode::Rom_session>
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<Genode::Rom_session>
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_session>
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<Genode::Rom_dataspace>(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<char>()+_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<Packet_handler>
{
Tx_source &source;
class Rom_root : public Genode::Root_component<Rom_session_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<Packet_handler>(
ep, *this, &Packet_handler::handle_packets),
source(source)
{ }
};
class Fs_rom::Rom_root : public Genode::Root_component<Fs_rom::Rom_session_component>
{
private:
@ -328,7 +402,9 @@ class Rom_root : public Genode::Root_component<Rom_session_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<Rom_session_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<Rom_session_component>
Genode::Root_component<Rom_session_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<Rom_session_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);
}

View File

@ -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

View File

@ -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();
}
};

View File

@ -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<Session_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_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

View File

@ -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.
*/