vfs,libc: introduce Vfs::Env::User interface

The new interface is meant to replace the 'Vfs::Io_response_handler'.
In contrast to the 'Io_response_handler', which had to be called
on a 'Vfs_handle', the new interface does not require any specific
'Vfs_handle'. It is merely meant to prompt the VFS user (like the libc)
to re-attempt stalled I/O operations but it does not provide any
immediate hint, about which of the handles have become ready for
reading/writing.

Issue #4697
This commit is contained in:
Norman Feske 2022-12-07 14:06:35 +01:00 committed by Christian Helmuth
parent cf87b0fadb
commit 5ad98f2b7c
4 changed files with 56 additions and 9 deletions

View File

@ -64,8 +64,11 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
public:
Env_implementation(Genode::Env &env, Genode::Allocator &alloc)
: _env(env), _vfs_env(_env, alloc, _vfs_config()) { }
Env_implementation(Genode::Env &env, Genode::Allocator &alloc,
Vfs::Env::User &vfs_user)
:
_env(env), _vfs_env(_env, alloc, _vfs_config(), vfs_user)
{ }
Vfs::File_system &vfs() { return _vfs_env.root_dir(); }

View File

@ -151,7 +151,24 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
*/
void reset_malloc_heap() override;
Env_implementation _libc_env { _env, _heap };
/* io_progress_handler marker */
bool _io_progressed = false;
struct Vfs_user : Vfs::Env::User
{
bool &_io_progressed;
Vfs_user(bool &io_progressed) : _io_progressed(io_progressed) { }
void wakeup_vfs_user() override
{
_io_progressed = true;
}
};
Vfs_user _vfs_user { _io_progressed };
Env_implementation _libc_env { _env, _heap, _vfs_user };
bool const _update_mtime = _libc_env.libc_config().attribute_value("update_mtime", true);
@ -205,9 +222,6 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
jmp_buf _user_context;
bool _valid_user_context = false;
/* io_progress_handler marker */
bool _io_progressed { false };
Thread &_myself { *Thread::myself() };
addr_t _kernel_stack = Thread::mystack().top;

View File

@ -60,6 +60,20 @@ struct Vfs::Env : Interface
};
virtual Io &io() = 0;
/**
* Interface for notifying the VFS user about possible progress
*
* This interface allows VFS plugins to prompt the potential unblocking of
* the VFS user, e.g., continuing a write operation that was stalled
* because of a saturated I/O buffer.
*/
struct User : Interface, Genode::Noncopyable
{
virtual void wakeup_vfs_user() = 0;
};
virtual User &user() = 0;
};
#endif /* _INCLUDE__VFS__ENV_H_ */

View File

@ -22,12 +22,13 @@
namespace Vfs { struct Simple_env; }
class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io
class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io, private Vfs::Env::User
{
private:
Genode::Env &_env;
Genode::Allocator &_alloc;
Vfs::Env::User &_user;
Global_file_system_factory _fs_factory { _alloc };
@ -41,9 +42,15 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io
Simple_env(Genode::Env &env,
Genode::Allocator &alloc,
Genode::Xml_node config)
Genode::Xml_node config,
Vfs::Env::User &user)
:
_env(env), _alloc(alloc), _root_dir(*this, config, _fs_factory)
_env(env), _alloc(alloc), _user(user), _root_dir(*this, config, _fs_factory)
{ }
Simple_env(Genode::Env &env, Genode::Allocator &alloc, Genode::Xml_node config)
:
Simple_env(env, alloc, config, *this)
{ }
void apply_config(Genode::Xml_node const &config)
@ -56,6 +63,7 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io
Vfs::File_system &root_dir() override { return _root_dir; }
Deferred_wakeups &deferred_wakeups() override { return _deferred_wakeups; }
Vfs::Env::Io &io() override { return *this; }
Vfs::Env::User &user() override { return _user; }
/**
* Vfs::Env::Io interface
@ -70,6 +78,14 @@ class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io
_deferred_wakeups.trigger();
_env.ep().wait_and_dispatch_one_io_signal();
}
/**
* Vfs::Env::User interface
*
* Fallback implementation used if no 'user' is specified at
* construction time.
*/
void wakeup_vfs_user() override { };
};
#endif /* _INCLUDE__VFS__SIMPLE_ENV_H_ */