ram_fs: tie writeable bit to session policy

Related to issue #3507
This commit is contained in:
Norman Feske 2019-11-21 12:24:35 +01:00
parent ee64e29e77
commit 3aaed7188f
5 changed files with 51 additions and 42 deletions

View File

@ -181,7 +181,8 @@ class Ram_fs::Directory : public Node
return static_cast<Directory *>(lookup(path, true));
}
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
size_t read(char *dst, size_t len, seek_off_t seek_offset,
Session_writeable writeable) override
{
using File_system::Directory_entry;
@ -218,7 +219,7 @@ class Ram_fs::Directory : public Node
.inode = node->inode(),
.type = type(),
.rwx = { .readable = true,
.writeable = true,
.writeable = writeable == Session_writeable::WRITEABLE,
.executable = true },
.name = { node->name() }
};
@ -232,15 +233,15 @@ class Ram_fs::Directory : public Node
return 0;
}
Status status() override
Status status(Session_writeable writeable) override
{
return {
.size = _num_entries * sizeof(File_system::Directory_entry),
.type = File_system::Node_type::DIRECTORY,
.rwx = { .readable = true,
.writeable = true,
.executable = true },
.inode = inode(),
.size = _num_entries * sizeof(File_system::Directory_entry),
.type = File_system::Node_type::DIRECTORY,
.rwx = { .readable = true,
.writeable = (writeable == Session_writeable::WRITEABLE),
.executable = true },
.inode = inode(),
.modification_time = modification_time()
};
}

View File

@ -51,7 +51,7 @@ class Ram_fs::File : public Node
File(Allocator &alloc, char const *name)
: _chunk(alloc, 0), _length(0) { Node::name(name); }
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
size_t read(char *dst, size_t len, seek_off_t seek_offset, Session_writeable) override
{
file_size_t const chunk_used_size = _chunk.used_size();
@ -110,15 +110,15 @@ class Ram_fs::File : public Node
return len;
}
Status status() override
Status status(Session_writeable writeable) override
{
return {
.size = _length,
.type = File_system::Node_type::CONTINUOUS_FILE,
.rwx = { .readable = true,
.writeable = true,
.executable = true },
.inode = inode(),
.size = _length,
.type = File_system::Node_type::CONTINUOUS_FILE,
.rwx = { .readable = true,
.writeable = (writeable == Session_writeable::WRITEABLE),
.executable = true },
.inode = inode(),
.modification_time = modification_time()
};
}

View File

@ -51,7 +51,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
Genode::Allocator &_alloc;
Directory &_root;
Id_space<File_system::Node> _open_node_registry { };
bool _writable;
Session_writeable const _writeable;
Signal_handler<Session_component> _process_packet_handler;
@ -81,10 +81,10 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
if (!node.valid())
break;
res_length = node->read((char *)tx_sink()->packet_content(packet),
length, packet.position());
length, packet.position(), _writeable);
/* read data or EOF is a success */
succeeded = res_length || (packet.position() >= node->status().size);
succeeded = res_length || (packet.position() >= node->status(_writeable).size);
}
break;
@ -208,14 +208,14 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
Session_component(size_t tx_buf_size, Genode::Entrypoint &ep,
Genode::Ram_allocator &ram, Genode::Region_map &rm,
Genode::Allocator &alloc,
Directory &root, bool writable)
Directory &root, Session_writeable writeable)
:
Session_rpc_object(ram.alloc(tx_buf_size), rm, ep.rpc_ep()),
_ep(ep),
_ram(ram),
_alloc(alloc),
_root(root),
_writable(writable),
_writeable(writeable),
_process_packet_handler(_ep, *this, &Session_component::_process_packets)
{
/*
@ -253,13 +253,13 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
if (!dir.valid())
throw Unavailable();
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
if (mode != STAT_ONLY && mode != READ_ONLY)
throw Permission_denied();
if (create) {
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
if (dir->has_sub_node_unsynchronized(name.string()))
@ -305,7 +305,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
if (create) {
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
if (dir->has_sub_node_unsynchronized(name.string()))
@ -348,7 +348,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
if (create) {
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
if (!path.valid_string())
@ -424,8 +424,8 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
auto status_fn = [&] (Open_node &open_node) {
Locked_ptr<Node> node { open_node.node() };
if (!node.valid())
throw Unavailable();
return node->status();
throw Unavailable();
return node->status(_writeable);
};
try {
@ -442,7 +442,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
if (!valid_name(name.string()))
throw Invalid_name();
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
auto unlink_fn = [&] (Open_node &open_node) {
@ -468,7 +468,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
void truncate(File_handle file_handle, file_size_t size) override
{
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
auto truncate_fn = [&] (Open_node &open_node) {
@ -489,7 +489,7 @@ class Ram_fs::Session_component : public File_system::Session_rpc_object
void move(Dir_handle from_dir_handle, Name const &from_name,
Dir_handle to_dir_handle, Name const &to_name) override
{
if (!_writable)
if (_writeable == Session_writeable::READ_ONLY)
throw Permission_denied();
if (!valid_name(from_name.string()))
@ -642,7 +642,9 @@ class Ram_fs::Root : public Root_component<Session_component>
}
return new (md_alloc())
Session_component(tx_buf_size, _ep, _ram, _rm, _alloc,
*session_root_dir, writeable);
*session_root_dir,
writeable ? Session_writeable::WRITEABLE
: Session_writeable::READ_ONLY);
}
public:

View File

@ -27,6 +27,8 @@ namespace Ram_fs {
class Node;
class File;
class Symlink;
enum class Session_writeable { READ_ONLY, WRITEABLE };
}
@ -86,10 +88,14 @@ class Ram_fs::Node : public File_system::Node_base,
Timestamp modification_time() const { return _modification_time; }
virtual size_t read(char *dst, size_t len, seek_off_t) = 0;
/*
* 'Session_writeable' is supplied to the 'read' method to reflect the
* writeability in directory entries read from 'Directory' nodes.
*/
virtual size_t read(char *dst, size_t len, seek_off_t, Session_writeable) = 0;
virtual size_t write(char const *src, size_t len, seek_off_t) = 0;
virtual Status status() = 0;
virtual Status status(Session_writeable) = 0;
/* File functionality */

View File

@ -31,7 +31,7 @@ class Ram_fs::Symlink : public Node
Symlink(char const *name): _len(0) { Node::name(name); }
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
size_t read(char *dst, size_t len, seek_off_t seek_offset, Session_writeable) override
{
size_t count = min(len, _len-seek_offset);
Genode::memcpy(dst, _link_to+seek_offset, count);
@ -65,15 +65,15 @@ class Ram_fs::Symlink : public Node
return consumed_len;
}
Status status() override
Status status(Session_writeable writeable) override
{
return {
.size = _len,
.type = File_system::Node_type::SYMLINK,
.rwx = { .readable = true,
.writeable = true,
.executable = true },
.inode = inode(),
.size = _len,
.type = File_system::Node_type::SYMLINK,
.rwx = { .readable = true,
.writeable = (writeable == Session_writeable::WRITEABLE),
.executable = true },
.inode = inode(),
.modification_time = modification_time()
};
}