mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
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:
parent
29b3fff5eb
commit
24a9537a27
@ -61,12 +61,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
void * const content = tx_sink()->packet_content(packet);
|
void * const content = tx_sink()->packet_content(packet);
|
||||||
size_t const length = packet.length();
|
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 */
|
/* resulting length */
|
||||||
size_t res_length = 0;
|
size_t res_length = 0;
|
||||||
@ -74,13 +68,22 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
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;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
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;
|
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:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -88,6 +91,7 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
|
tx_sink()->acknowledge_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _process_packet()
|
void _process_packet()
|
||||||
@ -103,12 +107,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
_process_packet_op(packet, *node);
|
_process_packet_op(packet, *node);
|
||||||
}
|
}
|
||||||
catch (Invalid_handle) { Genode::error("Invalid_handle"); }
|
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();
|
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(); }
|
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::Env &_env;
|
||||||
|
|
||||||
|
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args)
|
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];
|
char tmp[MAX_PATH_LEN];
|
||||||
try {
|
try {
|
||||||
Session_policy policy(label);
|
Session_policy policy(label, _config.xml());
|
||||||
|
|
||||||
/* determine policy root offset */
|
/* determine policy root offset */
|
||||||
try {
|
try {
|
||||||
|
@ -63,12 +63,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
void * const content = tx_sink()->packet_content(packet);
|
void * const content = tx_sink()->packet_content(packet);
|
||||||
size_t const length = packet.length();
|
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 */
|
/* resulting length */
|
||||||
size_t res_length = 0;
|
size_t res_length = 0;
|
||||||
@ -76,17 +70,22 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
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;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
case Packet_descriptor::WRITE:
|
||||||
/* session is read-only */
|
if (content && (packet.length() <= packet.size()))
|
||||||
if (!_writeable)
|
res_length = node.write((char const *)content, length, packet.position());
|
||||||
break;
|
|
||||||
|
|
||||||
res_length = node.write((char const *)content, length, offset);
|
|
||||||
break;
|
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:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -94,6 +93,7 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
|
tx_sink()->acknowledge_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _process_packet()
|
void _process_packet()
|
||||||
@ -110,12 +110,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
_process_packet_op(packet, *node);
|
_process_packet_op(packet, *node);
|
||||||
}
|
}
|
||||||
catch (Invalid_handle) { Genode::error("Invalid_handle"); }
|
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
|
void sync(Node_handle) override
|
||||||
{
|
{
|
||||||
Fuse::sync_fs();
|
Fuse::sync_fs();
|
||||||
|
@ -8,36 +8,41 @@
|
|||||||
#define _FILE_SYSTEM__LISTENER_H_
|
#define _FILE_SYSTEM__LISTENER_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <file_system_session/file_system_session.h>
|
#include <file_system_session/rpc_object.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <base/lock.h>
|
#include <base/lock.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
|
|
||||||
namespace File_system {
|
namespace File_system {
|
||||||
|
|
||||||
|
typedef File_system::Session_rpc_object::Tx::Sink Sink;
|
||||||
|
|
||||||
class Listener : public Genode::List<Listener>::Element
|
class Listener : public Genode::List<Listener>::Element
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Lock _lock;
|
Genode::Lock _lock;
|
||||||
Genode::Signal_context_capability _sigh;
|
Sink *_sink = nullptr;
|
||||||
bool _marked_as_updated;
|
Node_handle _handle;
|
||||||
|
bool _marked_as_updated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Listener() : _marked_as_updated(false) { }
|
Listener() : _marked_as_updated(false) { }
|
||||||
|
|
||||||
Listener(Genode::Signal_context_capability sigh)
|
Listener(Sink &sink, Node_handle handle)
|
||||||
: _sigh(sigh), _marked_as_updated(false) { }
|
: _sink(&sink), _handle(handle), _marked_as_updated(false) { }
|
||||||
|
|
||||||
void notify()
|
void notify()
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard guard(_lock);
|
Genode::Lock::Guard guard(_lock);
|
||||||
|
|
||||||
if (_marked_as_updated && _sigh.valid())
|
if (_marked_as_updated && _sink && _sink->ready_to_ack()) {
|
||||||
Genode::Signal_transmitter(_sigh).submit();
|
_sink->acknowledge_packet(Packet_descriptor(
|
||||||
|
_handle, Packet_descriptor::CONTENT_CHANGED));
|
||||||
_marked_as_updated = false;
|
_marked_as_updated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_as_updated()
|
void mark_as_updated()
|
||||||
@ -47,7 +52,7 @@ namespace File_system {
|
|||||||
_marked_as_updated = true;
|
_marked_as_updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid() const { return _sigh.valid(); }
|
bool valid() const { return _sink != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ namespace File_system {
|
|||||||
/**
|
/**
|
||||||
* Register signal handler to be notified of node changes
|
* 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);
|
Genode::Lock::Guard guard(_lock);
|
||||||
|
|
||||||
@ -193,9 +193,6 @@ namespace File_system {
|
|||||||
if (!node)
|
if (!node)
|
||||||
throw Invalid_handle();
|
throw Invalid_handle();
|
||||||
|
|
||||||
node->lock();
|
|
||||||
Node_lock_guard node_lock_guard(node);
|
|
||||||
|
|
||||||
Listener &listener = _listeners[handle.value];
|
Listener &listener = _listeners[handle.value];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -208,7 +205,7 @@ namespace File_system {
|
|||||||
/*
|
/*
|
||||||
* Register new handler
|
* Register new handler
|
||||||
*/
|
*/
|
||||||
listener = Listener(sigh);
|
listener = Listener(sink, handle);
|
||||||
node->add_listener(&listener);
|
node->add_listener(&listener);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
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
|
void sync(Node_handle node) override
|
||||||
{
|
{
|
||||||
call<Rpc_sync>(node);
|
call<Rpc_sync>(node);
|
||||||
|
@ -119,7 +119,7 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum Opcode { READ, WRITE, READ_READY };
|
enum Opcode { READ, WRITE, CONTENT_CHANGED, READ_READY };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -158,6 +158,19 @@ class File_system::Packet_descriptor : public Genode::Packet_descriptor
|
|||||||
_position(position), _length(length), _success(false)
|
_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; }
|
Node_handle handle() const { return _handle; }
|
||||||
Opcode operation() const { return _op; }
|
Opcode operation() const { return _op; }
|
||||||
seek_off_t position() const { return _position; }
|
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,
|
virtual void move(Dir_handle, Name const &from,
|
||||||
Dir_handle, Name const &to) = 0;
|
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
|
* Synchronize file system
|
||||||
*
|
*
|
||||||
@ -406,14 +414,11 @@ struct File_system::Session : public Genode::Session
|
|||||||
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
GENODE_TYPE_LIST(Invalid_handle, Invalid_name,
|
||||||
Lookup_failed, Permission_denied),
|
Lookup_failed, Permission_denied),
|
||||||
Dir_handle, Name const &, Dir_handle, Name const &);
|
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(Rpc_sync, void, sync, Node_handle);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_tx_cap, Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node,
|
GENODE_RPC_INTERFACE(Rpc_tx_cap, Rpc_file, Rpc_symlink, Rpc_dir, Rpc_node,
|
||||||
Rpc_close, Rpc_status, Rpc_control, Rpc_unlink,
|
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_ */
|
#endif /* _INCLUDE__FILE_SYSTEM_SESSION__FILE_SYSTEM_SESSION_H_ */
|
||||||
|
121
repos/os/run/fs_rom_update.run
Normal file
121
repos/os/run/fs_rom_update.run
Normal 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
|
@ -263,6 +263,9 @@ class Vfs::Fs_file_system : public File_system
|
|||||||
handle.queued_write_packet = packet;
|
handle.queued_write_packet = packet;
|
||||||
handle.queued_write_state = Handle_state::Queued_state::ACK;
|
handle.queued_write_state = Handle_state::Queued_state::ACK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Packet_descriptor::CONTENT_CHANGED:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_post_signal_hook.arm(handle.context);
|
_post_signal_hook.arm(handle.context);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <file_system_session/connection.h>
|
#include <file_system_session/connection.h>
|
||||||
#include <file_system/util.h>
|
#include <file_system/util.h>
|
||||||
#include <os/path.h>
|
#include <os/path.h>
|
||||||
|
#include <base/attached_ram_dataspace.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <base/component.h>
|
#include <base/component.h>
|
||||||
#include <base/session_label.h>
|
#include <base/session_label.h>
|
||||||
@ -23,17 +24,29 @@
|
|||||||
#include <base/heap.h>
|
#include <base/heap.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
** ROM service **
|
** 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
|
* 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:
|
private:
|
||||||
|
|
||||||
@ -59,6 +72,11 @@ class Rom_session_component : public Genode::Rpc_object<Genode::Rom_session>
|
|||||||
*/
|
*/
|
||||||
File_system::file_size_t _file_size = 0;
|
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
|
* 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
|
* 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
|
* Signal destination for ROM file changes
|
||||||
*/
|
*/
|
||||||
Genode::Signal_context_capability _sigh;
|
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
|
* 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_handle) { Genode::error(_file_path, ": Invalid_handle"); }
|
||||||
catch (Invalid_name) { Genode::error(_file_path, ": invalid_name"); }
|
catch (Invalid_name) { Genode::error(_file_path, ": invalid_name"); }
|
||||||
catch (Lookup_failed) { Genode::error(_file_path, ": lookup_failed"); }
|
catch (Lookup_failed) { Genode::error(_file_path, ": lookup_failed"); }
|
||||||
|
catch (...) { Genode::error(_file_path, ": unhandled error"); };
|
||||||
|
|
||||||
return file_handle;
|
return file_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _register_for_compound_dir_changes()
|
void _register_for_compound_dir_changes()
|
||||||
{
|
{
|
||||||
|
using namespace File_system;
|
||||||
|
|
||||||
/* forget about the previously watched compound directory */
|
/* forget about the previously watched compound directory */
|
||||||
if (_compound_dir_handle.valid())
|
if (_compound_dir_handle.valid())
|
||||||
_fs.close(_compound_dir_handle);
|
_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 */
|
/* register for changes in compound directory */
|
||||||
if (_compound_dir_handle.valid())
|
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
|
else
|
||||||
Genode::warning("could not track compound dir, giving up");
|
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 =
|
File_system::file_size_t const new_file_size =
|
||||||
_fs.status(file_handle).size;
|
_fs.status(file_handle).size;
|
||||||
|
|
||||||
if (_file_ds.valid() && (new_file_size > _file_size)) {
|
if (_file_ds.size() && (new_file_size > _file_size)) {
|
||||||
_env.ram().free(_file_ds);
|
|
||||||
|
|
||||||
/* mark as invalid */
|
/* mark as invalid */
|
||||||
_file_ds = Ram_dataspace_capability();
|
_file_ds.realloc(&_env.ram(), 0);
|
||||||
_file_size = 0;
|
_file_size = 0;
|
||||||
|
_file_seek = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_fs.close(file_handle);
|
_fs.close(file_handle);
|
||||||
@ -225,8 +224,9 @@ class Rom_session_component : public Genode::Rpc_object<Genode::Rom_session>
|
|||||||
_fs.close(_compound_dir_handle);
|
_fs.close(_compound_dir_handle);
|
||||||
|
|
||||||
/* register for file changes */
|
/* register for file changes */
|
||||||
if (_sigh.valid() && _file_handle.valid())
|
if (_file_handle.valid())
|
||||||
_fs.sigh(_file_handle, _sigh);
|
_fs.tx()->submit_packet(File_system::Packet_descriptor(
|
||||||
|
_file_handle, File_system::Packet_descriptor::CONTENT_CHANGED));
|
||||||
|
|
||||||
size_t const file_size = _file_handle.valid()
|
size_t const file_size = _file_handle.valid()
|
||||||
? _fs.status(_file_handle).size : 0;
|
? _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 */
|
/* allocate new RAM dataspace according to file size */
|
||||||
if (file_size > 0) {
|
if (file_size > 0) {
|
||||||
try {
|
try {
|
||||||
if (!_file_ds.valid()) {
|
_file_seek = 0;
|
||||||
_file_ds = _env.ram().alloc(file_size);
|
_file_ds.realloc(&_env.ram(), file_size);
|
||||||
_file_size = file_size;
|
_file_size = file_size;
|
||||||
}
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Genode::error("couldn't allocate memory for file, empty result");
|
Genode::error("couldn't allocate memory for file, empty result");;
|
||||||
_file_ds = Ram_dataspace_capability();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (!_file_ds.valid()) {
|
|
||||||
_register_for_compound_dir_changes();
|
_register_for_compound_dir_changes();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map dataspace locally */
|
|
||||||
void * const dst_addr = _env.rm().attach(_file_ds);
|
|
||||||
|
|
||||||
/* read content from file */
|
/* 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 */
|
/* process ack at the global signal handler */
|
||||||
_env.rm().detach(dst_addr);
|
_env.ep().wait_and_dispatch_one_io_signal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -275,8 +282,10 @@ class Rom_session_component : public Genode::Rpc_object<Genode::Rom_session>
|
|||||||
Rom_session_component(Genode::Env &env,
|
Rom_session_component(Genode::Env &env,
|
||||||
File_system::Session &fs, const char *file_path)
|
File_system::Session &fs, const char *file_path)
|
||||||
:
|
:
|
||||||
_env(env), _fs(fs), _file_path(file_path),
|
_env(env), _fs(fs),
|
||||||
_file_handle(_open_file(_fs, _file_path))
|
_file_path(file_path),
|
||||||
|
_file_handle(_open_file(_fs, _file_path)),
|
||||||
|
_file_ds(env.ram(), env.rm(), 0) /* realloc later */
|
||||||
{
|
{
|
||||||
if (!_file_handle.valid())
|
if (!_file_handle.valid())
|
||||||
_register_for_compound_dir_changes();
|
_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())
|
if (_compound_dir_handle.valid())
|
||||||
_fs.close(_compound_dir_handle);
|
_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()
|
Genode::Rom_dataspace_capability dataspace()
|
||||||
{
|
{
|
||||||
_update_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);
|
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;
|
switch (packet.operation()) {
|
||||||
if (_file_handle.valid())
|
|
||||||
_fs.sigh(_file_handle, _sigh);
|
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:
|
private:
|
||||||
|
|
||||||
@ -328,7 +402,9 @@ class Rom_root : public Genode::Root_component<Rom_session_component>
|
|||||||
/* open file-system session */
|
/* open file-system session */
|
||||||
File_system::Connection _fs { _env, _fs_tx_block_alloc };
|
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 label = label_from_args(args);
|
||||||
Genode::Session_label const module_name = label.last_element();
|
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);
|
Genode::log("request for ", label);
|
||||||
|
|
||||||
/* create new session for the requested file */
|
/* 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());
|
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:
|
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),
|
Genode::Root_component<Rom_session_component>(env.ep(), md_alloc),
|
||||||
_env(env)
|
_env(env)
|
||||||
{
|
{
|
||||||
|
/* Process CONTENT_CHANGED acknowledgement packets at the entrypoint */
|
||||||
|
_fs.sigh_ack_avail(_packet_handler);
|
||||||
|
|
||||||
env.parent().announce(env.ep().manage(*this));
|
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)
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
static Sliced_heap sliced_heap(env.ram(), env.rm());
|
static Genode::Sliced_heap sliced_heap(env.ram(), env.rm());
|
||||||
static Rom_root inst(env, sliced_heap);
|
static Fs_rom::Rom_root inst(env, sliced_heap);
|
||||||
}
|
}
|
||||||
|
@ -58,12 +58,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
void * const content = tx_sink()->packet_content(packet);
|
void * const content = tx_sink()->packet_content(packet);
|
||||||
size_t const length = packet.length();
|
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 */
|
/* resulting length */
|
||||||
size_t res_length = 0;
|
size_t res_length = 0;
|
||||||
@ -71,13 +65,22 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
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;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
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;
|
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:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -85,6 +88,7 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
|
tx_sink()->acknowledge_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _process_packet()
|
void _process_packet()
|
||||||
@ -101,12 +105,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
_process_packet_op(packet, *node);
|
_process_packet_op(packet, *node);
|
||||||
}
|
}
|
||||||
catch (Invalid_handle) { Genode::error("Invalid_handle"); }
|
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");
|
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
|
* We could call sync(2) here but for now we forward just the
|
||||||
* reminder because besides testing, there is currently no
|
* reminder because besides testing, there is currently no
|
||||||
|
@ -63,12 +63,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
void * const content = tx_sink()->packet_content(packet);
|
void * const content = tx_sink()->packet_content(packet);
|
||||||
size_t const length = packet.length();
|
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 */
|
/* resulting length */
|
||||||
size_t res_length = 0;
|
size_t res_length = 0;
|
||||||
@ -76,13 +70,20 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
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;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
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;
|
break;
|
||||||
|
|
||||||
|
case Packet_descriptor::CONTENT_CHANGED:
|
||||||
|
_handle_registry.register_notify(*tx_sink(), packet.handle());
|
||||||
|
node.notify_listeners();
|
||||||
|
return;
|
||||||
|
|
||||||
case Packet_descriptor::READ_READY:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -90,6 +91,7 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
|
tx_sink()->acknowledge_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _process_packet()
|
void _process_packet()
|
||||||
@ -106,12 +108,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
_process_packet_op(packet, *node);
|
_process_packet_op(packet, *node);
|
||||||
}
|
}
|
||||||
catch (Invalid_handle) { Genode::error("Invalid_handle"); }
|
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()
|
void _process_packets()
|
||||||
@ -414,9 +410,11 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
node->notify_listeners();
|
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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -647,12 +647,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
{
|
{
|
||||||
void * const content = tx_sink()->packet_content(packet);
|
void * const content = tx_sink()->packet_content(packet);
|
||||||
size_t const length = packet.length();
|
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 */
|
/* resulting length */
|
||||||
size_t res_length = 0;
|
size_t res_length = 0;
|
||||||
@ -660,13 +654,22 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
switch (packet.operation()) {
|
switch (packet.operation()) {
|
||||||
|
|
||||||
case Packet_descriptor::READ:
|
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;
|
break;
|
||||||
|
|
||||||
case Packet_descriptor::WRITE:
|
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;
|
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:
|
case Packet_descriptor::READ_READY:
|
||||||
/* not supported */
|
/* not supported */
|
||||||
break;
|
break;
|
||||||
@ -674,6 +677,7 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
|
|
||||||
packet.length(res_length);
|
packet.length(res_length);
|
||||||
packet.succeeded(res_length > 0);
|
packet.succeeded(res_length > 0);
|
||||||
|
tx_sink()->acknowledge_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _process_packet()
|
void _process_packet()
|
||||||
@ -689,12 +693,6 @@ class File_system::Session_component : public Session_rpc_object
|
|||||||
_process_packet_op(packet, *node);
|
_process_packet_op(packet, *node);
|
||||||
}
|
}
|
||||||
catch (Invalid_handle) { Genode::error("Invalid_handle"); }
|
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 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;
|
Directory &_root_dir;
|
||||||
|
|
||||||
|
Genode::Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Session_component *_create_session(const char *args)
|
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);
|
Session_label const label = label_from_args(args);
|
||||||
try {
|
try {
|
||||||
Session_policy policy(label);
|
Session_policy policy(label, _config.xml());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Override default settings with specific session settings by
|
* Override default settings with specific session settings by
|
||||||
|
@ -192,6 +192,10 @@ class Vfs_server::Session_component : public File_system::Session_rpc_object,
|
|||||||
catch (Dont_ack) { throw; }
|
catch (Dont_ack) { throw; }
|
||||||
catch (...) { }
|
catch (...) { }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Packet_descriptor::CONTENT_CHANGED:
|
||||||
|
/* The VFS does not track file changes yet */
|
||||||
|
throw Dont_ack();
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.length(res_length);
|
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.
|
* Sync the VFS and send any pending signals on the node.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user