vfs: remove 'file_size' from read/write interfaces

The 'file_size' type denotes the size of files on disk in bytes. On
32-bit architectures it is larger than the size_t, which refers to
in-memory object sizes.

Whereas the use of 'file_size' is appropriate for ftruncate and seek, it
is not a suitable type for the parameters of read/write operations
because those operations refer to in-memory buffers.

This patch replaces the use of 'file_size' by size_t. However, since it
affects all sites where the read/write interface is uses, it takes the
opportunity to replace the C-style (pointer, size) arguments by
'Byte_range_ptr' and 'Const_byte_range_ptr'.

Issue #4706
This commit is contained in:
Norman Feske
2023-02-09 15:07:24 +01:00
committed by Christian Helmuth
parent 6e1517ca3c
commit bdf47785b8
55 changed files with 1295 additions and 1321 deletions

View File

@ -183,16 +183,14 @@ struct Vfs::File : Vfs::Node
virtual bool poll() { return true; } virtual bool poll() { return true; }
virtual Lxip::ssize_t write(Lxip_vfs_file_handle &, virtual Lxip::ssize_t write(Lxip_vfs_file_handle &,
char const *src, Genode::size_t len, Const_byte_range_ptr const &, file_size)
file_size)
{ {
Genode::error(name(), " not writeable"); Genode::error(name(), " not writeable");
return -1; return -1;
} }
virtual Lxip::ssize_t read(Lxip_vfs_file_handle &, virtual Lxip::ssize_t read(Lxip_vfs_file_handle &,
char *dst, Genode::size_t len, Byte_range_ptr const &, file_size)
file_size)
{ {
Genode::error(name(), " not readable"); Genode::error(name(), " not readable");
return -1; return -1;
@ -217,8 +215,7 @@ struct Vfs::Directory : Vfs::Node
Genode::Allocator &alloc, Genode::Allocator &alloc,
char const*, unsigned, Vfs::Vfs_handle**) = 0; char const*, unsigned, Vfs::Vfs_handle**) = 0;
virtual Lxip::ssize_t read(char *dst, Genode::size_t len, virtual Lxip::ssize_t read(Byte_range_ptr const &, file_size seek_offset) = 0;
file_size seek_offset) = 0;
}; };
@ -269,10 +266,8 @@ struct Vfs::Lxip_vfs_handle : Vfs::Vfs_handle
*/ */
virtual bool read_ready() const = 0; virtual bool read_ready() const = 0;
virtual Read_result read(char *dst, virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
file_size count, file_size &out_count) = 0; virtual Write_result write(Const_byte_range_ptr const &src, size_t &out_count) = 0;
virtual Write_result write(char const *src,
file_size count, file_size &out_count) = 0;
virtual Sync_result sync() { virtual Sync_result sync() {
return Sync_result::SYNC_OK; } return Sync_result::SYNC_OK; }
@ -314,32 +309,32 @@ struct Vfs::Lxip_vfs_file_handle final : Vfs::Lxip_vfs_handle
bool read_ready() const override { bool read_ready() const override {
return (file) ? file->poll() : false; } return (file) ? file->poll() : false; }
Read_result read(char *dst, file_size count, file_size &out_count) override Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
{ {
if (!file) return Read_result::READ_ERR_INVALID; if (!file) return Read_result::READ_ERR_INVALID;
Lxip::ssize_t res = file->read(*this, dst, count, seek()); Lxip::ssize_t res = file->read(*this, dst, seek());
if (res < 0) return Read_result::READ_ERR_IO; if (res < 0) return Read_result::READ_ERR_IO;
out_count = res; out_count = res;
return Read_result::READ_OK; return Read_result::READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
if (!file) return Write_result::WRITE_ERR_INVALID; if (!file) return Write_result::WRITE_ERR_INVALID;
Lxip::ssize_t res = file->write(*this, src, count, seek()); Lxip::ssize_t res = file->write(*this, src, seek());
if (res < 0) return Write_result::WRITE_ERR_IO; if (res < 0) return Write_result::WRITE_ERR_IO;
out_count = res; out_count = res;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
bool write_content_line(char const *buf, Genode::size_t len) bool write_content_line(Const_byte_range_ptr const &src)
{ {
if (len > sizeof(content_buffer) - 2) if (src.num_bytes > sizeof(content_buffer) - 2)
return false; return false;
Genode::memcpy(content_buffer, buf, len); Genode::memcpy(content_buffer, src.start, src.num_bytes);
content_buffer[len+0] = '\n'; content_buffer[src.num_bytes + 0] = '\n';
content_buffer[len+1] = '\0'; content_buffer[src.num_bytes + 1] = '\0';
return true; return true;
} }
@ -359,15 +354,15 @@ struct Vfs::Lxip_vfs_dir_handle final : Vfs::Lxip_vfs_handle
bool read_ready() const override { return true; } bool read_ready() const override { return true; }
Read_result read(char *dst, file_size count, file_size &out_count) override Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
{ {
Lxip::ssize_t res = dir.read(dst, count, seek()); Lxip::ssize_t res = dir.read(dst, seek());
if (res < 0) return Read_result::READ_ERR_IO; if (res < 0) return Read_result::READ_ERR_IO;
out_count = res; out_count = res;
return Read_result::READ_OK; return Read_result::READ_OK;
} }
Write_result write(char const*, file_size, file_size &) override { Write_result write(Const_byte_range_ptr const &, size_t &) override {
return Write_result::WRITE_ERR_INVALID; } return Write_result::WRITE_ERR_INVALID; }
}; };
@ -462,19 +457,19 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t write(Lxip_vfs_file_handle &, Lxip::ssize_t write(Lxip_vfs_file_handle &,
char const *src, Genode::size_t len, Const_byte_range_ptr const &src,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
iovec iov { const_cast<char *>(src), len }; iovec iov { (void *)src.start, src.num_bytes };
msghdr msg = create_msghdr(&_parent.remote_addr(), msghdr msg = create_msghdr(&_parent.remote_addr(),
sizeof(sockaddr_in), len, &iov); sizeof(sockaddr_in), src.num_bytes, &iov);
Lxip::ssize_t res = _sock.ops->sendmsg(&_sock, &msg, len); Lxip::ssize_t res = _sock.ops->sendmsg(&_sock, &msg, src.num_bytes);
if (res < 0) _write_err = res; if (res < 0) _write_err = res;
@ -482,18 +477,18 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
iovec iov { dst, len }; iovec iov { dst.start, dst.num_bytes };
msghdr msg = create_msghdr(nullptr, 0, len, &iov); msghdr msg = create_msghdr(nullptr, 0, dst.num_bytes, &iov);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT); Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, dst.num_bytes, MSG_DONTWAIT);
if (ret == -EAGAIN) if (ret == -EAGAIN)
throw Would_block(); throw Would_block();
@ -520,26 +515,25 @@ class Vfs::Lxip_peek_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t write(Lxip_vfs_file_handle &, Lxip::ssize_t write(Lxip_vfs_file_handle &,
char const *, Genode::size_t, Const_byte_range_ptr const &, file_size) override
file_size) override
{ {
return -1; return -1;
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
iovec iov { dst, len }; iovec iov { dst.start, dst.num_bytes };
msghdr msg = create_msghdr(nullptr, 0, len, &iov); msghdr msg = create_msghdr(nullptr, 0, dst.num_bytes, &iov);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT|MSG_PEEK);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, dst.num_bytes,
MSG_DONTWAIT|MSG_PEEK);
if (ret == -EAGAIN) if (ret == -EAGAIN)
return 0; return 0;
@ -566,7 +560,7 @@ class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
********************/ ********************/
Lxip::ssize_t write(Lxip_vfs_file_handle &handle, Lxip::ssize_t write(Lxip_vfs_file_handle &handle,
char const *src, Genode::size_t len, Const_byte_range_ptr const &src,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
@ -576,7 +570,7 @@ class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
/* already bound to port */ /* already bound to port */
if (_port >= 0) return -1; if (_port >= 0) return -1;
if (!handle.write_content_line(src, len)) return -1; if (!handle.write_content_line(src)) return -1;
/* check if port is already used by other socket */ /* check if port is already used by other socket */
long port = get_port(handle.content_buffer); long port = get_port(handle.content_buffer);
@ -598,18 +592,18 @@ class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
_parent.bind(true); _parent.bind(true);
return len; return src.num_bytes;
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
if (len < sizeof(handle.content_buffer)) if (dst.num_bytes < sizeof(handle.content_buffer))
return -1; return -1;
Genode::size_t const n = Genode::strlen(handle.content_buffer); Genode::size_t const n = Genode::strlen(handle.content_buffer);
Genode::memcpy(dst, handle.content_buffer, n); Genode::memcpy(dst.start, handle.content_buffer, n);
return n; return n;
} }
@ -632,7 +626,7 @@ class Vfs::Lxip_listen_file final : public Vfs::Lxip_file
********************/ ********************/
Lxip::ssize_t write(Lxip_vfs_file_handle &handle, Lxip::ssize_t write(Lxip_vfs_file_handle &handle,
char const *src, Genode::size_t len, Const_byte_range_ptr const &src,
file_size /* ignored */) override file_size /* ignored */) override
{ {
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
@ -640,7 +634,7 @@ class Vfs::Lxip_listen_file final : public Vfs::Lxip_file
/* write-once */ /* write-once */
if (_backlog != ~0UL) return -1; if (_backlog != ~0UL) return -1;
if (!handle.write_content_line(src, len)) return -1; if (!handle.write_content_line(src)) return -1;
Genode::ascii_to_unsigned( Genode::ascii_to_unsigned(
handle.content_buffer, _backlog, sizeof(handle.content_buffer)); handle.content_buffer, _backlog, sizeof(handle.content_buffer));
@ -649,20 +643,20 @@ class Vfs::Lxip_listen_file final : public Vfs::Lxip_file
_write_err = _sock.ops->listen(&_sock, _backlog); _write_err = _sock.ops->listen(&_sock, _backlog);
if (_write_err != 0) { if (_write_err != 0) {
handle.write_content_line("", 0); handle.write_content_line(Const_byte_range_ptr("", 0));
return -1; return -1;
} }
_parent.listen(true); _parent.listen(true);
return len; return src.num_bytes;
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
return Genode::snprintf(dst, len, "%lu\n", _backlog); return Genode::snprintf(dst.start, dst.num_bytes, "%lu\n", _backlog);
} }
}; };
@ -698,14 +692,14 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t write(Lxip_vfs_file_handle &handle, Lxip::ssize_t write(Lxip_vfs_file_handle &handle,
char const *src, Genode::size_t len, Const_byte_range_ptr const &src,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
if (!handle.write_content_line(src, len)) return -1; if (!handle.write_content_line(src)) return -1;
long const port = get_port(handle.content_buffer); long const port = get_port(handle.content_buffer);
if (port == -1) return -1; if (port == -1) return -1;
@ -723,7 +717,7 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
case Lxip::Io_result::LINUX_EINPROGRESS: case Lxip::Io_result::LINUX_EINPROGRESS:
_connecting = true; _connecting = true;
_write_err = 0; _write_err = 0;
return len; return src.num_bytes;
case Lxip::Io_result::LINUX_EALREADY: case Lxip::Io_result::LINUX_EALREADY:
return -1; return -1;
@ -752,11 +746,11 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
_parent.connect(true); _parent.connect(true);
return len; return src.num_bytes;
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
int so_error = 0; int so_error = 0;
@ -770,11 +764,11 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
switch (so_error) { switch (so_error) {
case 0: case 0:
return Genode::snprintf(dst, len, "connected"); return Genode::snprintf(dst.start, dst.num_bytes, "connected");
case Linux::ECONNREFUSED: case Linux::ECONNREFUSED:
return Genode::snprintf(dst, len, "connection refused"); return Genode::snprintf(dst.start, dst.num_bytes, "connection refused");
default: default:
return Genode::snprintf(dst, len, "unknown error"); return Genode::snprintf(dst.start, dst.num_bytes, "unknown error");
} }
} }
}; };
@ -792,14 +786,14 @@ class Vfs::Lxip_local_file final : public Vfs::Lxip_file
********************/ ********************/
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!_sock_valid()) return -1; if (!_sock_valid()) return -1;
if (len < sizeof(handle.content_buffer)) if (dst.num_bytes < sizeof(handle.content_buffer))
return -1; return -1;
sockaddr_storage addr_storage; sockaddr_storage addr_storage;
@ -812,7 +806,7 @@ class Vfs::Lxip_local_file final : public Vfs::Lxip_file
in_addr const i_addr = addr->sin_addr; in_addr const i_addr = addr->sin_addr;
unsigned char const *a = (unsigned char *)&i_addr.s_addr; unsigned char const *a = (unsigned char *)&i_addr.s_addr;
unsigned char const *p = (unsigned char *)&addr->sin_port; unsigned char const *p = (unsigned char *)&addr->sin_port;
return Genode::snprintf(dst, len, return Genode::snprintf(dst.start, dst.num_bytes,
"%d.%d.%d.%d:%u\n", "%d.%d.%d.%d:%u\n",
a[0], a[1], a[2], a[3], (p[0]<<8)|(p[1]<<0)); a[0], a[1], a[2], a[3], (p[0]<<8)|(p[1]<<0));
} }
@ -849,7 +843,7 @@ class Vfs::Lxip_remote_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
@ -889,18 +883,18 @@ class Vfs::Lxip_remote_file final : public Vfs::Lxip_file
in_addr const i_addr = addr->sin_addr; in_addr const i_addr = addr->sin_addr;
unsigned char const *a = (unsigned char *)&i_addr.s_addr; unsigned char const *a = (unsigned char *)&i_addr.s_addr;
unsigned char const *p = (unsigned char *)&addr->sin_port; unsigned char const *p = (unsigned char *)&addr->sin_port;
return Genode::snprintf(dst, len, return Genode::snprintf(dst.start, dst.num_bytes,
"%d.%d.%d.%d:%u\n", "%d.%d.%d.%d:%u\n",
a[0], a[1], a[2], a[3], (p[0]<<8)|(p[1]<<0)); a[0], a[1], a[2], a[3], (p[0]<<8)|(p[1]<<0));
} }
Lxip::ssize_t write(Lxip_vfs_file_handle &handle, Lxip::ssize_t write(Lxip_vfs_file_handle &handle,
char const *src, Genode::size_t len, Const_byte_range_ptr const &src,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
if (!handle.write_content_line(src, len)) return -1; if (!handle.write_content_line(src)) return -1;
long const port = get_port(handle.content_buffer); long const port = get_port(handle.content_buffer);
if (port == -1) return -1; if (port == -1) return -1;
@ -910,7 +904,7 @@ class Vfs::Lxip_remote_file final : public Vfs::Lxip_file
remote_addr->sin_addr.s_addr = get_addr(handle.content_buffer); remote_addr->sin_addr.s_addr = get_addr(handle.content_buffer);
remote_addr->sin_family = AF_INET; remote_addr->sin_family = AF_INET;
return len; return src.num_bytes;
} }
}; };
@ -937,7 +931,7 @@ class Vfs::Lxip_accept_file final : public Vfs::Lxip_file
} }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
using namespace Linux; using namespace Linux;
@ -948,8 +942,8 @@ class Vfs::Lxip_accept_file final : public Vfs::Lxip_file
f.f_flags = 0; f.f_flags = 0;
if (_sock.ops->poll(&f, &_sock, nullptr) & (POLLIN)) { if (_sock.ops->poll(&f, &_sock, nullptr) & (POLLIN)) {
copy_cstring(dst, "1\n", len); copy_cstring(dst.start, "1\n", dst.num_bytes);
return Genode::strlen(dst); return Genode::strlen(dst.start);
} }
throw Would_block(); throw Would_block();
@ -1123,17 +1117,17 @@ class Vfs::Lxip_socket_dir final : public Lxip::Socket_dir
file_size num_dirent() override { return _num_nodes(); } file_size num_dirent() override { return _num_nodes(); }
Lxip::ssize_t read(char *dst, Genode::size_t len, Lxip::ssize_t read(Byte_range_ptr const &dst,
file_size seek_offset) override file_size seek_offset) override
{ {
typedef Vfs::Directory_service::Dirent Dirent; typedef Vfs::Directory_service::Dirent Dirent;
if (len < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return -1; return -1;
Vfs::file_size index = seek_offset / sizeof(Dirent); size_t index = size_t(seek_offset / sizeof(Dirent));
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
Vfs::Node *node = nullptr; Vfs::Node *node = nullptr;
for (Vfs::File *n : _files) { for (Vfs::File *n : _files) {
@ -1181,14 +1175,14 @@ struct Vfs::Lxip_socket_handle final : Vfs::Lxip_vfs_handle
bool read_ready() const override { return true; } bool read_ready() const override { return true; }
Read_result read(char *dst, file_size count, file_size &out_count) override Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
{ {
out_count = Genode::snprintf( out_count = Genode::snprintf(
dst, count, "%s/%s\n", socket_dir.parent().name(), socket_dir.name()); dst.start, dst.num_bytes, "%s/%s\n", socket_dir.parent().name(), socket_dir.name());
return Read_result::READ_OK; return Read_result::READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override { Write_result write(Const_byte_range_ptr const &, size_t &) override {
return Write_result::WRITE_ERR_INVALID; } return Write_result::WRITE_ERR_INVALID; }
}; };
@ -1457,17 +1451,17 @@ class Lxip::Protocol_dir_impl : public Protocol_dir
Vfs::file_size num_dirent() override { return _num_nodes(); } Vfs::file_size num_dirent() override { return _num_nodes(); }
Lxip::ssize_t read(char *dst, Genode::size_t len, Lxip::ssize_t read(Vfs::Byte_range_ptr const &dst,
Vfs::file_size seek_offset) override Vfs::file_size seek_offset) override
{ {
typedef Vfs::Directory_service::Dirent Dirent; typedef Vfs::Directory_service::Dirent Dirent;
if (len < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return -1; return -1;
Vfs::file_size index = seek_offset / sizeof(Dirent); size_t index = size_t(seek_offset / sizeof(Dirent));
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
Vfs::Node *node = nullptr; Vfs::Node *node = nullptr;
for (Vfs::Node *n : _nodes) { for (Vfs::Node *n : _nodes) {
@ -1525,7 +1519,7 @@ class Vfs::Lxip_address_file final : public Vfs::File
: Vfs::File(name), _numeric_address(numeric_address) { } : Vfs::File(name), _numeric_address(numeric_address) { }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
enum { enum {
@ -1536,10 +1530,10 @@ class Vfs::Lxip_address_file final : public Vfs::File
Net::Ipv4_address(&_numeric_address) Net::Ipv4_address(&_numeric_address)
}; };
Lxip::size_t n = min(len, strlen(address.string())); Lxip::size_t n = min(dst.num_bytes, strlen(address.string()));
memcpy(dst, address.string(), n); memcpy(dst.start, address.string(), n);
if (n < len) if (n < dst.num_bytes)
dst[n++] = '\n'; dst.start[n++] = '\n';
return n; return n;
} }
@ -1558,7 +1552,7 @@ class Vfs::Lxip_link_state_file final : public Vfs::File
: Vfs::File(name), _numeric_link_state(numeric_link_state) { } : Vfs::File(name), _numeric_link_state(numeric_link_state) { }
Lxip::ssize_t read(Lxip_vfs_file_handle &handle, Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
char *dst, Genode::size_t len, Byte_range_ptr const &dst,
file_size /* ignored */) override file_size /* ignored */) override
{ {
enum { enum {
@ -1569,10 +1563,10 @@ class Vfs::Lxip_link_state_file final : public Vfs::File
_numeric_link_state ? "up" : "down" _numeric_link_state ? "up" : "down"
}; };
Lxip::size_t n = min(len, strlen(link_state.string())); Lxip::size_t n = min(dst.num_bytes, strlen(link_state.string()));
memcpy(dst, link_state.string(), n); memcpy(dst.start, link_state.string(), n);
if (n < len) if (n < dst.num_bytes)
dst[n++] = '\n'; dst.start[n++] = '\n';
return n; return n;
} }
@ -1649,14 +1643,13 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0); return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0);
} }
Read_result _read(Vfs::Vfs_handle *vfs_handle, char *dst, Read_result _read(Vfs::Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
Vfs::file_size count, size_t &out_count)
Vfs::file_size &out_count)
{ {
Vfs::Lxip_vfs_handle *handle = Vfs::Lxip_vfs_handle *handle =
static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle); static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle);
return handle->read(dst, count, out_count); return handle->read(dst, out_count);
} }
public: public:
@ -1731,10 +1724,9 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
char const*, unsigned, Vfs::Vfs_handle**) override { char const*, unsigned, Vfs::Vfs_handle**) override {
return Vfs::Directory::Open_result::OPEN_ERR_UNACCESSIBLE; } return Vfs::Directory::Open_result::OPEN_ERR_UNACCESSIBLE; }
Lxip::ssize_t read(char *dst, Genode::size_t len, Lxip::ssize_t read(Byte_range_ptr const &dst, file_size seek_offset) override
file_size seek_offset) override
{ {
if (len < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return -1; return -1;
file_size const index = seek_offset / sizeof(Dirent); file_size const index = seek_offset / sizeof(Dirent);
@ -1760,7 +1752,7 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
Entry const &entry = entries[min(index, NUM_ENTRIES - 1U)]; Entry const &entry = entries[min(index, NUM_ENTRIES - 1U)];
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
out = { out = {
.fileno = (Genode::addr_t)entry.fileno, .fileno = (Genode::addr_t)entry.fileno,
@ -1929,23 +1921,23 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
** Lxip_file I/O service interface ** ** Lxip_file I/O service interface **
*************************************/ *************************************/
Write_result write(Vfs_handle *vfs_handle, char const *src, Write_result write(Vfs_handle *vfs_handle,
file_size count, Vfs::Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
Vfs::Lxip_vfs_handle *handle = Vfs::Lxip_vfs_handle *handle =
static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle); static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle);
try { return handle->write(src, count, out_count); } try { return handle->write(src, out_count); }
catch (File::Would_block) { return WRITE_ERR_WOULD_BLOCK; } catch (File::Would_block) { return WRITE_ERR_WOULD_BLOCK; }
} }
Read_result complete_read(Vfs_handle *vfs_handle, Read_result complete_read(Vfs_handle *vfs_handle,
char *dst, file_size count, Vfs::Byte_range_ptr const &dst,
file_size &out_count) override size_t &out_count) override
{ {
try { return _read(vfs_handle, dst, count, out_count); } try { return _read(vfs_handle, dst, out_count); }
catch (File::Would_block) { return READ_QUEUED; } catch (File::Would_block) { return READ_QUEUED; }
} }

View File

@ -227,7 +227,7 @@ class Backend
.type = (op & RUMPUSER_BIO_WRITE) .type = (op & RUMPUSER_BIO_WRITE)
? Block::Operation::Type::WRITE ? Block::Operation::Type::WRITE
: Block::Operation::Type::READ, : Block::Operation::Type::READ,
.block_number = offset / _info.block_size, .block_number = block_number_t(offset / _info.block_size),
.count = length / _info.block_size }; .count = length / _info.block_size };
bool const success = _synchronous_io(data, operation); bool const success = _synchronous_io(data, operation);

View File

@ -80,16 +80,16 @@ class Vfs::Rump_file_system : public File_system
{ {
using Vfs_handle::Vfs_handle; using Vfs_handle::Vfs_handle;
virtual Read_result read(char *buf, file_size buf_size, virtual Read_result read(Byte_range_ptr const &dst,
file_size seek_offset, file_size &out_count) file_size seek_offset, size_t &out_count)
{ {
Genode::error("Rump_vfs_handle::read() called"); Genode::error("Rump_vfs_handle::read() called");
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
virtual Write_result write(char const *buf, file_size buf_size, virtual Write_result write(Const_byte_range_ptr const &src,
file_size seek_offset, file_size seek_offset,
file_size &out_count) size_t &out_count)
{ {
Genode::error("Rump_vfs_handle::write() called"); Genode::error("Rump_vfs_handle::write() called");
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
@ -131,10 +131,10 @@ class Vfs::Rump_file_system : public File_system
return FTRUNCATE_OK; return FTRUNCATE_OK;
} }
Read_result read(char *buf, file_size buf_size, Read_result read(Byte_range_ptr const &dst,
file_size seek_offset, file_size &out_count) override file_size seek_offset, size_t &out_count) override
{ {
ssize_t n = rump_sys_pread(_fd, buf, buf_size, seek_offset); ssize_t n = rump_sys_pread(_fd, dst.start, dst.num_bytes, seek_offset);
if (n == -1) switch (errno) { if (n == -1) switch (errno) {
case EWOULDBLOCK: return READ_ERR_WOULD_BLOCK; case EWOULDBLOCK: return READ_ERR_WOULD_BLOCK;
case EINVAL: return READ_ERR_INVALID; case EINVAL: return READ_ERR_INVALID;
@ -148,13 +148,12 @@ class Vfs::Rump_file_system : public File_system
return READ_OK; return READ_OK;
} }
Write_result write(char const *buf, file_size buf_size, Write_result write(Const_byte_range_ptr const &src,
file_size seek_offset, file_size seek_offset, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
ssize_t n = rump_sys_pwrite(_fd, buf, buf_size, seek_offset); ssize_t n = rump_sys_pwrite(_fd, src.start, src.num_bytes, seek_offset);
if (n == -1) switch (errno) { if (n == -1) switch (errno) {
case EWOULDBLOCK: return WRITE_ERR_WOULD_BLOCK; case EWOULDBLOCK: return WRITE_ERR_WOULD_BLOCK;
case EINVAL: return WRITE_ERR_INVALID; case EINVAL: return WRITE_ERR_INVALID;
@ -234,18 +233,17 @@ class Vfs::Rump_file_system : public File_system
~Rump_vfs_dir_handle() { rump_sys_close(_fd); } ~Rump_vfs_dir_handle() { rump_sys_close(_fd); }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst,
file_size seek_offset, file_size seek_offset, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
file_size index = seek_offset / sizeof(Dirent); size_t const index = size_t(seek_offset / sizeof(Dirent));
Dirent *vfs_dir = (Dirent*)dst; Dirent *vfs_dir = (Dirent*)dst.start;
out_count = sizeof(Dirent); out_count = sizeof(Dirent);
@ -289,9 +287,8 @@ class Vfs::Rump_file_system : public File_system
int status_flags, char const *path) int status_flags, char const *path)
: Rump_vfs_handle(fs, fs, alloc, status_flags), _path(path) { } : Rump_vfs_handle(fs, fs, alloc, status_flags), _path(path) { }
Read_result read(char *buf, file_size buf_size, Read_result read(Byte_range_ptr const &dst,
file_size seek_offset, file_size seek_offset, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
@ -300,7 +297,7 @@ class Vfs::Rump_file_system : public File_system
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
ssize_t n = rump_sys_readlink(_path.base(), buf, buf_size); ssize_t n = rump_sys_readlink(_path.base(), dst.start, dst.num_bytes);
if (n == -1) if (n == -1)
return READ_ERR_IO; return READ_ERR_IO;
@ -309,18 +306,17 @@ class Vfs::Rump_file_system : public File_system
return READ_OK; return READ_OK;
} }
Write_result write(char const *buf, file_size buf_size, Write_result write(Const_byte_range_ptr const &src,
file_size seek_offset, file_size seek_offset, size_t &out_count) override
file_size &out_count) override
{ {
rump_sys_unlink(_path.base()); rump_sys_unlink(_path.base());
if (rump_sys_symlink(buf, _path.base()) != 0) { if (rump_sys_symlink(src.start, _path.base()) != 0) {
out_count = 0; out_count = 0;
return WRITE_OK; return WRITE_OK;
} }
out_count = buf_size; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
}; };
@ -781,28 +777,27 @@ class Vfs::Rump_file_system : public File_system
** File io service interface ** ** File io service interface **
*******************************/ *******************************/
Write_result write(Vfs_handle *vfs_handle, Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
char const *buf, file_size buf_size, size_t &out_count) override
file_size &out_count) override
{ {
Rump_vfs_handle *handle = Rump_vfs_handle *handle =
static_cast<Rump_vfs_handle *>(vfs_handle); static_cast<Rump_vfs_handle *>(vfs_handle);
if (handle) if (handle)
return handle->write(buf, buf_size, handle->seek(), out_count); return handle->write(src, handle->seek(), out_count);
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
Read_result complete_read(Vfs_handle *vfs_handle, char *buf, Read_result complete_read(Vfs_handle *vfs_handle,
file_size buf_size, Byte_range_ptr const &dst,
file_size &out_count) override size_t &out_count) override
{ {
Rump_vfs_handle *handle = Rump_vfs_handle *handle =
static_cast<Rump_vfs_handle *>(vfs_handle); static_cast<Rump_vfs_handle *>(vfs_handle);
if (handle) if (handle)
return handle->read(buf, buf_size, handle->seek(), out_count); return handle->read(dst, handle->seek(), out_count);
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }

View File

@ -25,6 +25,8 @@ namespace Cbe_crypto {
using uint32_t = Genode::uint32_t; using uint32_t = Genode::uint32_t;
using uint64_t = Genode::uint64_t; using uint64_t = Genode::uint64_t;
using size_t = Genode::size_t; using size_t = Genode::size_t;
using Byte_range_ptr = Genode::Byte_range_ptr;
using Const_byte_range_ptr = Genode::Const_byte_range_ptr;
struct Interface; struct Interface;
@ -103,17 +105,15 @@ struct Cbe_crypto::Interface
virtual bool submit_encryption_request(uint64_t const block_number, virtual bool submit_encryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) = 0;
size_t const src_len) = 0;
virtual Complete_request encryption_request_complete(char *dst, size_t const dst_len) = 0; virtual Complete_request encryption_request_complete(Byte_range_ptr const &dst) = 0;
virtual bool submit_decryption_request(uint64_t const block_number, virtual bool submit_decryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) = 0;
size_t const src_len) = 0;
virtual Complete_request decryption_request_complete(char *dst, size_t dst_len) = 0; virtual Complete_request decryption_request_complete(Byte_range_ptr const &dst) = 0;
}; };
#endif /* _INCLUDE__CBE__CRYPTO__INTERFACE_H_ */ #endif /* _INCLUDE__CBE__CRYPTO__INTERFACE_H_ */

View File

@ -23,13 +23,16 @@ namespace Util {
using file_size = Vfs::file_size; using file_size = Vfs::file_size;
using file_offset = Vfs::file_offset; using file_offset = Vfs::file_offset;
using Byte_range_ptr = Vfs::Byte_range_ptr;
using Const_byte_range_ptr = Vfs::Const_byte_range_ptr;
using size_t = Genode::size_t;
struct Io_job struct Io_job
{ {
struct Buffer struct Buffer
{ {
char *base; char *base;
file_size size; size_t size;
}; };
enum class Operation { INVALID, READ, WRITE, SYNC }; enum class Operation { INVALID, READ, WRITE, SYNC };
@ -83,7 +86,7 @@ namespace Util {
char *_data; char *_data;
file_offset const _base_offset; file_offset const _base_offset;
file_offset _current_offset; file_offset _current_offset;
file_size _current_count; size_t _current_count;
bool const _allow_partial; bool const _allow_partial;
@ -110,12 +113,11 @@ namespace Util {
using Result = Vfs::File_io_service::Read_result; using Result = Vfs::File_io_service::Read_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Byte_range_ptr const dst { _data + _current_offset, _current_count };
Result const result = _handle.fs().complete_read(&_handle, dst, out);
Result const result =
_handle.fs().complete_read(&_handle,
_data + _current_offset,
_current_count, out);
if (result == Result::READ_QUEUED if (result == Result::READ_QUEUED
|| result == Result::READ_ERR_WOULD_BLOCK) { || result == Result::READ_ERR_WOULD_BLOCK) {
return progress; return progress;
@ -170,12 +172,11 @@ namespace Util {
using Result = Vfs::File_io_service::Write_result; using Result = Vfs::File_io_service::Write_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Const_byte_range_ptr const src { _data + _current_offset, _current_count };
Result const result = _handle.fs().write(&_handle, src, out);
Result const result =
_handle.fs().write(&_handle, _data + _current_offset,
_current_count, out);
switch (result) { switch (result) {
case Result::WRITE_ERR_WOULD_BLOCK: case Result::WRITE_ERR_WOULD_BLOCK:
return progress; return progress;

View File

@ -66,13 +66,15 @@ Crypto::Result Crypto::add_key(Key const &key)
key.value, sizeof (key.value)); key.value, sizeof (key.value));
_add_key_handle.seek(0); _add_key_handle.seek(0);
file_size nr_of_written_bytes { 0 };
size_t written_bytes = 0;
using Write_result = Vfs::File_io_service::Write_result; using Write_result = Vfs::File_io_service::Write_result;
Const_byte_range_ptr const src(buffer, sizeof(buffer));
Write_result const result = Write_result const result =
_add_key_handle.fs().write(&_add_key_handle, buffer, sizeof (buffer), _add_key_handle.fs().write(&_add_key_handle, src, written_bytes);
nr_of_written_bytes);
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
return Result::RETRY_LATER; return Result::RETRY_LATER;
@ -92,15 +94,15 @@ Crypto::Result Crypto::add_key(Key const &key)
Crypto::Result Crypto::remove_key(Cbe::Key::Id key_id) Crypto::Result Crypto::remove_key(Cbe::Key::Id key_id)
{ {
Vfs::file_size written = 0; size_t written_bytes = 0;
_remove_key_handle.seek(0); _remove_key_handle.seek(0);
Const_byte_range_ptr const src((char *)&key_id.value, sizeof(key_id.value));
using Write_result = Vfs::File_io_service::Write_result; using Write_result = Vfs::File_io_service::Write_result;
Write_result const result = Write_result const result =
_remove_key_handle.fs().write(&_remove_key_handle, _remove_key_handle.fs().write(&_remove_key_handle, src, written_bytes);
(char const*)&key_id.value,
sizeof (key_id.value),
written);
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
return Result::RETRY_LATER; return Result::RETRY_LATER;
@ -195,14 +197,14 @@ void Crypto::_execute_decrypt_block(Job &job,
case Job_state::SUBMITTED: case Job_state::SUBMITTED:
{ {
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE); job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
file_size nr_of_written_bytes { 0 };
job.handle->fs().write( size_t written_bytes = 0;
job.handle,
reinterpret_cast<char const*>( Const_byte_range_ptr const src(
&cipher_buf.item(job.cipher_buf_idx)), reinterpret_cast<char const*>(&cipher_buf.item(job.cipher_buf_idx)),
file_size(sizeof (Cbe::Block_data)), sizeof(Cbe::Block_data));
nr_of_written_bytes);
job.handle->fs().write( job.handle, src, written_bytes);
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE; job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
progress = true; progress = true;
@ -224,14 +226,14 @@ void Crypto::_execute_decrypt_block(Job &job,
} }
case Job_state::READING_VFS_HANDLE_SUCCEEDED: case Job_state::READING_VFS_HANDLE_SUCCEEDED:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
Byte_range_ptr const dst(
reinterpret_cast<char *>(&plain_buf.item(job.plain_buf_idx)),
sizeof(Cbe::Block_data));
Read_result const result = Read_result const result =
job.handle->fs().complete_read( job.handle->fs().complete_read(job.handle, dst, read_bytes);
job.handle,
reinterpret_cast<char *>(
&plain_buf.item(job.plain_buf_idx)),
sizeof (Cbe::Block_data),
nr_of_read_bytes);
switch (result) { switch (result) {
case Read_result::READ_QUEUED: return; case Read_result::READ_QUEUED: return;
@ -259,14 +261,15 @@ void Crypto::_execute_encrypt_block(Job &job,
case Job_state::SUBMITTED: case Job_state::SUBMITTED:
{ {
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE); job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
file_size nr_of_written_bytes { 0 };
job.handle->fs().write( size_t written_bytes = 0;
job.handle,
Const_byte_range_ptr const src(
reinterpret_cast<char const*>( reinterpret_cast<char const*>(
&plain_buf.item(job.plain_buf_idx)), &plain_buf.item(job.plain_buf_idx)),
file_size(sizeof (Cbe::Block_data)), sizeof(Cbe::Block_data));
nr_of_written_bytes);
job.handle->fs().write(job.handle, src, written_bytes);
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE; job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
progress = true; progress = true;
@ -288,14 +291,14 @@ void Crypto::_execute_encrypt_block(Job &job,
} }
case Job_state::READING_VFS_HANDLE_SUCCEEDED: case Job_state::READING_VFS_HANDLE_SUCCEEDED:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
Read_result const result {
job.handle->fs().complete_read( Byte_range_ptr const dst(
job.handle, reinterpret_cast<char *>(&cipher_buf.item(job.cipher_buf_idx)),
reinterpret_cast<char *>( sizeof (Cbe::Block_data));
&cipher_buf.item(job.cipher_buf_idx)),
sizeof (Cbe::Block_data), Read_result const result =
nr_of_read_bytes) }; job.handle->fs().complete_read(job.handle, dst, read_bytes);
switch (result) { switch (result) {
case Read_result::READ_QUEUED: return; case Read_result::READ_QUEUED: return;

View File

@ -298,17 +298,17 @@ class Vfs_block_io_job
case State::IN_PROGRESS: case State::IN_PROGRESS:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
char *const data { char *const data {
reinterpret_cast<char *>( reinterpret_cast<char *>(
&io_data.item(_cbe_req_io_buf_idx(_cbe_req))) }; &io_data.item(_cbe_req_io_buf_idx(_cbe_req))) };
Result const result { Byte_range_ptr const dst(data + _nr_of_processed_bytes,
_handle.fs().complete_read(&_handle, _nr_of_remaining_bytes);
data + _nr_of_processed_bytes,
_nr_of_remaining_bytes, Result const result =
nr_of_read_bytes) }; _handle.fs().complete_read(&_handle, dst, read_bytes);
switch (result) { switch (result) {
case Result::READ_QUEUED: case Result::READ_QUEUED:
@ -318,8 +318,8 @@ class Vfs_block_io_job
case Result::READ_OK: case Result::READ_OK:
_nr_of_processed_bytes += nr_of_read_bytes; _nr_of_processed_bytes += read_bytes;
_nr_of_remaining_bytes -= nr_of_read_bytes; _nr_of_remaining_bytes -= read_bytes;
if (_nr_of_remaining_bytes == 0) { if (_nr_of_remaining_bytes == 0) {
@ -385,17 +385,17 @@ class Vfs_block_io_job
case State::IN_PROGRESS: case State::IN_PROGRESS:
{ {
file_size nr_of_written_bytes { 0 }; size_t written_bytes = 0;
char const *const data { char const *const data {
reinterpret_cast<char *>( reinterpret_cast<char *>(
&io_data.item(_cbe_req_io_buf_idx(_cbe_req))) }; &io_data.item(_cbe_req_io_buf_idx(_cbe_req))) };
Const_byte_range_ptr const src(data + _nr_of_processed_bytes,
_nr_of_remaining_bytes);
Result const result = Result const result =
_handle.fs().write(&_handle, _handle.fs().write(&_handle, src, written_bytes);
data + _nr_of_processed_bytes,
_nr_of_remaining_bytes,
nr_of_written_bytes);
switch (result) { switch (result) {
case Result::WRITE_ERR_WOULD_BLOCK: case Result::WRITE_ERR_WOULD_BLOCK:
@ -403,8 +403,8 @@ class Vfs_block_io_job
case Result::WRITE_OK: case Result::WRITE_OK:
_nr_of_processed_bytes += nr_of_written_bytes; _nr_of_processed_bytes += written_bytes;
_nr_of_remaining_bytes -= nr_of_written_bytes; _nr_of_remaining_bytes -= written_bytes;
if (_nr_of_remaining_bytes == 0) { if (_nr_of_remaining_bytes == 0) {

View File

@ -36,10 +36,12 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
case Job_state::WRITE_IN_PROGRESS: case Job_state::WRITE_IN_PROGRESS:
{ {
file_size nr_of_written_bytes { 0 }; size_t written_bytes { 0 };
Write_result const result =
file.fs().write(&file, write_buf + _job.fl_offset, Const_byte_range_ptr const src(write_buf + _job.fl_offset, _job.fl_size);
_job.fl_size, nr_of_written_bytes);
Write_result const result = file.fs().write(&file, src, written_bytes);
switch (result) { switch (result) {
case Write_result::WRITE_ERR_WOULD_BLOCK: case Write_result::WRITE_ERR_WOULD_BLOCK:
@ -47,8 +49,8 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
case Write_result::WRITE_OK: case Write_result::WRITE_OK:
_job.fl_offset += nr_of_written_bytes; _job.fl_offset += written_bytes;
_job.fl_size -= nr_of_written_bytes; _job.fl_size -= written_bytes;
if (_job.fl_size > 0) { if (_job.fl_size > 0) {
@ -84,11 +86,11 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
case Job_state::READ_IN_PROGRESS: case Job_state::READ_IN_PROGRESS:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
Read_result const result {
file.fs().complete_read( Byte_range_ptr const dst(read_buf + _job.fl_offset, _job.fl_size);
&file, read_buf + _job.fl_offset, _job.fl_size,
nr_of_read_bytes) }; Read_result const result = file.fs().complete_read( &file, dst, read_bytes);
switch (result) { switch (result) {
case Read_result::READ_QUEUED: case Read_result::READ_QUEUED:
@ -98,8 +100,8 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
case Read_result::READ_OK: case Read_result::READ_OK:
_job.fl_offset += nr_of_read_bytes; _job.fl_offset += read_bytes;
_job.fl_size -= nr_of_read_bytes; _job.fl_size -= read_bytes;
_job.request.success(true); _job.request.success(true);
if (_job.fl_size > 0) { if (_job.fl_size > 0) {
@ -142,11 +144,11 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
case Job_state::WRITE_IN_PROGRESS: case Job_state::WRITE_IN_PROGRESS:
{ {
file_size nr_of_written_bytes { 0 }; size_t written_bytes = 0;
Write_result const result =
file.fs().write( Const_byte_range_ptr const src(write_buf + _job.fl_offset, _job.fl_size);
&file, write_buf + _job.fl_offset,
_job.fl_size, nr_of_written_bytes); Write_result const result = file.fs().write( &file, src, written_bytes);
switch (result) { switch (result) {
@ -155,8 +157,8 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
case Write_result::WRITE_OK: case Write_result::WRITE_OK:
_job.fl_offset += nr_of_written_bytes; _job.fl_offset += written_bytes;
_job.fl_size -= nr_of_written_bytes; _job.fl_size -= written_bytes;
if (_job.fl_size > 0) { if (_job.fl_size > 0) {
@ -192,11 +194,11 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
case Job_state::READ_IN_PROGRESS: case Job_state::READ_IN_PROGRESS:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
Read_result const result {
file.fs().complete_read( Byte_range_ptr const dst(_read_buf + _job.fl_offset, _job.fl_size);
&file, _read_buf + _job.fl_offset, _job.fl_size,
nr_of_read_bytes) }; Read_result const result = file.fs().complete_read(&file, dst, read_bytes);
switch (result) { switch (result) {
case Read_result::READ_QUEUED: case Read_result::READ_QUEUED:
@ -206,8 +208,8 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
case Read_result::READ_OK: case Read_result::READ_OK:
_job.fl_offset += nr_of_read_bytes; _job.fl_offset += read_bytes;
_job.fl_size -= nr_of_read_bytes; _job.fl_size -= read_bytes;
_job.request.success(true); _job.request.success(true);
if (_job.fl_size > 0) { if (_job.fl_size > 0) {
@ -254,11 +256,11 @@ void Trust_anchor::_execute_read_operation(Vfs_handle &file,
case Job_state::READ_IN_PROGRESS: case Job_state::READ_IN_PROGRESS:
{ {
file_size nr_of_read_bytes { 0 }; size_t read_bytes = 0;
Read_result const result {
file.fs().complete_read( Byte_range_ptr const dst(read_buf + _job.fl_offset, _job.fl_size);
&file, read_buf + _job.fl_offset, _job.fl_size,
nr_of_read_bytes) }; Read_result const result = file.fs().complete_read(&file, dst, read_bytes);
switch (result) { switch (result) {
case Read_result::READ_QUEUED: case Read_result::READ_QUEUED:
@ -268,8 +270,8 @@ void Trust_anchor::_execute_read_operation(Vfs_handle &file,
case Read_result::READ_OK: case Read_result::READ_OK:
_job.fl_offset += nr_of_read_bytes; _job.fl_offset += read_bytes;
_job.fl_size -= nr_of_read_bytes; _job.fl_size -= read_bytes;
_job.request.success(true); _job.request.success(true);
if (_job.fl_size > 0) { if (_job.fl_size > 0) {

View File

@ -97,11 +97,11 @@ class Vfs_replay
Type type; Type type;
State state; State state;
file_offset offset; file_offset offset;
file_size count; size_t count;
file_size out_count; size_t out_count;
file_offset current_offset; file_offset current_offset;
file_size current_count; size_t current_count;
bool success; bool success;
bool complete; bool complete;
@ -174,12 +174,14 @@ class Vfs_replay
using Result = Vfs::File_io_service::Read_result; using Result = Vfs::File_io_service::Read_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Byte_range_ptr const dst(_read_buffer.local_addr<char>(),
request.current_count);
Result const result = Result const result =
_vfs_handle->fs().complete_read(_vfs_handle, _vfs_handle->fs().complete_read(_vfs_handle, dst, out);
_read_buffer.local_addr<char>(),
request.current_count, out);
if (result == Result::READ_QUEUED if (result == Result::READ_QUEUED
|| result == Result::READ_ERR_WOULD_BLOCK) { || result == Result::READ_ERR_WOULD_BLOCK) {
return progress; return progress;
@ -244,12 +246,13 @@ class Vfs_replay
using Result = Vfs::File_io_service::Write_result; using Result = Vfs::File_io_service::Write_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Const_byte_range_ptr const src(_write_buffer.local_addr<char>(),
request.current_count);
Result const result = _vfs_handle->fs().write(_vfs_handle, src, out);
Result const result =
_vfs_handle->fs().write(_vfs_handle,
_write_buffer.local_addr<char>(),
request.current_count, out);
switch (result) { switch (result) {
case Result::WRITE_ERR_WOULD_BLOCK: case Result::WRITE_ERR_WOULD_BLOCK:
return progress; return progress;
@ -342,7 +345,7 @@ class Vfs_replay
if (!_current_request.pending()) { if (!_current_request.pending()) {
file_offset const offset = node.attribute_value("offset", file_size(~0llu)); file_offset const offset = node.attribute_value("offset", file_size(~0llu));
file_size const count = node.attribute_value("count", file_size(~0llu)); size_t const count = node.attribute_value("count", ~0lu);
using Type_String = String<16>; using Type_String = String<16>;
Type_String const type_string = node.attribute_value("type", Type_String()); Type_String const type_string = node.attribute_value("type", Type_String());

View File

@ -218,15 +218,14 @@ class Vfs_audit::File_system : public Vfs::File_system
**********************/ **********************/
Write_result write(Vfs_handle *vfs_handle, Write_result write(Vfs_handle *vfs_handle,
const char *buf, file_size len, Const_byte_range_ptr const &src, size_t &out) override
file_size &out) override
{ {
Handle &h = *static_cast<Handle*>(vfs_handle); Handle &h = *static_cast<Handle*>(vfs_handle);
h.sync_state(); h.sync_state();
Write_result const result = h.audit->fs().write(h.audit, buf, len, out); Write_result const result = h.audit->fs().write(h.audit, src, out);
if (result == WRITE_OK) if (result == WRITE_OK)
_log("wrote to ", h.path, " ", out, " / ", len); _log("wrote to ", h.path, " ", out, " / ", src.num_bytes);
else if (result == WRITE_ERR_WOULD_BLOCK) else if (result == WRITE_ERR_WOULD_BLOCK)
_log("write stalled for ", h.path); _log("write stalled for ", h.path);
else else
@ -235,7 +234,7 @@ class Vfs_audit::File_system : public Vfs::File_system
return result; return result;
} }
bool queue_read(Vfs_handle *vfs_handle, file_size len) override bool queue_read(Vfs_handle *vfs_handle, size_t len) override
{ {
Handle &h = *static_cast<Handle*>(vfs_handle); Handle &h = *static_cast<Handle*>(vfs_handle);
h.sync_state(); h.sync_state();
@ -244,13 +243,12 @@ class Vfs_audit::File_system : public Vfs::File_system
} }
Read_result complete_read(Vfs_handle *vfs_handle, Read_result complete_read(Vfs_handle *vfs_handle,
char *buf, file_size len, Byte_range_ptr const &dst, size_t &out) override
file_size &out) override
{ {
Handle &h = *static_cast<Handle*>(vfs_handle); Handle &h = *static_cast<Handle*>(vfs_handle);
h.sync_state(); h.sync_state();
Read_result const result = h.audit->fs().complete_read(h.audit, buf, len, out); Read_result const result = h.audit->fs().complete_read(h.audit, dst, out);
if (result == READ_OK) if (result == READ_OK)
_log("completed read from ", h.path, " ", out); _log("completed read from ", h.path, " ", out);

View File

@ -19,6 +19,9 @@ namespace Vfs_cbe {
using file_size = Vfs::file_size; using file_size = Vfs::file_size;
using file_offset = Vfs::file_offset; using file_offset = Vfs::file_offset;
using Byte_range_ptr = Vfs::Byte_range_ptr;
using Const_byte_range_ptr = Vfs::Const_byte_range_ptr;
using size_t = Genode::size_t;
struct Io_job struct Io_job
{ {
@ -84,14 +87,14 @@ namespace Vfs_cbe {
using Result = Vfs::File_io_service::Read_result; using Result = Vfs::File_io_service::Read_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
char * const data = reinterpret_cast<char *const>(&io_data.item(_index)); char * const data = reinterpret_cast<char *const>(&io_data.item(_index));
Result const result = Byte_range_ptr const dst(data + _current_offset, _current_count);
_handle.fs().complete_read(&_handle,
data + _current_offset, Result const result = _handle.fs().complete_read(&_handle, dst, out);
_current_count, out);
if (result == Result::READ_QUEUED if (result == Result::READ_QUEUED
|| result == Result::READ_ERR_WOULD_BLOCK) { || result == Result::READ_ERR_WOULD_BLOCK) {
return progress; return progress;
@ -148,14 +151,15 @@ namespace Vfs_cbe {
using Result = Vfs::File_io_service::Write_result; using Result = Vfs::File_io_service::Write_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
char const * const data = char const * const data =
reinterpret_cast<char const * const>(&io_data.item(_index)); reinterpret_cast<char const * const>(&io_data.item(_index));
Result const result = Const_byte_range_ptr const src(data + _current_offset, _current_count);
_handle.fs().write(&_handle, data + _current_offset,
_current_count, out); Result const result = _handle.fs().write(&_handle, src, out);
switch (result) { switch (result) {
case Result::WRITE_ERR_WOULD_BLOCK: case Result::WRITE_ERR_WOULD_BLOCK:
return progress; return progress;

View File

@ -516,8 +516,7 @@ class Vfs_cbe::Wrapper
} }
bool submit_frontend_request(Vfs_handle &handle, bool submit_frontend_request(Vfs_handle &handle,
char *data, Byte_range_ptr const &data,
file_size count,
Cbe::Request::Operation op, Cbe::Request::Operation op,
uint32_t snap_id) uint32_t snap_id)
{ {
@ -550,7 +549,9 @@ class Vfs_cbe::Wrapper
/* unaligned request if any condition is true */ /* unaligned request if any condition is true */
unaligned_request |= (offset % Cbe::BLOCK_SIZE) != 0; unaligned_request |= (offset % Cbe::BLOCK_SIZE) != 0;
unaligned_request |= (count < Cbe::BLOCK_SIZE); unaligned_request |= (data.num_bytes < Cbe::BLOCK_SIZE);
size_t count = data.num_bytes;
if ((count % Cbe::BLOCK_SIZE) != 0 && if ((count % Cbe::BLOCK_SIZE) != 0 &&
!unaligned_request) !unaligned_request)
@ -589,7 +590,7 @@ class Vfs_cbe::Wrapper
op, op,
false, false,
offset / Cbe::BLOCK_SIZE, offset / Cbe::BLOCK_SIZE,
(uint64_t)data, (uint64_t)data.start,
(uint32_t)(count / Cbe::BLOCK_SIZE), (uint32_t)(count / Cbe::BLOCK_SIZE),
0, 0,
0); 0);
@ -1125,14 +1126,15 @@ class Vfs_cbe::Wrapper
memcpy(buffer, &key.id.value, sizeof (key.id.value)); memcpy(buffer, &key.id.value, sizeof (key.id.value));
memcpy(buffer + sizeof (key.id.value), key.value, sizeof (key.value)); memcpy(buffer + sizeof (key.id.value), key.value, sizeof (key.value));
file_size written = 0; size_t written = 0;
_add_key_handle->seek(0); _add_key_handle->seek(0);
using Write_result = Vfs::File_io_service::Write_result; using Write_result = Vfs::File_io_service::Write_result;
Const_byte_range_ptr const src(buffer, sizeof(buffer));
Write_result const result = Write_result const result =
_add_key_handle->fs().write(_add_key_handle, _add_key_handle->fs().write(_add_key_handle, src, written);
buffer, sizeof (buffer), written);
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
break; /* try again later */ break; /* try again later */
@ -1217,16 +1219,16 @@ class Vfs_cbe::Wrapper
break; break;
} }
file_size written = 0; size_t written = 0;
_remove_key_handle->seek(0); _remove_key_handle->seek(0);
Const_byte_range_ptr const src((char *)&key_id.value,
sizeof(key_id.value));
using Write_result = Vfs::File_io_service::Write_result; using Write_result = Vfs::File_io_service::Write_result;
Write_result const result = Write_result const result =
_remove_key_handle->fs().write(_remove_key_handle, _remove_key_handle->fs().write(_remove_key_handle, src, written);
(char const*)&key_id.value,
sizeof (key_id.value),
written);
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
break; /* try again later */ break; /* try again later */
@ -1345,10 +1347,12 @@ class Vfs_cbe::Wrapper
data = reinterpret_cast<char const*>(&cipher.item(cipher_index)); data = reinterpret_cast<char const*>(&cipher.item(cipher_index));
} }
file_size out = 0; size_t out = 0;
_handle->seek(offset); _handle->seek(offset);
_handle->fs().write(_handle, data,
file_size(sizeof (Cbe::Block_data)), out); Const_byte_range_ptr const src(data, sizeof(Cbe::Block_data));
_handle->fs().write(_handle, src, out);
if (op == Crypto_job::Operation::ENCRYPT) { if (op == Crypto_job::Operation::ENCRYPT) {
cbe.crypto_cipher_data_requested(plain_index); cbe.crypto_cipher_data_requested(plain_index);
@ -1377,7 +1381,7 @@ class Vfs_cbe::Wrapper
{ {
using Result = Vfs::File_io_service::Read_result; using Result = Vfs::File_io_service::Read_result;
file_size out = 0; size_t out = 0;
char *data = nullptr; char *data = nullptr;
if (op == Crypto_job::Operation::ENCRYPT) { if (op == Crypto_job::Operation::ENCRYPT) {
@ -1388,9 +1392,10 @@ class Vfs_cbe::Wrapper
data = reinterpret_cast<char *>(&plain.item(plain_index)); data = reinterpret_cast<char *>(&plain.item(plain_index));
} }
Result const res = Byte_range_ptr const dst(data, sizeof (Cbe::Block_data));
_handle->fs().complete_read(_handle, data,
sizeof (Cbe::Block_data), out); Result const res = _handle->fs().complete_read(_handle, dst, out);
if (_read_queued(res)) { if (_read_queued(res)) {
break; break;
} }
@ -1815,8 +1820,7 @@ class Vfs_cbe::Data_file_system : public Single_file_system
_w(w), _snap_id(snap_id) _w(w), _snap_id(snap_id)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
Genode::Mutex::Guard guard { _w.frontend_mtx() }; Genode::Mutex::Guard guard { _w.frontend_mtx() };
@ -1831,8 +1835,7 @@ class Vfs_cbe::Data_file_system : public Single_file_system
using Op = Cbe::Request::Operation; using Op = Cbe::Request::Operation;
bool const accepted = bool const accepted =
_w.submit_frontend_request(*this, dst, count, _w.submit_frontend_request(*this, dst, Op::READ, _snap_id);
Op::READ, _snap_id);
if (!accepted) { return READ_ERR_IO; } if (!accepted) { return READ_ERR_IO; }
} }
@ -1865,8 +1868,8 @@ class Vfs_cbe::Data_file_system : public Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
Genode::Mutex::Guard guard { _w.frontend_mtx() }; Genode::Mutex::Guard guard { _w.frontend_mtx() };
@ -1881,8 +1884,11 @@ class Vfs_cbe::Data_file_system : public Single_file_system
using Op = Cbe::Request::Operation; using Op = Cbe::Request::Operation;
bool const accepted = bool const accepted =
_w.submit_frontend_request(*this, const_cast<char*>(src), _w.submit_frontend_request(*this,
count, Op::WRITE, _snap_id); Byte_range_ptr(
const_cast<char*>(src.start),
src.num_bytes),
Op::WRITE, _snap_id);
if (!accepted) { return WRITE_ERR_IO; } if (!accepted) { return WRITE_ERR_IO; }
} }
@ -1930,7 +1936,8 @@ class Vfs_cbe::Data_file_system : public Single_file_system
using Op = Cbe::Request::Operation; using Op = Cbe::Request::Operation;
bool const accepted = bool const accepted =
_w.submit_frontend_request(*this, nullptr, 0, Op::SYNC, 0); _w.submit_frontend_request(*this, Byte_range_ptr(nullptr, 0),
Op::SYNC, 0);
if (!accepted) { return SYNC_ERR_INVALID; } if (!accepted) { return SYNC_ERR_INVALID; }
} }
@ -2080,23 +2087,22 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
_w(w) _w(w)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (seek() != 0) { if (seek() != 0) {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
Content_string const result { content_string(_w) }; Content_string const result { content_string(_w) };
copy_cstring(dst, result.string(), count); copy_cstring(dst.start, result.string(), dst.num_bytes);
size_t const length_without_nul = result.length() - 1; size_t const length_without_nul = result.length() - 1;
out_count = count > length_without_nul - 1 ? out_count = dst.num_bytes > length_without_nul - 1 ?
length_without_nul : count; length_without_nul : dst.num_bytes;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
using Type = Wrapper::Extending::Type; using Type = Wrapper::Extending::Type;
using State = Wrapper::Extending::State; using State = Wrapper::Extending::State;
@ -2105,13 +2111,13 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
} }
char tree[16]; char tree[16];
Arg_string::find_arg(src, "tree").string(tree, sizeof (tree), "-"); Arg_string::find_arg(src.start, "tree").string(tree, sizeof (tree), "-");
Type type = Wrapper::Extending::string_to_type(tree); Type type = Wrapper::Extending::string_to_type(tree);
if (type == Type::INVALID) { if (type == Type::INVALID) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
unsigned long blocks = Arg_string::find_arg(src, "blocks").ulong_value(0); unsigned long blocks = Arg_string::find_arg(src.start, "blocks").ulong_value(0);
if (blocks == 0) { if (blocks == 0) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -2121,7 +2127,7 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -2271,23 +2277,22 @@ class Vfs_cbe::Rekey_file_system : public Vfs::Single_file_system
_w(w) _w(w)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (seek() != 0) { if (seek() != 0) {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
Content_string const result { content_string(_w) }; Content_string const result { content_string(_w) };
copy_cstring(dst, result.string(), count); copy_cstring(dst.start, result.string(), dst.num_bytes);
size_t const length_without_nul = result.length() - 1; size_t const length_without_nul = result.length() - 1;
out_count = count > length_without_nul - 1 ? out_count = dst.num_bytes > length_without_nul - 1 ?
length_without_nul : count; length_without_nul : dst.num_bytes;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
using State = Wrapper::Rekeying::State; using State = Wrapper::Rekeying::State;
if (_w.rekeying_progress().state != State::IDLE) { if (_w.rekeying_progress().state != State::IDLE) {
@ -2295,7 +2300,7 @@ class Vfs_cbe::Rekey_file_system : public Vfs::Single_file_system
} }
bool start_rekeying { false }; bool start_rekeying { false };
Genode::ascii_to(src, start_rekeying); Genode::ascii_to(src.start, start_rekeying);
if (!start_rekeying) { if (!start_rekeying) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -2305,7 +2310,7 @@ class Vfs_cbe::Rekey_file_system : public Vfs::Single_file_system
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -2455,23 +2460,22 @@ class Vfs_cbe::Deinitialize_file_system : public Vfs::Single_file_system
_w(w) _w(w)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (seek() != 0) { if (seek() != 0) {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
Content_string const result { content_string(_w) }; Content_string const result { content_string(_w) };
copy_cstring(dst, result.string(), count); copy_cstring(dst.start, result.string(), dst.num_bytes);
size_t const length_without_nul = result.length() - 1; size_t const length_without_nul = result.length() - 1;
out_count = count > length_without_nul - 1 ? out_count = dst.num_bytes > length_without_nul - 1 ?
length_without_nul : count; length_without_nul : dst.num_bytes;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
using State = Wrapper::Deinitialize::State; using State = Wrapper::Deinitialize::State;
if (_w.deinitialize_progress().state != State::IDLE) { if (_w.deinitialize_progress().state != State::IDLE) {
@ -2479,7 +2483,7 @@ class Vfs_cbe::Deinitialize_file_system : public Vfs::Single_file_system
} }
bool start_deinitialize { false }; bool start_deinitialize { false };
Genode::ascii_to(src, start_deinitialize); Genode::ascii_to(src.start, start_deinitialize);
if (!start_deinitialize) { if (!start_deinitialize) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -2489,7 +2493,7 @@ class Vfs_cbe::Deinitialize_file_system : public Vfs::Single_file_system
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -2605,17 +2609,16 @@ class Vfs_cbe::Create_snapshot_file_system : public Vfs::Single_file_system
_w(w) _w(w)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &, size_t &) override
file_size &out_count) override
{ {
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
bool create_snapshot { false }; bool create_snapshot { false };
Genode::ascii_to(src, create_snapshot); Genode::ascii_to(src.start, create_snapshot);
Genode::String<64> str(Genode::Cstring(src, count)); Genode::String<64> str(Genode::Cstring(src.start, src.num_bytes));
if (!create_snapshot) { if (!create_snapshot) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -2626,7 +2629,7 @@ class Vfs_cbe::Create_snapshot_file_system : public Vfs::Single_file_system
return WRITE_OK; return WRITE_OK;
} }
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -2705,18 +2708,18 @@ class Vfs_cbe::Discard_snapshot_file_system : public Vfs::Single_file_system
_w(w) _w(w)
{ } { }
Read_result read(char *, file_size, file_size &) override Read_result read(Byte_range_ptr const &, size_t &) override
{ {
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
out_count = 0; out_count = 0;
Genode::uint64_t id { 0 }; Genode::uint64_t id { 0 };
Genode::ascii_to(src, id); Genode::ascii_to(src.start, id);
if (id == 0) { if (id == 0) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -2983,11 +2986,9 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
{ {
using Vfs_handle::Vfs_handle; using Vfs_handle::Vfs_handle;
virtual Read_result read(char *dst, file_size count, virtual Read_result read(Byte_range_ptr const &, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual Write_result write(char const *src, file_size count, virtual Write_result write(Const_byte_range_ptr const &, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual Sync_result sync() virtual Sync_result sync()
{ {
@ -3004,8 +3005,8 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
bool const _root_dir { false }; bool const _root_dir { false };
Read_result _query_snapshots(file_size index, Read_result _query_snapshots(size_t index,
file_size &out_count, size_t &out_count,
Dirent &out) Dirent &out)
{ {
if (index >= _snap_reg.number_of_snapshots()) { if (index >= _snap_reg.number_of_snapshots()) {
@ -3031,8 +3032,8 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
} }
} }
Read_result _query_root(file_size index, Read_result _query_root(size_t index,
file_size &out_count, size_t &out_count,
Dirent &out) Dirent &out)
{ {
if (index == 0) { if (index == 0) {
@ -3060,17 +3061,16 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
_snap_reg(snap_reg), _root_dir(root_dir) _snap_reg(snap_reg), _root_dir(root_dir)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
file_size index = seek() / sizeof(Dirent); size_t index = size_t(seek() / sizeof(Dirent));
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
if (!_root_dir) { if (!_root_dir) {
@ -3083,7 +3083,7 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
} }
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
@ -3347,32 +3347,30 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
********************************/ ********************************/
Write_result write(Vfs::Vfs_handle *vfs_handle, Write_result write(Vfs::Vfs_handle *vfs_handle,
char const *buf, file_size buf_size, Const_byte_range_ptr const &, size_t &out_count) override
file_size &out_count) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
bool queue_read(Vfs::Vfs_handle *vfs_handle, file_size size) override bool queue_read(Vfs::Vfs_handle *vfs_handle, size_t size) override
{ {
Dir_snap_vfs_handle *dh = Dir_snap_vfs_handle *dh =
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle); dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
if (dh) { if (dh) {
return dh->vfs_handle.fs().queue_read(&dh->vfs_handle, return dh->vfs_handle.fs().queue_read(&dh->vfs_handle, size);
size);
} }
return true; return true;
} }
Read_result complete_read(Vfs::Vfs_handle *vfs_handle, Read_result complete_read(Vfs::Vfs_handle *vfs_handle,
char *dst, file_size count, Byte_range_ptr const &dst,
file_size & out_count) override size_t & out_count) override
{ {
Snap_vfs_handle *sh = Snap_vfs_handle *sh =
dynamic_cast<Snap_vfs_handle*>(vfs_handle); dynamic_cast<Snap_vfs_handle*>(vfs_handle);
if (sh) { if (sh) {
Read_result const res = sh->read(dst, count, out_count); Read_result const res = sh->read(dst, out_count);
return res; return res;
} }
@ -3380,7 +3378,7 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle); dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
if (dh) { if (dh) {
return dh->vfs_handle.fs().complete_read(&dh->vfs_handle, return dh->vfs_handle.fs().complete_read(&dh->vfs_handle,
dst, count, out_count); dst, out_count);
} }
return READ_ERR_IO; return READ_ERR_IO;

View File

@ -160,10 +160,9 @@ struct Crypto : Cbe_crypto::Interface
bool submit_encryption_request(uint64_t const block_number, bool submit_encryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) override
size_t const src_len) override
{ {
if (!src || src_len != sizeof (Cbe::Block_data)) { if (!src.start || src.num_bytes != sizeof (Cbe::Block_data)) {
error("buffer has wrong size"); error("buffer has wrong size");
throw Buffer_size_mismatch(); throw Buffer_size_mismatch();
} }
@ -179,7 +178,7 @@ struct Crypto : Cbe_crypto::Interface
uint64_t block_id = job.request.block_number(); uint64_t block_id = job.request.block_number();
Aes_cbc_4k::Block_number block_number { block_id }; Aes_cbc_4k::Block_number block_number { block_id };
Aes_cbc_4k::Plaintext const &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext const *>(src); Aes_cbc_4k::Plaintext const &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext const *>(src.start);
Aes_cbc_4k::Ciphertext &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext *>(&job.data); Aes_cbc_4k::Ciphertext &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext *>(&job.data);
/* paranoia */ /* paranoia */
@ -190,13 +189,12 @@ struct Crypto : Cbe_crypto::Interface
}); });
} }
Complete_request encryption_request_complete(char * const dst, Complete_request encryption_request_complete(Byte_range_ptr const &dst) override
size_t const dst_len) override
{ {
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch"); static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch");
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch"); static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch");
if (dst_len != sizeof (Cbe::Block_data)) { if (dst.num_bytes != sizeof (Cbe::Block_data)) {
error("buffer has wrong size"); error("buffer has wrong size");
throw Buffer_size_mismatch(); throw Buffer_size_mismatch();
} }
@ -204,7 +202,7 @@ struct Crypto : Cbe_crypto::Interface
uint64_t block_id = 0; uint64_t block_id = 0;
bool const valid = jobs.apply_encrypt([&](auto const &job) { bool const valid = jobs.apply_encrypt([&](auto const &job) {
Genode::memcpy(dst, &job.data, sizeof(job.data)); Genode::memcpy(dst.start, &job.data, sizeof(job.data));
block_id = job.request.block_number(); block_id = job.request.block_number();
@ -217,10 +215,9 @@ struct Crypto : Cbe_crypto::Interface
bool submit_decryption_request(uint64_t const block_number, bool submit_decryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) override
size_t const src_len) override
{ {
if (src_len != sizeof (Cbe::Block_data)) { if (src.num_bytes != sizeof (Cbe::Block_data)) {
error("buffer has wrong size"); error("buffer has wrong size");
throw Buffer_size_mismatch(); throw Buffer_size_mismatch();
} }
@ -233,17 +230,17 @@ struct Crypto : Cbe_crypto::Interface
return jobs.queue_decrypt([&] (auto &job) { return jobs.queue_decrypt([&] (auto &job) {
job.request = Cbe::Request(Cbe::Request::Operation::READ, job.request = Cbe::Request(Cbe::Request::Operation::READ,
false, block_number, 0, 1, key_id, 0); false, block_number, 0, 1, key_id, 0);
Genode::memcpy(&job.data, src, sizeof(job.data)); Genode::memcpy(&job.data, src.start, sizeof(job.data));
}); });
}); });
} }
Complete_request decryption_request_complete(char *dst, size_t dst_len) override Complete_request decryption_request_complete(Byte_range_ptr const &dst) override
{ {
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch"); static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Ciphertext), "size mismatch");
static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch"); static_assert(sizeof(Cbe::Block_data) == sizeof(Aes_cbc_4k::Plaintext), "size mismatch");
if (dst_len != sizeof (Cbe::Block_data)) { if (dst.num_bytes != sizeof (Cbe::Block_data)) {
error("buffer has wrong size"); error("buffer has wrong size");
throw Buffer_size_mismatch(); throw Buffer_size_mismatch();
} }
@ -256,7 +253,7 @@ struct Crypto : Cbe_crypto::Interface
Aes_cbc_4k::Block_number block_number { block_id }; Aes_cbc_4k::Block_number block_number { block_id };
Aes_cbc_4k::Ciphertext const &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext const *>(&job.data); Aes_cbc_4k::Ciphertext const &ciphertext = *reinterpret_cast<Aes_cbc_4k::Ciphertext const *>(&job.data);
Aes_cbc_4k::Plaintext &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext *>(dst); Aes_cbc_4k::Plaintext &plaintext = *reinterpret_cast<Aes_cbc_4k::Plaintext *>(dst.start);
/* paranoia */ /* paranoia */
static_assert(sizeof(ciphertext) == sizeof(job.data), "size mismatch"); static_assert(sizeof(ciphertext) == sizeof(job.data), "size mismatch");

View File

@ -65,14 +65,13 @@ struct Crypto : Cbe_crypto::Interface
bool _submit_request(uint64_t const block_number, bool _submit_request(uint64_t const block_number,
uint32_t const /* key_id */, uint32_t const /* key_id */,
char const *src, Const_byte_range_ptr const &src)
size_t const src_len)
{ {
if (_request.pending) { if (_request.pending) {
return false; return false;
} }
if (src_len < sizeof (_internal_buffer)) { if (src.num_bytes < sizeof (_internal_buffer)) {
error("buffer too small"); error("buffer too small");
throw Buffer_too_small(); throw Buffer_too_small();
} }
@ -80,30 +79,29 @@ struct Crypto : Cbe_crypto::Interface
_request.pending = true; _request.pending = true;
_request.block_number = block_number; _request.block_number = block_number;
Genode::memcpy(_internal_buffer, src, sizeof (_internal_buffer)); Genode::memcpy(_internal_buffer, src.start, sizeof (_internal_buffer));
return true; return true;
} }
bool submit_encryption_request(uint64_t const block_number, bool submit_encryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) override
size_t const src_len) override
{ {
return _submit_request(block_number, key_id, src, src_len); return _submit_request(block_number, key_id, src);
} }
Complete_request _request_complete(char *dst, size_t const dst_len) Complete_request _request_complete(Byte_range_ptr const &dst)
{ {
if (!_request.pending) { if (!_request.pending) {
return Complete_request { .valid = false, .block_number = 0 }; return Complete_request { .valid = false, .block_number = 0 };
} }
if (dst_len < sizeof (_internal_buffer)) { if (dst.num_bytes < sizeof (_internal_buffer)) {
error("buffer too small"); error("buffer too small");
throw Buffer_too_small(); throw Buffer_too_small();
} }
Genode::memcpy(dst, _internal_buffer, sizeof (_internal_buffer)); Genode::memcpy(dst.start, _internal_buffer, sizeof (_internal_buffer));
_request.pending = false; _request.pending = false;
@ -112,22 +110,21 @@ struct Crypto : Cbe_crypto::Interface
.block_number = _request.block_number }; .block_number = _request.block_number };
} }
Complete_request encryption_request_complete(char *dst, size_t const dst_len) override Complete_request encryption_request_complete(Byte_range_ptr const &dst) override
{ {
return _request_complete(dst, dst_len); return _request_complete(dst);
} }
bool submit_decryption_request(uint64_t const block_number, bool submit_decryption_request(uint64_t const block_number,
uint32_t const key_id, uint32_t const key_id,
char const *src, Const_byte_range_ptr const &src) override
size_t const src_len) override
{ {
return _submit_request(block_number, key_id, src, src_len); return _submit_request(block_number, key_id, src);
} }
Complete_request decryption_request_complete(char *dst, size_t dst_len) override Complete_request decryption_request_complete(Byte_range_ptr const &dst) override
{ {
return _request_complete(dst, dst_len); return _request_complete(dst);
} }
}; };

View File

@ -71,8 +71,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
_state { State::NONE } _state { State::NONE }
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::PENDING) { if (_state != State::PENDING) {
return READ_ERR_IO; return READ_ERR_IO;
@ -82,14 +81,14 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
try { try {
Cbe_crypto::Interface::Complete_request const cr = Cbe_crypto::Interface::Complete_request const cr =
_crypto.encryption_request_complete(dst, count); _crypto.encryption_request_complete(dst);
if (!cr.valid) { if (!cr.valid) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = dst.num_bytes;
return READ_OK; return READ_OK;
} catch (Cbe_crypto::Interface::Buffer_too_small) { } catch (Cbe_crypto::Interface::Buffer_too_small) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -98,8 +97,8 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
if (_state != State::NONE) { if (_state != State::NONE) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -108,7 +107,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
try { try {
uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE; uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE;
bool const ok = bool const ok =
_crypto.submit_encryption_request(block_number, _key_id, src, count); _crypto.submit_encryption_request(block_number, _key_id, src);
if (!ok) { if (!ok) {
out_count = 0; out_count = 0;
return WRITE_OK; return WRITE_OK;
@ -119,7 +118,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
} }
_crypto.execute(); _crypto.execute();
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -206,8 +205,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
_state { State::NONE } _state { State::NONE }
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::PENDING) { if (_state != State::PENDING) {
return READ_ERR_IO; return READ_ERR_IO;
@ -217,12 +215,12 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
try { try {
Cbe_crypto::Interface::Complete_request const cr = Cbe_crypto::Interface::Complete_request const cr =
_crypto.decryption_request_complete(dst, count); _crypto.decryption_request_complete(dst);
if (cr.valid) { if (cr.valid) {
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = dst.num_bytes;
return READ_OK; return READ_OK;
} catch (Cbe_crypto::Interface::Buffer_too_small) { } catch (Cbe_crypto::Interface::Buffer_too_small) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -231,8 +229,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::NONE) { if (_state != State::NONE) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -241,7 +238,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
try { try {
uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE; uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE;
bool const ok = bool const ok =
_crypto.submit_decryption_request(block_number, _key_id, src, count); _crypto.submit_decryption_request(block_number, _key_id, src);
if (!ok) { if (!ok) {
out_count = 0; out_count = 0;
return WRITE_OK; return WRITE_OK;
@ -252,7 +249,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
} }
_crypto.execute(); _crypto.execute();
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -499,11 +496,11 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
{ {
using Vfs_handle::Vfs_handle; using Vfs_handle::Vfs_handle;
virtual Read_result read(char *dst, file_size count, virtual Read_result read(Byte_range_ptr const &dst,
file_size &out_count) = 0; size_t &out_count) = 0;
virtual Write_result write(char const *src, file_size count, virtual Write_result write(Const_byte_range_ptr const &src,
file_size &out_count) = 0; size_t &out_count) = 0;
virtual Sync_result sync() virtual Sync_result sync()
{ {
@ -520,8 +517,8 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
bool const _root_dir { false }; bool const _root_dir { false };
Read_result _query_keys(file_size index, Read_result _query_keys(size_t index,
file_size &out_count, size_t &out_count,
Dirent &out) Dirent &out)
{ {
if (index >= _key_reg.number_of_keys()) { if (index >= _key_reg.number_of_keys()) {
@ -547,8 +544,8 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
} }
} }
Read_result _query_root(file_size index, Read_result _query_root(size_t index,
file_size &out_count, size_t &out_count,
Dirent &out) Dirent &out)
{ {
if (index == 0) { if (index == 0) {
@ -576,17 +573,16 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
_key_reg(key_reg), _root_dir(root_dir) _key_reg(key_reg), _root_dir(root_dir)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
file_size index = seek() / sizeof(Dirent); size_t const index = size_t(seek() / sizeof(Dirent));
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
if (!_root_dir) { if (!_root_dir) {
@ -599,7 +595,7 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
} }
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
@ -851,13 +847,13 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Write_result write(Vfs::Vfs_handle *, char const *, Write_result write(Vfs::Vfs_handle *,
file_size, file_size &) override Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
bool queue_read(Vfs::Vfs_handle *vfs_handle, file_size size) override bool queue_read(Vfs::Vfs_handle *vfs_handle, size_t size) override
{ {
Dir_snap_vfs_handle *dh = Dir_snap_vfs_handle *dh =
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle); dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
@ -870,13 +866,13 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
} }
Read_result complete_read(Vfs::Vfs_handle *vfs_handle, Read_result complete_read(Vfs::Vfs_handle *vfs_handle,
char *dst, file_size count, Byte_range_ptr const &dst,
file_size & out_count) override size_t &out_count) override
{ {
Local_vfs_handle *lh = Local_vfs_handle *lh =
dynamic_cast<Local_vfs_handle*>(vfs_handle); dynamic_cast<Local_vfs_handle*>(vfs_handle);
if (lh) { if (lh) {
Read_result const res = lh->read(dst, count, out_count); Read_result const res = lh->read(dst, out_count);
return res; return res;
} }
@ -884,7 +880,7 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle); dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
if (dh) { if (dh) {
return dh->vfs_handle.fs().complete_read(&dh->vfs_handle, return dh->vfs_handle.fs().complete_read(&dh->vfs_handle,
dst, count, out_count); dst, out_count);
} }
return READ_ERR_IO; return READ_ERR_IO;
@ -949,13 +945,13 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
_crypto { crypto } _crypto { crypto }
{ } { }
Read_result read(char *, file_size, file_size &) override Read_result read(Byte_range_ptr const &, size_t &) override
{ {
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
out_count = 0; out_count = 0;
@ -963,26 +959,26 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
if (src == nullptr || count < sizeof (uint32_t)) { if (src.start == nullptr || src.num_bytes < sizeof (uint32_t)) {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
uint32_t id = *reinterpret_cast<uint32_t const*>(src); uint32_t id = *reinterpret_cast<uint32_t const*>(src.start);
if (id == 0) { if (id == 0) {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
if (_type == Type::ADD_KEY) { if (_type == Type::ADD_KEY) {
if (count != sizeof (uint32_t) + 32 /* XXX Cbe::Key::value*/) { if (src.num_bytes != sizeof (uint32_t) + 32 /* XXX Cbe::Key::value*/) {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
try { try {
char const * value = src + sizeof (uint32_t); char const * value = src.start + sizeof (uint32_t);
size_t const value_len = count - sizeof (uint32_t); size_t const value_len = src.num_bytes - sizeof (uint32_t);
if (_crypto.add_key(id, value, value_len)) { if (_crypto.add_key(id, value, value_len)) {
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
} catch (...) { } } catch (...) { }
@ -991,12 +987,12 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
if (_type == Type::REMOVE_KEY) { if (_type == Type::REMOVE_KEY) {
if (count != sizeof (uint32_t)) { if (src.num_bytes != sizeof (uint32_t)) {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
if (_crypto.remove_key(id)) { if (_crypto.remove_key(id)) {
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
} }

View File

@ -69,6 +69,8 @@ class Trust_anchor
Trust_anchor &operator=(Trust_anchor const&) = delete; Trust_anchor &operator=(Trust_anchor const&) = delete;
using size_t = Genode::size_t; using size_t = Genode::size_t;
using Byte_range_ptr = Genode::Byte_range_ptr;
using Const_byte_range_ptr = Genode::Const_byte_range_ptr;
Vfs::Env &_vfs_env; Vfs::Env &_vfs_env;
@ -978,7 +980,7 @@ class Trust_anchor
return result; return result;
} }
bool queue_initialize(char const *src, size_t len) bool queue_initialize(Const_byte_range_ptr const &src)
{ {
if (_job != Job::NONE) { if (_job != Job::NONE) {
return false; return false;
@ -987,7 +989,7 @@ class Trust_anchor
if (_state != State::UNINITIALIZED) { if (_state != State::UNINITIALIZED) {
return false; return false;
} }
SHA256((unsigned char const *)src, len, SHA256((unsigned char const *)src.start, src.num_bytes,
(unsigned char *)_passphrase_hash_buffer.base); (unsigned char *)_passphrase_hash_buffer.base);
_passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH; _passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH;
@ -1010,7 +1012,7 @@ class Trust_anchor
return { true, _job_success }; return { true, _job_success };
} }
bool queue_unlock(char const *src, size_t len) bool queue_unlock(Const_byte_range_ptr const &src)
{ {
if (_job != Job::NONE) { if (_job != Job::NONE) {
return false; return false;
@ -1027,7 +1029,7 @@ class Trust_anchor
return true; return true;
} }
SHA256((unsigned char const *)src, len, SHA256((unsigned char const *)src.start, src.num_bytes,
(unsigned char *)_passphrase_hash_buffer.base); (unsigned char *)_passphrase_hash_buffer.base);
_passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH; _passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH;
@ -1065,24 +1067,24 @@ class Trust_anchor
return true; return true;
} }
Complete_request complete_read_last_hash(char *dst, size_t len) Complete_request complete_read_last_hash(Vfs::Byte_range_ptr const &dst)
{ {
if (_job != Job::READ_HASH || _job_state != Job_state::COMPLETE) { if (_job != Job::READ_HASH || _job_state != Job_state::COMPLETE) {
return { false, false }; return { false, false };
} }
if (len < _last_hash.length) { if (dst.num_bytes < _last_hash.length) {
Genode::warning("truncate hash"); Genode::warning("truncate hash");
} }
Genode::memcpy(dst, _last_hash.value, len); Genode::memcpy(dst.start, _last_hash.value, dst.num_bytes);
_job = Job::NONE; _job = Job::NONE;
_job_state = Job_state::NONE; _job_state = Job_state::NONE;
return { true, _job_success }; return { true, _job_success };
} }
bool queue_update_last_hash(char const *src, size_t len) bool queue_update_last_hash(Vfs::Const_byte_range_ptr const &src)
{ {
if (_job != Job::NONE) { if (_job != Job::NONE) {
return false; return false;
@ -1092,20 +1094,17 @@ class Trust_anchor
return false; return false;
} }
if (len != _last_hash.length) { if (src.num_bytes != _last_hash.length) {
return false; return false;
} }
if (len > _hash_io_job_buffer.size) { size_t const len = Genode::min(src.num_bytes, _hash_io_job_buffer.size);
len = _hash_io_job_buffer.size;
}
_hash_io_job_buffer.size = len; _hash_io_job_buffer.size = len;
Genode::memcpy(_hash_io_job_buffer.buffer, src, Genode::memcpy(_hash_io_job_buffer.buffer, src.start, len);
_hash_io_job_buffer.size);
Genode::memcpy(_last_hash.value, src, len); Genode::memcpy(_last_hash.value, src.start, len);
_job = Job::UPDATE_HASH; _job = Job::UPDATE_HASH;
_job_state = Job_state::PENDING; _job_state = Job_state::PENDING;
@ -1123,7 +1122,7 @@ class Trust_anchor
return { true, _job_success }; return { true, _job_success };
} }
bool queue_encrypt_key(char const *src, size_t len) bool queue_encrypt_key(Const_byte_range_ptr const &src)
{ {
if (_job != Job::NONE) { if (_job != Job::NONE) {
return false; return false;
@ -1133,39 +1132,39 @@ class Trust_anchor
return false; return false;
} }
if (len != _encrypt_key.length) { if (src.num_bytes != _encrypt_key.length) {
Genode::error(__func__, ": key length mismatch, expected: ", Genode::error(__func__, ": key length mismatch, expected: ",
_encrypt_key.length, " got: ", len); _encrypt_key.length, " got: ", src.num_bytes);
return false; return false;
} }
Genode::memcpy(_encrypt_key.value, src, len); Genode::memcpy(_encrypt_key.value, src.start, src.num_bytes);
_job = Job::ENCRYPT; _job = Job::ENCRYPT;
_job_state = Job_state::PENDING; _job_state = Job_state::PENDING;
return true; return true;
} }
Complete_request complete_encrypt_key(char *dst, size_t len) Complete_request complete_encrypt_key(Byte_range_ptr const &dst)
{ {
if (_job != Job::ENCRYPT || _job_state != Job_state::COMPLETE) { if (_job != Job::ENCRYPT || _job_state != Job_state::COMPLETE) {
return { false, false }; return { false, false };
} }
if (len != _encrypt_key.length) { if (dst.num_bytes != _encrypt_key.length) {
Genode::error(__func__, ": key length mismatch, expected: ", Genode::error(__func__, ": key length mismatch, expected: ",
_encrypt_key.length, " got: ", len); _encrypt_key.length, " got: ", dst.num_bytes);
return { true, false }; return { true, false };
} }
Genode::memcpy(dst, _encrypt_key.value, _encrypt_key.length); Genode::memcpy(dst.start, _encrypt_key.value, _encrypt_key.length);
_job = Job::NONE; _job = Job::NONE;
_job_state = Job_state::NONE; _job_state = Job_state::NONE;
return { true, _job_success }; return { true, _job_success };
} }
bool queue_decrypt_key(char const *src, size_t len) bool queue_decrypt_key(Const_byte_range_ptr const &src)
{ {
if (_job != Job::NONE) { if (_job != Job::NONE) {
return false; return false;
@ -1175,32 +1174,32 @@ class Trust_anchor
return false; return false;
} }
if (len != _decrypt_key.length) { if (src.num_bytes != _decrypt_key.length) {
Genode::error(__func__, ": key length mismatch, expected: ", Genode::error(__func__, ": key length mismatch, expected: ",
_decrypt_key.length, " got: ", len); _decrypt_key.length, " got: ", src.num_bytes);
return false; return false;
} }
Genode::memcpy(_decrypt_key.value, src, len); Genode::memcpy(_decrypt_key.value, src.start, src.num_bytes);
_job = Job::DECRYPT; _job = Job::DECRYPT;
_job_state = Job_state::PENDING; _job_state = Job_state::PENDING;
return true; return true;
} }
Complete_request complete_decrypt_key(char *dst, size_t len) Complete_request complete_decrypt_key(Byte_range_ptr const &dst)
{ {
if (_job != Job::DECRYPT || _job_state != Job_state::COMPLETE) { if (_job != Job::DECRYPT || _job_state != Job_state::COMPLETE) {
return { false, false }; return { false, false };
} }
if (len != _decrypt_key.length) { if (dst.num_bytes != _decrypt_key.length) {
Genode::error(__func__, ": key length mismatch, expected: ", Genode::error(__func__, ": key length mismatch, expected: ",
_decrypt_key.length, " got: ", len); _decrypt_key.length, " got: ", dst.num_bytes);
return { true, false }; return { true, false };
} }
Genode::memcpy(dst, _decrypt_key.value, _decrypt_key.length); Genode::memcpy(dst.start, _decrypt_key.value, _decrypt_key.length);
_job = Job::NONE; _job = Job::NONE;
_job_state = Job_state::NONE; _job_state = Job_state::NONE;
@ -1218,21 +1217,21 @@ class Trust_anchor
return true; return true;
} }
Complete_request complete_generate_key(char *dst, size_t len) Complete_request complete_generate_key(Vfs::Byte_range_ptr const &dst)
{ {
if (_job != Job::GENERATE || _job_state != Job_state::COMPLETE) { if (_job != Job::GENERATE || _job_state != Job_state::COMPLETE) {
return { false, false }; return { false, false };
} }
size_t len = dst.num_bytes;
if (len < _generated_key.length) { if (len < _generated_key.length) {
Genode::warning("truncate generated key"); Genode::warning("truncate generated key");
} else } else {
len = Genode::min(len, _generated_key.length);
if (len > _generated_key.length) {
len = _generated_key.length;
} }
Genode::memcpy(dst, _generated_key.value, len); Genode::memcpy(dst.start, _generated_key.value, len);
Genode::memset(_generated_key.value, 0, sizeof (_generated_key.value)); Genode::memset(_generated_key.value, 0, sizeof (_generated_key.value));
_job = Job::NONE; _job = Job::NONE;
@ -1264,8 +1263,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
_trust_anchor { ta } _trust_anchor { ta }
{ } { }
Read_result read(char *src, file_size count, Read_result read(Byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
_trust_anchor.execute(); _trust_anchor.execute();
@ -1288,14 +1286,14 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
if (_state == State::PENDING_READ) { if (_state == State::PENDING_READ) {
try { try {
Trust_anchor::Complete_request const cr = Trust_anchor::Complete_request const cr =
_trust_anchor.complete_read_last_hash(src, count); _trust_anchor.complete_read_last_hash(src);
if (!cr.valid) { if (!cr.valid) {
_trust_anchor.execute(); _trust_anchor.execute();
return READ_QUEUED; return READ_QUEUED;
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = src.num_bytes;
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} catch (...) { } catch (...) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -1312,7 +1310,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = src.num_bytes;
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} catch (...) { } catch (...) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -1322,8 +1320,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
_trust_anchor.execute(); _trust_anchor.execute();
@ -1332,8 +1329,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
} }
try { try {
bool const ok = bool const ok = _trust_anchor.queue_update_last_hash(src);
_trust_anchor.queue_update_last_hash(src, count);
if (!ok) { if (!ok) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -1343,7 +1339,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
} }
_trust_anchor.execute(); _trust_anchor.execute();
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -1425,8 +1421,7 @@ class Vfs_cbe_trust_anchor::Generate_key_file_system : public Vfs::Single_file_s
_trust_anchor { ta } _trust_anchor { ta }
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_state == State::NONE) { if (_state == State::NONE) {
@ -1439,17 +1434,17 @@ class Vfs_cbe_trust_anchor::Generate_key_file_system : public Vfs::Single_file_s
(void)_trust_anchor.execute(); (void)_trust_anchor.execute();
Trust_anchor::Complete_request const cr = Trust_anchor::Complete_request const cr =
_trust_anchor.complete_generate_key(dst, count); _trust_anchor.complete_generate_key(dst);
if (!cr.valid) { if (!cr.valid) {
return READ_QUEUED; return READ_QUEUED;
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = dst.num_bytes;
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} }
Write_result write(char const *, file_size , file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -1533,8 +1528,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
_state { State::NONE } _state { State::NONE }
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::PENDING) { if (_state != State::PENDING) {
return READ_ERR_IO; return READ_ERR_IO;
@ -1544,14 +1538,14 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
try { try {
Trust_anchor::Complete_request const cr = Trust_anchor::Complete_request const cr =
_trust_anchor.complete_encrypt_key(dst, count); _trust_anchor.complete_encrypt_key(dst);
if (!cr.valid) { if (!cr.valid) {
return READ_QUEUED; return READ_QUEUED;
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = dst.num_bytes;
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} catch (...) { } catch (...) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -1560,8 +1554,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::NONE) { if (_state != State::NONE) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -1569,7 +1562,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
try { try {
bool const ok = bool const ok =
_trust_anchor.queue_encrypt_key(src, count); _trust_anchor.queue_encrypt_key(src);
if (!ok) { if (!ok) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -1579,7 +1572,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
} }
_trust_anchor.execute(); _trust_anchor.execute();
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -1661,8 +1654,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
_state { State::NONE } _state { State::NONE }
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::PENDING) { if (_state != State::PENDING) {
return READ_ERR_IO; return READ_ERR_IO;
@ -1672,14 +1664,14 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
try { try {
Trust_anchor::Complete_request const cr = Trust_anchor::Complete_request const cr =
_trust_anchor.complete_decrypt_key(dst, count); _trust_anchor.complete_decrypt_key(dst);
if (!cr.valid) { if (!cr.valid) {
return READ_QUEUED; return READ_QUEUED;
} }
_state = State::NONE; _state = State::NONE;
out_count = count; out_count = dst.num_bytes;
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} catch (...) { } catch (...) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -1688,8 +1680,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
return READ_ERR_IO; return READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::NONE) { if (_state != State::NONE) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
@ -1697,7 +1688,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
try { try {
bool const ok = bool const ok =
_trust_anchor.queue_decrypt_key(src, count); _trust_anchor.queue_decrypt_key(src);
if (!ok) { if (!ok) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
@ -1707,7 +1698,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
} }
_trust_anchor.execute(); _trust_anchor.execute();
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }
@ -1790,7 +1781,7 @@ class Vfs_cbe_trust_anchor::Initialize_file_system : public Vfs::Single_file_sys
_trust_anchor { ta } _trust_anchor { ta }
{ } { }
Read_result read(char *, file_size, file_size &) override Read_result read(Byte_range_ptr const &, size_t &) override
{ {
if (_state != State::PENDING) { if (_state != State::PENDING) {
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -1811,8 +1802,7 @@ class Vfs_cbe_trust_anchor::Initialize_file_system : public Vfs::Single_file_sys
return cr.success ? READ_OK : READ_ERR_IO; return cr.success ? READ_OK : READ_ERR_IO;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (_state != State::NONE) { if (_state != State::NONE) {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
@ -1820,15 +1810,15 @@ class Vfs_cbe_trust_anchor::Initialize_file_system : public Vfs::Single_file_sys
_init_pending = _trust_anchor.initialized(); _init_pending = _trust_anchor.initialized();
bool const res = _init_pending ? _trust_anchor.queue_unlock(src, count) bool const res = _init_pending ? _trust_anchor.queue_unlock(src)
: _trust_anchor.queue_initialize(src, count); : _trust_anchor.queue_initialize(src);
if (!res) { if (!res) {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }
_state = State::PENDING; _state = State::PENDING;
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }

View File

@ -63,19 +63,18 @@ struct Vfs_gpu::File_system : Single_file_system
_gpu_session.completion_sigh(_completion_sigh); _gpu_session.completion_sigh(_completion_sigh);
} }
Read_result read(char *dst, file_size /* count */, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (!_complete) return READ_QUEUED; if (!_complete) return READ_QUEUED;
_complete = false; _complete = false;
dst[0] = 1; dst.start[0] = 1;
out_count = 1; out_count = 1;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -91,17 +91,17 @@ class Vfs_import::File_system : public Vfs::File_system
{ {
Flush_guard flush(env.io(), *dst_handle); Flush_guard flush(env.io(), *dst_handle);
file_size count = target.length(); Const_byte_range_ptr const src { target.string(), target.length() };
for (;;) { for (;;) {
file_size out_count = 0; size_t out_count = 0;
auto wres = dst_handle->fs().write( auto wres = dst_handle->fs().write(dst_handle, src, out_count);
dst_handle, target.string(), count, out_count);
switch (wres) { switch (wres) {
case WRITE_ERR_WOULD_BLOCK: case WRITE_ERR_WOULD_BLOCK:
break; break;
default: default:
if (out_count < count) { if (out_count < src.num_bytes) {
Genode::error("failed to write symlink ", path, ", ", wres); Genode::error("failed to write symlink ", path, ", ", wres);
env.root_dir().unlink(path.string()); env.root_dir().unlink(path.string());
} }
@ -146,22 +146,26 @@ class Vfs_import::File_system : public Vfs::File_system
while (true) { while (true) {
file_size const bytes_from_source = size_t const bytes_from_source =
src_file.read(at, Genode::Byte_range_ptr(buf, sizeof(buf))); src_file.read(at, Genode::Byte_range_ptr(buf, sizeof(buf)));
if (!bytes_from_source) break; if (!bytes_from_source)
break;
bool write_error { false }; bool write_error = false;
Vfs::file_size remaining_bytes { bytes_from_source };
char const *src { buf }; size_t remaining_bytes = bytes_from_source;
char const *src_ptr = buf;
while (remaining_bytes > 0 && !write_error) { while (remaining_bytes > 0 && !write_error) {
Vfs::file_size out_count { 0 }; size_t out_count = 0;
Const_byte_range_ptr const src { src_ptr, remaining_bytes };
switch (dst_handle->fs().write(dst_handle, src, out_count)) {
switch (dst_handle->fs().write(dst_handle, src,
remaining_bytes,
out_count)) {
case WRITE_ERR_WOULD_BLOCK: case WRITE_ERR_WOULD_BLOCK:
env.io().commit_and_wait(); env.io().commit_and_wait();
break; break;
@ -175,7 +179,7 @@ class Vfs_import::File_system : public Vfs::File_system
case WRITE_OK: case WRITE_OK:
out_count = min(remaining_bytes, out_count); out_count = min(remaining_bytes, out_count);
remaining_bytes -= out_count; remaining_bytes -= out_count;
src += out_count; src_ptr += out_count;
at.value += out_count; at.value += out_count;
dst_handle->advance_seek(out_count); dst_handle->advance_seek(out_count);
break; break;
@ -275,14 +279,10 @@ class Vfs_import::File_system : public Vfs::File_system
** File I/O service ** ** File I/O service **
**********************/ **********************/
Write_result write(Vfs_handle*, Write_result write(Vfs_handle*, Const_byte_range_ptr const &, size_t &) override {
const char *, file_size,
file_size &) override {
return WRITE_ERR_INVALID; } return WRITE_ERR_INVALID; }
Read_result complete_read(Vfs_handle*, Read_result complete_read(Vfs_handle*, Byte_range_ptr const &, size_t &) override {
char*, file_size,
file_size&) override {
return READ_ERR_INVALID; } return READ_ERR_INVALID; }
bool read_ready(Vfs_handle const &) const override { bool read_ready(Vfs_handle const &) const override {

View File

@ -68,13 +68,8 @@ struct Vfs_pipe::Pipe_handle : Vfs::Vfs_handle, private Pipe_handle_registry_ele
virtual ~Pipe_handle(); virtual ~Pipe_handle();
Write_result write(const char *buf, Write_result write(Const_byte_range_ptr const &, size_t &out_count);
file_size count, Read_result read (Byte_range_ptr const &, size_t &out_count);
file_size &out_count);
Read_result read(char *buf,
file_size count,
file_size &out_count);
bool read_ready() const; bool read_ready() const;
bool write_ready() const; bool write_ready() const;
@ -197,19 +192,18 @@ struct Vfs_pipe::Pipe
return Open_result::OPEN_ERR_UNACCESSIBLE; return Open_result::OPEN_ERR_UNACCESSIBLE;
} }
Write_result write(Pipe_handle &, Write_result write(Pipe_handle &, Const_byte_range_ptr const &src, size_t &out_count)
const char *buf, file_size count,
file_size &out_count)
{ {
file_size out = 0; size_t out = 0;
if (buffer.avail_capacity() == 0) { if (buffer.avail_capacity() == 0) {
out_count = 0; out_count = 0;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
while (out < count && 0 < buffer.avail_capacity()) { char const *buf_ptr = src.start;
buffer.add(*(buf++)); while (out < src.num_bytes && 0 < buffer.avail_capacity()) {
buffer.add(*(buf_ptr++));
++out; ++out;
} }
@ -221,13 +215,13 @@ struct Vfs_pipe::Pipe
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
Read_result read(Pipe_handle &handle, Read_result read(Pipe_handle &handle, Byte_range_ptr const &dst, size_t &out_count)
char *buf, file_size count,
file_size &out_count)
{ {
file_size out = 0; size_t out = 0;
while (out < count && !buffer.empty()) {
*(buf++) = buffer.get(); char *buf_ptr = dst.start;
while (out < dst.num_bytes && !buffer.empty()) {
*(buf_ptr++) = buffer.get();
++out; ++out;
} }
@ -252,21 +246,23 @@ struct Vfs_pipe::Pipe
}; };
Vfs_pipe::Pipe_handle::~Pipe_handle() { Vfs_pipe::Pipe_handle::~Pipe_handle()
pipe.remove(*this); } {
pipe.remove(*this);
}
Vfs_pipe::Write_result Vfs_pipe::Write_result
Vfs_pipe::Pipe_handle::write(const char *buf, Vfs_pipe::Pipe_handle::write(Const_byte_range_ptr const &src, size_t &out_count)
file_size count, {
file_size &out_count) { return Pipe_handle::pipe.write(*this, src, out_count);
return Pipe_handle::pipe.write(*this, buf, count, out_count); } }
Vfs_pipe::Read_result Vfs_pipe::Read_result
Vfs_pipe::Pipe_handle::read(char *buf, file_size count, file_size &out_count) Vfs_pipe::Pipe_handle::read(Byte_range_ptr const &dst, size_t &out_count)
{ {
return Pipe_handle::pipe.read(*this, buf, count, out_count); return Pipe_handle::pipe.read(*this, dst, out_count);
} }
@ -314,13 +310,11 @@ struct Vfs_pipe::New_pipe_handle : Vfs::Vfs_handle
pipe.remove_new_handle(); pipe.remove_new_handle();
} }
Read_result read(char *buf, Read_result read(Byte_range_ptr const &dst, size_t &out_count)
file_size count,
file_size &out_count)
{ {
auto name = pipe.name(); auto name = pipe.name();
if (name.length() < count) { if (name.length() < dst.num_bytes) {
memcpy(buf, name.string(), name.length()); memcpy(dst.start, name.string(), name.length());
out_count = name.length(); out_count = name.length();
return Read_result::READ_OK; return Read_result::READ_OK;
} }
@ -569,24 +563,22 @@ class Vfs_pipe::File_system : public Vfs::File_system
**********************/ **********************/
Write_result write(Vfs_handle *vfs_handle, Write_result write(Vfs_handle *vfs_handle,
const char *src, file_size count, Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (Pipe_handle *handle = dynamic_cast<Pipe_handle*>(vfs_handle)) if (Pipe_handle *handle = dynamic_cast<Pipe_handle*>(vfs_handle))
return handle->write(src, count, out_count); return handle->write(src, out_count);
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
Read_result complete_read(Vfs_handle *vfs_handle, Read_result complete_read(Vfs_handle *vfs_handle,
char *dst, file_size count, Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (Pipe_handle *handle = dynamic_cast<Pipe_handle*>(vfs_handle)) if (Pipe_handle *handle = dynamic_cast<Pipe_handle*>(vfs_handle))
return handle->read(dst, count, out_count); return handle->read(dst, out_count);
if (New_pipe_handle *handle = dynamic_cast<New_pipe_handle*>(vfs_handle)) if (New_pipe_handle *handle = dynamic_cast<New_pipe_handle*>(vfs_handle))
return handle->read(dst, count, out_count); return handle->read(dst, out_count);
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }

View File

@ -122,16 +122,15 @@ class Vfs_trace::Trace_buffer_file_system : public Single_file_system
: Single_vfs_handle(ds, fs, alloc, 0), _entries(entries) : Single_vfs_handle(ds, fs, alloc, 0), _entries(entries)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
_entries.for_each_new_entry([&](Trace::Buffer::Entry entry) { _entries.for_each_new_entry([&](Trace::Buffer::Entry entry) {
file_size size = min(count - out_count, entry.length()); size_t const size = min(dst.num_bytes - out_count, entry.length());
memcpy(dst + out_count, entry.data(), (size_t)size); memcpy(dst.start + out_count, entry.data(), size);
out_count += size; out_count += size;
if (out_count == count) if (out_count == dst.num_bytes)
return false; return false;
return true; return true;
@ -140,8 +139,7 @@ class Vfs_trace::Trace_buffer_file_system : public Single_file_system
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, Write_result write(Const_byte_range_ptr const &, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;

View File

@ -54,17 +54,19 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
Single_vfs_handle(ds, fs, alloc, 0), _font(font) Single_vfs_handle(ds, fs, alloc, 0), _font(font)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
if (seek() > FILE_SIZE) if (seek() > FILE_SIZE)
return READ_ERR_INVALID; return READ_ERR_INVALID;
Codepoint const codepoint { (uint32_t)(seek() / Vfs_font::GLYPH_SLOT_BYTES) }; Codepoint const codepoint { uint32_t(seek() / Vfs_font::GLYPH_SLOT_BYTES) };
file_size byte_offset = seek() % Vfs_font::GLYPH_SLOT_BYTES; size_t byte_offset = size_t(seek() % Vfs_font::GLYPH_SLOT_BYTES);
char *dst_ptr = dst.start;
size_t count = dst.num_bytes;
_font.apply_glyph(codepoint, [&] (Glyph_painter::Glyph const &glyph) { _font.apply_glyph(codepoint, [&] (Glyph_painter::Glyph const &glyph) {
@ -73,10 +75,10 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
Glyph_header const header(glyph); Glyph_header const header(glyph);
char const * const src = (char const *)&header + byte_offset; char const * const src = (char const *)&header + byte_offset;
size_t const len = min(sizeof(header) - (size_t)byte_offset, (size_t)count); size_t const len = min(sizeof(header) - byte_offset, count);
memcpy(dst, src, len); memcpy(dst_ptr, src, len);
dst += len; dst_ptr += len;
byte_offset += len; byte_offset += len;
count -= len; count -= len;
out_count += len; out_count += len;
@ -92,8 +94,8 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
if (alpha_offset < alpha_values_len) { if (alpha_offset < alpha_values_len) {
char const * const src = (char const *)glyph.values + alpha_offset; char const * const src = (char const *)glyph.values + alpha_offset;
size_t const len = min(alpha_values_len - alpha_offset, (size_t)count); size_t const len = min(alpha_values_len - alpha_offset, count);
memcpy(dst, src, len); memcpy(dst_ptr, src, len);
out_count += len; out_count += len;
} }
}); });
@ -101,7 +103,7 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -846,12 +846,14 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
Vfs::Vfs_handle *handle = vfs_handle(fd); Vfs::Vfs_handle *handle = vfs_handle(fd);
Vfs::file_size out_count = 0; ::size_t out_count = 0;
Result out_result = Result::WRITE_OK; Result out_result = Result::WRITE_OK;
Const_byte_range_ptr const src { (char const *)buf, count };
if (fd->flags & O_NONBLOCK) { if (fd->flags & O_NONBLOCK) {
monitor().monitor([&] { monitor().monitor([&] {
out_result = handle->fs().write(handle, (char const *)buf, count, out_count); out_result = handle->fs().write(handle, src, out_count);
return Fn::COMPLETE; return Fn::COMPLETE;
}); });
} else { } else {
@ -862,7 +864,7 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
Vfs::Vfs_handle *_handle { handle }; Vfs::Vfs_handle *_handle { handle };
void const *_buf { buf }; void const *_buf { buf };
::size_t _count { count }; ::size_t _count { count };
Vfs::file_size &_out_count { out_count }; ::size_t &_out_count { out_count };
Result &_out_result { out_result }; Result &_out_result { out_result };
::off_t _offset { 0 }; ::off_t _offset { 0 };
unsigned _iteration { 0 }; unsigned _iteration { 0 };
@ -889,10 +891,12 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
for (;;) { for (;;) {
/* number of bytes written in one iteration */ /* number of bytes written in one iteration */
Vfs::file_size partial_out_count = 0; ::size_t partial_out_count = 0;
char const * const src = (char const *)_buf + _offset; Const_byte_range_ptr const src { (char const *)_buf + _offset,
_out_result = _handle->fs().write(_handle, src, _count, partial_out_count); _count };
_out_result = _handle->fs().write(_handle, src, partial_out_count);
if (_out_result == Result::WRITE_ERR_WOULD_BLOCK) if (_out_result == Result::WRITE_ERR_WOULD_BLOCK)
return Fn::INCOMPLETE; return Fn::INCOMPLETE;
@ -986,11 +990,12 @@ ssize_t Libc::Vfs_plugin::read(File_descriptor *fd, void *buf,
if (!succeeded) if (!succeeded)
return Errno(result_errno); return Errno(result_errno);
Vfs::file_size out_count = 0; ::size_t out_count = 0;
Result out_result; Result out_result;
monitor().monitor([&] { monitor().monitor([&] {
out_result = handle->fs().complete_read(handle, (char *)buf, count, out_count); Byte_range_ptr const dst { (char *)buf, count };
out_result = handle->fs().complete_read(handle, dst, out_count);
return out_result != Result::READ_QUEUED ? Fn::COMPLETE : Fn::INCOMPLETE; return out_result != Result::READ_QUEUED ? Fn::COMPLETE : Fn::INCOMPLETE;
}); });
@ -1034,10 +1039,11 @@ ssize_t Libc::Vfs_plugin::getdirentries(File_descriptor *fd, char *buf,
}); });
Result out_result; Result out_result;
Vfs::file_size out_count; ::size_t out_count;
monitor().monitor([&] { monitor().monitor([&] {
out_result = handle->fs().complete_read(handle, (char *)&dirent_out, sizeof(Dirent), out_count); Byte_range_ptr const dst { (char *)&dirent_out, sizeof(Dirent) };
out_result = handle->fs().complete_read(handle, dst, out_count);
return out_result != Result::READ_QUEUED ? Fn::COMPLETE : Fn::INCOMPLETE; return out_result != Result::READ_QUEUED ? Fn::COMPLETE : Fn::INCOMPLETE;
}); });
@ -2072,8 +2078,10 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
{ {
Vfs::Vfs_handle *handle { nullptr }; Vfs::Vfs_handle *handle { nullptr };
Constructible<Sync> sync; Constructible<Sync> sync;
Vfs::file_size const count { ::strlen(target_path) + 1 };
Vfs::file_size out_count { 0 }; size_t const count = ::strlen(target_path) + 1;
size_t out_count = 0;
{ {
bool succeeded { false }; bool succeeded { false };
@ -2127,10 +2135,12 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
case Stage::WRITE: case Stage::WRITE:
{ {
typedef Vfs::File_io_service::Write_result Result; using Result = Vfs::File_io_service::Write_result;
Const_byte_range_ptr const src { target_path, count };
Result result = handle->fs().write(handle, src, out_count);
Result result = handle->fs().write(handle, target_path,
count, out_count);
if (result == Result::WRITE_ERR_WOULD_BLOCK) if (result == Result::WRITE_ERR_WOULD_BLOCK)
return Fn::INCOMPLETE; return Fn::INCOMPLETE;
} }
@ -2165,11 +2175,13 @@ ssize_t Libc::Vfs_plugin::readlink(const char *link_path, char *buf, ::size_t bu
enum class Stage { OPEN, QUEUE_READ, COMPLETE_READ }; enum class Stage { OPEN, QUEUE_READ, COMPLETE_READ };
Stage stage { Stage::OPEN }; Stage stage { Stage::OPEN };
Vfs::Vfs_handle *handle { nullptr };
Vfs::file_size out_len { 0 };
bool succeeded { false }; Vfs::Vfs_handle *handle = nullptr;
int result_errno { 0 };
::size_t out_count = 0;
bool succeeded = false;
int result_errno = 0;
monitor().monitor([&] { monitor().monitor([&] {
switch (stage) { switch (stage) {
@ -2207,10 +2219,12 @@ ssize_t Libc::Vfs_plugin::readlink(const char *link_path, char *buf, ::size_t bu
case Stage::COMPLETE_READ: case Stage::COMPLETE_READ:
{ {
typedef Vfs::File_io_service::Read_result Result; using Result = Vfs::File_io_service::Read_result;
Byte_range_ptr const dst { buf, buf_size };
Result out_result = Result out_result =
handle->fs().complete_read(handle, buf, buf_size, out_len); handle->fs().complete_read(handle, dst, out_count);
switch (out_result) { switch (out_result) {
case Result::READ_QUEUED: return Fn::INCOMPLETE;; case Result::READ_QUEUED: return Fn::INCOMPLETE;;
@ -2230,7 +2244,7 @@ ssize_t Libc::Vfs_plugin::readlink(const char *link_path, char *buf, ::size_t bu
if (!succeeded) if (!succeeded)
return Errno(result_errno); return Errno(result_errno);
return out_len; return out_count;
} }

View File

@ -88,9 +88,8 @@ class Fatfs::File_system : public Vfs::File_system
{ {
using Vfs_handle::Vfs_handle; using Vfs_handle::Vfs_handle;
virtual Read_result complete_read(char *buf, virtual Read_result complete_read(Byte_range_ptr const &dst,
file_size buf_size, size_t &out_count) = 0;
file_size &out_count) = 0;
}; };
struct Fatfs_file_watch_handle : Vfs_watch_handle, Fatfs_watch_handles::Element struct Fatfs_file_watch_handle : Vfs_watch_handle, Fatfs_watch_handles::Element
@ -121,9 +120,8 @@ class Fatfs::File_system : public Vfs::File_system
Fatfs_file_handle(File_system &fs, Allocator &alloc, int status_flags) Fatfs_file_handle(File_system &fs, Allocator &alloc, int status_flags)
: Fatfs_handle(fs, fs, alloc, status_flags) { } : Fatfs_handle(fs, fs, alloc, status_flags) { }
Read_result complete_read(char *buf, Read_result complete_read(Byte_range_ptr const &dst,
file_size buf_size, size_t &out_count) override
file_size &out_count) override
{ {
if (!file) { if (!file) {
Genode::error("READ_ERR_INVALID"); Genode::error("READ_ERR_INVALID");
@ -138,7 +136,7 @@ class Fatfs::File_system : public Vfs::File_system
fres = f_lseek(fil, seek()); fres = f_lseek(fil, seek());
if (fres == FR_OK) { if (fres == FR_OK) {
UINT bw = 0; UINT bw = 0;
fres = f_read(fil, buf, buf_size, &bw); fres = f_read(fil, dst.start, dst.num_bytes, &bw);
out_count = bw; out_count = bw;
} }
@ -163,25 +161,24 @@ class Fatfs::File_system : public Vfs::File_system
Fatfs_dir_handle(File_system &fs, Allocator &alloc, char const *path) Fatfs_dir_handle(File_system &fs, Allocator &alloc, char const *path)
: Fatfs_handle(fs, fs, alloc, 0), path(path) { } : Fatfs_handle(fs, fs, alloc, 0), path(path) { }
Read_result complete_read(char *buf, Read_result complete_read(Byte_range_ptr const &dst,
file_size buf_size, size_t &out_count) override
file_size &out_count) override
{ {
/* not very efficient, just N calls to f_readdir */ /* not very efficient, just N calls to f_readdir */
out_count = 0; out_count = 0;
if (buf_size < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
file_size dir_index = seek() / sizeof(Dirent); size_t dir_index = size_t(seek() / sizeof(Dirent));
if (dir_index < cur_index) { if (dir_index < cur_index) {
/* reset the seek position */ /* reset the seek position */
f_readdir(&dir, nullptr); f_readdir(&dir, nullptr);
cur_index = 0; cur_index = 0;
} }
Dirent &vfs_dirent = *(Dirent*)buf; Dirent &vfs_dirent = *(Dirent*)dst.start;
FILINFO info; FILINFO info;
FRESULT res; FRESULT res;
@ -692,9 +689,8 @@ class Fatfs::File_system : public Vfs::File_system
** File io service interface ** ** File io service interface **
*******************************/ *******************************/
Write_result write(Vfs_handle *vfs_handle, Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
char const *buf, file_size buf_size, size_t &out_count) override
file_size &out_count) override
{ {
Fatfs_file_handle *handle = static_cast<Fatfs_file_handle *>(vfs_handle); Fatfs_file_handle *handle = static_cast<Fatfs_file_handle *>(vfs_handle);
if (!handle->file) if (!handle->file)
@ -723,7 +719,7 @@ class Fatfs::File_system : public Vfs::File_system
if (fres == FR_OK) { if (fres == FR_OK) {
UINT bw = 0; UINT bw = 0;
fres = f_write(fil, buf, buf_size, &bw); fres = f_write(fil, src.start, src.num_bytes, &bw);
f_sync(fil); f_sync(fil);
handle->modifying = true; handle->modifying = true;
out_count = bw; out_count = bw;
@ -738,12 +734,11 @@ class Fatfs::File_system : public Vfs::File_system
} }
} }
Read_result complete_read(Vfs_handle *vfs_handle, char *buf, Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
file_size buf_size, size_t &out_count) override
file_size &out_count) override
{ {
Fatfs_file_handle *handle = static_cast<Fatfs_file_handle *>(vfs_handle); Fatfs_file_handle *handle = static_cast<Fatfs_file_handle *>(vfs_handle);
return handle->complete_read(buf, buf_size, out_count); return handle->complete_read(dst, out_count);
} }
Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) override Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) override

View File

@ -67,29 +67,27 @@ class Jitterentropy_file_system : public Vfs::Single_file_system
_ec_stir(ec_stir), _ec_stir(ec_stir),
_initialized(initialized) { } _initialized(initialized) { }
Read_result read(char *dst, Vfs::file_size count, Read_result read(Genode::Byte_range_ptr const &dst, size_t &out_count) override
Vfs::file_size &out_count) override
{ {
if (!_initialized) if (!_initialized)
return READ_ERR_IO; return READ_ERR_IO;
enum { MAX_BUF_LEN = 256 }; enum { MAX_BUF_LEN = 256UL };
char buf[MAX_BUF_LEN]; char buf[MAX_BUF_LEN];
size_t len = count > MAX_BUF_LEN ? MAX_BUF_LEN : count; size_t const len = Genode::min(dst.num_bytes, MAX_BUF_LEN);
if (jent_read_entropy(_ec_stir, buf, len) < 0) if (jent_read_entropy(_ec_stir, buf, len) < 0)
return READ_ERR_IO; return READ_ERR_IO;
Genode::memcpy(dst, buf, len); Genode::memcpy(dst.start, buf, len);
out_count = len; out_count = len;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, Vfs::file_size count, Write_result write(Genode::Const_byte_range_ptr const &, size_t &) override
Vfs::file_size &out_count) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -86,8 +86,7 @@ class Libusb_file_system : public Vfs::Single_file_system
return nonconst_this._usb_connection.source()->ack_avail(); return nonconst_this._usb_connection.source()->ack_avail();
} }
Read_result read(char *dst, Vfs::file_size count, Read_result read(Genode::Byte_range_ptr const &, Genode::size_t &) override
Vfs::file_size &out_count) override
{ {
return READ_ERR_IO; return READ_ERR_IO;
} }
@ -97,8 +96,7 @@ class Libusb_file_system : public Vfs::Single_file_system
return true; return true;
} }
Write_result write(char const *src, Vfs::file_size count, Write_result write(Genode::Const_byte_range_ptr const &, Genode::size_t &) override
Vfs::file_size &out_count) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -130,8 +130,7 @@ struct Lwip::Directory
{ {
virtual ~Directory() { } virtual ~Directory() { }
virtual Read_result readdir(char *dst, file_size count, virtual Read_result readdir(Byte_range_ptr const &dst, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual bool directory(char const *path) = 0; virtual bool directory(char const *path) = 0;
}; };
@ -142,11 +141,9 @@ struct Lwip::Lwip_handle : Vfs::Vfs_handle
Lwip_handle(Vfs::File_system &fs, Allocator &alloc, int status_flags) Lwip_handle(Vfs::File_system &fs, Allocator &alloc, int status_flags)
: Vfs_handle(fs, fs, alloc, status_flags) { } : Vfs_handle(fs, fs, alloc, status_flags) { }
virtual Read_result read(char *dst, file_size count, virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual Write_result write(char const *, file_size, virtual Write_result write(Const_byte_range_ptr const &, size_t &) {
file_size &) {
return Write_result::WRITE_ERR_INVALID; } return Write_result::WRITE_ERR_INVALID; }
}; };
@ -166,11 +163,10 @@ struct Lwip::Lwip_dir_handle final : Lwip_handle
Lwip_dir_handle(Vfs::File_system &fs, Allocator &alloc, Directory &dir) Lwip_dir_handle(Vfs::File_system &fs, Allocator &alloc, Directory &dir)
: Lwip_handle(fs, alloc, 0), dir(&dir) { } : Lwip_handle(fs, alloc, 0), dir(&dir) { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
return (dir) return (dir)
? dir->readdir(dst, count, out_count) ? dir->readdir(dst, out_count)
: Read_result::READ_ERR_INVALID; : Read_result::READ_ERR_INVALID;
} }
}; };
@ -182,15 +178,14 @@ struct Lwip::Lwip_nameserver_handle final : Lwip_handle, private Nameserver_regi
: Lwip_handle(fs, alloc, Vfs::Directory_service::OPEN_MODE_RDONLY), : Lwip_handle(fs, alloc, Vfs::Directory_service::OPEN_MODE_RDONLY),
Nameserver_registry::Element(registry, *this) { } Nameserver_registry::Element(registry, *this) { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
memset(dst, 0x00, min(file_size(IPADDR_STRLEN_MAX), count)); memset(dst.start, 0x00, min(file_size(IPADDR_STRLEN_MAX), dst.num_bytes));
ipaddr_ntoa_r(dns_getserver(0), dst, count); ipaddr_ntoa_r(dns_getserver(0), dst.start, dst.num_bytes);
auto n = strlen(dst); auto n = strlen(dst.start);
if (n < count) if (n < dst.num_bytes)
dst[n] = '\n'; dst.start[n] = '\n';
out_count = n+1; out_count = n+1;
return Read_result::READ_OK; return Read_result::READ_OK;
@ -208,8 +203,7 @@ struct Lwip::Lwip_address_handle final : Lwip_handle
, netif(netif) , netif(netif)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
using namespace Genode; using namespace Genode;
@ -220,8 +214,8 @@ struct Lwip::Lwip_address_handle final : Lwip_handle
Genode::String<ADDRESS_FILE_SIZE> Genode::String<ADDRESS_FILE_SIZE>
line((char const *)address, "\n"); line((char const *)address, "\n");
size_t n = min(line.length(), count); size_t n = min(line.length(), dst.num_bytes);
memcpy(dst, line.string(), n); memcpy(dst.start, line.string(), n);
out_count = n; out_count = n;
return Read_result::READ_OK; return Read_result::READ_OK;
} }
@ -238,8 +232,7 @@ struct Lwip::Lwip_netmask_handle final : Lwip_handle
, netif(netif) , netif(netif)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
using namespace Genode; using namespace Genode;
@ -250,8 +243,8 @@ struct Lwip::Lwip_netmask_handle final : Lwip_handle
Genode::String<ADDRESS_FILE_SIZE> Genode::String<ADDRESS_FILE_SIZE>
line((char const *)netmask, "\n"); line((char const *)netmask, "\n");
size_t n = min(line.length(), count); size_t n = min(line.length(), dst.num_bytes);
memcpy(dst, line.string(), n); memcpy(dst.start, line.string(), n);
out_count = n; out_count = n;
return Read_result::READ_OK; return Read_result::READ_OK;
} }
@ -318,11 +311,9 @@ struct Lwip::Lwip_file_handle final : Lwip_handle, private Lwip_handle_list::Ele
~Lwip_file_handle(); ~Lwip_file_handle();
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override;
file_size &out_count) override;
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override;
file_size &out_count) override;
bool notify_read_ready(); bool notify_read_ready();
}; };
@ -406,7 +397,7 @@ struct Lwip::Socket_dir : Lwip::Directory
return Open_result::OPEN_OK; return Open_result::OPEN_OK;
} }
Read_result readdir(char *, file_size, file_size &) override Read_result readdir(Byte_range_ptr const &, size_t &) override
{ {
Genode::warning(__func__, " NOT_IMPLEMENTED"); Genode::warning(__func__, " NOT_IMPLEMENTED");
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
@ -419,12 +410,12 @@ struct Lwip::Socket_dir : Lwip::Directory
} }
virtual Read_result read(Lwip_file_handle &, virtual Read_result read(Lwip_file_handle &,
char *dst, file_size count, Byte_range_ptr const &dst,
file_size &out_count) = 0; size_t &out_count) = 0;
virtual Write_result write(Lwip_file_handle &, virtual Write_result write(Lwip_file_handle &,
char const *src, file_size count, Const_byte_range_ptr const &src,
file_size &out_count) = 0; size_t &out_count) = 0;
virtual bool read_ready (Lwip_file_handle const &) const = 0; virtual bool read_ready (Lwip_file_handle const &) const = 0;
virtual bool write_ready(Lwip_file_handle const &) const = 0; virtual bool write_ready(Lwip_file_handle const &) const = 0;
@ -444,11 +435,13 @@ struct Lwip::Socket_dir : Lwip::Directory
Lwip::Lwip_file_handle::Lwip_file_handle(Vfs::File_system &fs, Allocator &alloc, Lwip::Lwip_file_handle::Lwip_file_handle(Vfs::File_system &fs, Allocator &alloc,
int status_flags, int status_flags,
Socket_dir &s, Lwip_file_handle::Kind k) Socket_dir &s, Lwip_file_handle::Kind k)
: Lwip_handle(fs, alloc, status_flags), socket(&s), kind(k) :
Lwip_handle(fs, alloc, status_flags), socket(&s), kind(k)
{ {
socket->handles.insert(this); socket->handles.insert(this);
} }
Lwip::Lwip_file_handle::~Lwip_file_handle() Lwip::Lwip_file_handle::~Lwip_file_handle()
{ {
if (socket) { if (socket) {
@ -462,24 +455,27 @@ Lwip::Lwip_file_handle::~Lwip_file_handle()
} }
} }
Lwip::Read_result Lwip::Lwip_file_handle::read(char *dst, file_size count,
file_size &out_count) Lwip::Read_result Lwip::Lwip_file_handle::read(Byte_range_ptr const &dst,
size_t &out_count)
{ {
if (!socket) if (!socket)
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
return socket->read(*this, dst, count, out_count); return socket->read(*this, dst, out_count);
} }
Lwip::Write_result Lwip::Lwip_file_handle::write(char const *src, file_size count,
file_size &out_count) Lwip::Write_result Lwip::Lwip_file_handle::write(Const_byte_range_ptr const &src,
size_t &out_count)
{ {
if (!socket) if (!socket)
return Write_result::WRITE_ERR_INVALID; return Write_result::WRITE_ERR_INVALID;
return socket->write(*this, src, count, out_count); return socket->write(*this, src, out_count);
} }
bool Lwip::Lwip_file_handle::notify_read_ready() bool Lwip::Lwip_file_handle::notify_read_ready()
{ {
if (socket) { if (socket) {
@ -644,7 +640,7 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
return Directory_service::STAT_ERR_NO_ENTRY; return Directory_service::STAT_ERR_NO_ENTRY;
} }
Read_result readdir(char *, file_size, file_size &) override Read_result readdir(Byte_range_ptr const &, size_t &) override
{ {
Genode::warning(__func__, " NOT_IMPLEMENTED"); Genode::warning(__func__, " NOT_IMPLEMENTED");
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
@ -891,9 +887,8 @@ class Lwip::Udp_socket_dir final :
return true; return true;
} }
Read_result read(Lwip_file_handle &handle, Read_result read(Lwip_file_handle &handle, Byte_range_ptr const &dst,
char *dst, file_size count, size_t &out_count) override
file_size &out_count) override
{ {
Read_result result = Read_result::READ_ERR_INVALID; Read_result result = Read_result::READ_ERR_INVALID;
@ -902,7 +897,7 @@ class Lwip::Udp_socket_dir final :
case Lwip_file_handle::DATA: { case Lwip_file_handle::DATA: {
result = Read_result::READ_QUEUED; result = Read_result::READ_QUEUED;
_packet_queue.head([&] (Packet &pkt) { _packet_queue.head([&] (Packet &pkt) {
out_count = pkt.read(dst, count); out_count = pkt.read(dst.start, dst.num_bytes);
if (pkt.empty()) { if (pkt.empty()) {
_packet_queue.remove(pkt); _packet_queue.remove(pkt);
destroy(_packet_slab, &pkt); destroy(_packet_slab, &pkt);
@ -914,18 +909,18 @@ class Lwip::Udp_socket_dir final :
case Lwip_file_handle::PEEK: case Lwip_file_handle::PEEK:
_packet_queue.head([&] (Packet const &pkt) { _packet_queue.head([&] (Packet const &pkt) {
out_count = pkt.peek(dst, count); out_count = pkt.peek(dst.start, dst.num_bytes);
result = Read_result::READ_OK; result = Read_result::READ_OK;
}); });
break; break;
case Lwip_file_handle::LOCAL: case Lwip_file_handle::LOCAL:
case Lwip_file_handle::BIND: { case Lwip_file_handle::BIND: {
if (count < ENDPOINT_STRLEN_MAX) if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
char const *ip_str = ipaddr_ntoa(&_pcb->local_ip); char const *ip_str = ipaddr_ntoa(&_pcb->local_ip);
/* TODO: [IPv6]:port */ /* TODO: [IPv6]:port */
out_count = Genode::snprintf(dst, count, "%s:%d\n", out_count = Genode::snprintf(dst.start, dst.num_bytes, "%s:%d\n",
ip_str, _pcb->local_port); ip_str, _pcb->local_port);
return Read_result::READ_OK; return Read_result::READ_OK;
} }
@ -933,14 +928,14 @@ class Lwip::Udp_socket_dir final :
case Lwip_file_handle::CONNECT: { case Lwip_file_handle::CONNECT: {
/* check if the PCB was connected */ /* check if the PCB was connected */
if (!ip_addr_isany(&_pcb->remote_ip)) if (!ip_addr_isany(&_pcb->remote_ip))
out_count = Genode::snprintf(dst, count, "connected"); out_count = Genode::snprintf(dst.start, dst.num_bytes, "connected");
else else
out_count = Genode::snprintf(dst, count, "not connected"); out_count = Genode::snprintf(dst.start, dst.num_bytes, "not connected");
return Read_result::READ_OK; return Read_result::READ_OK;
} }
case Lwip_file_handle::REMOTE: case Lwip_file_handle::REMOTE:
if (count < ENDPOINT_STRLEN_MAX) { if (dst.num_bytes < ENDPOINT_STRLEN_MAX) {
Genode::error("VFS LwIP: accept file read buffer is too small"); Genode::error("VFS LwIP: accept file read buffer is too small");
result = Read_result::READ_ERR_INVALID; result = Read_result::READ_ERR_INVALID;
} else } else
@ -948,14 +943,14 @@ class Lwip::Udp_socket_dir final :
_packet_queue.head([&] (Packet &pkt) { _packet_queue.head([&] (Packet &pkt) {
char const *ip_str = ipaddr_ntoa(&pkt.addr); char const *ip_str = ipaddr_ntoa(&pkt.addr);
/* TODO: IPv6 */ /* TODO: IPv6 */
out_count = Genode::snprintf(dst, count, "%s:%d\n", out_count = Genode::snprintf(dst.start, dst.num_bytes, "%s:%d\n",
ip_str, pkt.port); ip_str, pkt.port);
result = Read_result::READ_OK; result = Read_result::READ_OK;
}); });
} else { } else {
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip); char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
/* TODO: [IPv6]:port */ /* TODO: [IPv6]:port */
out_count = Genode::snprintf(dst, count, "%s:%d\n", out_count = Genode::snprintf(dst.start, dst.num_bytes, "%s:%d\n",
ip_str, _pcb->remote_port); ip_str, _pcb->remote_port);
result = Read_result::READ_OK; result = Read_result::READ_OK;
} }
@ -965,8 +960,8 @@ class Lwip::Udp_socket_dir final :
/* /*
* Print the location of this socket directory * Print the location of this socket directory
*/ */
out_count = Genode::snprintf( out_count = Genode::snprintf(dst.start, dst.num_bytes, "udp/%s\n",
dst, count, "udp/%s\n", name().string()); name().string());
return Read_result::READ_OK; return Read_result::READ_OK;
break; break;
@ -982,18 +977,20 @@ class Lwip::Udp_socket_dir final :
} }
Write_result write(Lwip_file_handle &handle, Write_result write(Lwip_file_handle &handle,
char const *src, file_size count, Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
switch (handle.kind) { switch (handle.kind) {
case Lwip_file_handle::DATA: { case Lwip_file_handle::DATA: {
if (ip_addr_isany(&_to_addr)) break; if (ip_addr_isany(&_to_addr)) break;
file_size remain = count; char const *src_ptr = src.start;
size_t remain = src.num_bytes;
while (remain) { while (remain) {
pbuf *buf = pbuf_alloc(PBUF_RAW, remain, PBUF_RAM); pbuf * const buf = pbuf_alloc(PBUF_RAW, remain, PBUF_RAM);
pbuf_take(buf, src, buf->tot_len); pbuf_take(buf, src_ptr, buf->tot_len);
err_t err = udp_sendto(_pcb, buf, &_to_addr, _to_port); err_t err = udp_sendto(_pcb, buf, &_to_addr, _to_port);
pbuf_free(buf); pbuf_free(buf);
@ -1002,9 +999,9 @@ class Lwip::Udp_socket_dir final :
else if (err != ERR_OK) else if (err != ERR_OK)
return Write_result::WRITE_ERR_IO; return Write_result::WRITE_ERR_IO;
remain -= buf->tot_len; remain -= buf->tot_len;
src += buf->tot_len; src_ptr += buf->tot_len;
} }
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
@ -1013,12 +1010,11 @@ class Lwip::Udp_socket_dir final :
return Write_result::WRITE_ERR_INVALID; return Write_result::WRITE_ERR_INVALID;
} else { } else {
char buf[ENDPOINT_STRLEN_MAX]; char buf[ENDPOINT_STRLEN_MAX];
copy_cstring(buf, src, min(count+1, sizeof(buf))); copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
_to_port = remove_port(buf); _to_port = remove_port(buf);
out_count = count;
if (ipaddr_aton(buf, &_to_addr)) { if (ipaddr_aton(buf, &_to_addr)) {
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
} }
@ -1026,19 +1022,19 @@ class Lwip::Udp_socket_dir final :
} }
case Lwip_file_handle::BIND: { case Lwip_file_handle::BIND: {
if (count < ENDPOINT_STRLEN_MAX) { if (src.num_bytes < ENDPOINT_STRLEN_MAX) {
char buf[ENDPOINT_STRLEN_MAX]; char buf[ENDPOINT_STRLEN_MAX];
ip_addr_t addr; ip_addr_t addr;
u16_t port; u16_t port;
copy_cstring(buf, src, min(count+1, sizeof(buf))); copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
port = remove_port(buf); port = remove_port(buf);
if (!ipaddr_aton(buf, &addr)) if (!ipaddr_aton(buf, &addr))
break; break;
err_t err = udp_bind(_pcb, &addr, port); err_t err = udp_bind(_pcb, &addr, port);
if (err == ERR_OK) { if (err == ERR_OK) {
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
return Write_result::WRITE_ERR_IO; return Write_result::WRITE_ERR_IO;
@ -1047,10 +1043,10 @@ class Lwip::Udp_socket_dir final :
} }
case Lwip_file_handle::CONNECT: { case Lwip_file_handle::CONNECT: {
if (count < ENDPOINT_STRLEN_MAX) { if (src.num_bytes < ENDPOINT_STRLEN_MAX) {
char buf[ENDPOINT_STRLEN_MAX]; char buf[ENDPOINT_STRLEN_MAX];
copy_cstring(buf, src, min(count+1, sizeof(buf))); copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
_to_port = remove_port(buf); _to_port = remove_port(buf);
if (!ipaddr_aton(buf, &_to_addr)) if (!ipaddr_aton(buf, &_to_addr))
@ -1062,7 +1058,7 @@ class Lwip::Udp_socket_dir final :
return Write_result::WRITE_ERR_IO; return Write_result::WRITE_ERR_IO;
} }
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
break; break;
@ -1303,9 +1299,8 @@ class Lwip::Tcp_socket_dir final :
return false; return false;
} }
Read_result read(Lwip_file_handle &handle, Read_result read(Lwip_file_handle &handle, Byte_range_ptr const &dst,
char *dst, file_size count, size_t &out_count) override
file_size &out_count) override
{ {
switch (handle.kind) { switch (handle.kind) {
@ -1328,8 +1323,8 @@ class Lwip::Tcp_socket_dir final :
: Read_result::READ_OK; : Read_result::READ_OK;
} }
u16_t const ucount = min(count, (file_size)0xffff); u16_t const ucount = min(dst.num_bytes, (file_size)0xffff);
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst, ucount, 0); u16_t const n = pbuf_copy_partial(_recv_pbuf, dst.start, ucount, 0);
_recv_pbuf = pbuf_free_header(_recv_pbuf, n); _recv_pbuf = pbuf_free_header(_recv_pbuf, n);
@ -1347,19 +1342,19 @@ class Lwip::Tcp_socket_dir final :
case Lwip_file_handle::PEEK: case Lwip_file_handle::PEEK:
if (_recv_pbuf != nullptr) { if (_recv_pbuf != nullptr) {
u16_t const ucount = min(count, (file_size)0xffff); u16_t const ucount = min(dst.num_bytes, 0xffffUL);
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst, ucount, 0); u16_t const n = pbuf_copy_partial(_recv_pbuf, dst.start, ucount, 0);
out_count = n; out_count = n;
} }
return Read_result::READ_OK; return Read_result::READ_OK;
case Lwip_file_handle::REMOTE: case Lwip_file_handle::REMOTE:
if (state == READY) { if (state == READY) {
if (count < ENDPOINT_STRLEN_MAX) if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip); char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
/* TODO: [IPv6]:port */ /* TODO: [IPv6]:port */
out_count = Genode::snprintf(dst, count, "%s:%d\n", out_count = Genode::snprintf(dst.start, dst.num_bytes, "%s:%d\n",
ip_str, _pcb->remote_port); ip_str, _pcb->remote_port);
return Read_result::READ_OK; return Read_result::READ_OK;
} else { } else {
@ -1385,7 +1380,7 @@ class Lwip::Tcp_socket_dir final :
handle.kind = Lwip_file_handle::LOCATION; handle.kind = Lwip_file_handle::LOCATION;
/* read the location of the new socket directory */ /* read the location of the new socket directory */
Read_result result = handle.read(dst, count, out_count); Read_result result = handle.read(dst, out_count);
return result; return result;
} }
@ -1397,8 +1392,8 @@ class Lwip::Tcp_socket_dir final :
/* /*
* Print the location of this socket directory * Print the location of this socket directory
*/ */
out_count = Genode::snprintf( out_count = Genode::snprintf(dst.start, dst.num_bytes, "tcp/%s\n",
dst, count, "tcp/%s\n", name().string()); name().string());
return Read_result::READ_OK; return Read_result::READ_OK;
break; break;
@ -1410,20 +1405,19 @@ class Lwip::Tcp_socket_dir final :
for (Pcb_pending *p = _pcb_pending.first(); p; p = p->next()) for (Pcb_pending *p = _pcb_pending.first(); p; p = p->next())
++pending_count; ++pending_count;
out_count = Genode::snprintf( out_count = Genode::snprintf(dst.start, dst.num_bytes, "%d\n", pending_count);
dst, count, "%d\n", pending_count);
return Read_result::READ_OK; return Read_result::READ_OK;
} }
case Lwip_file_handle::LOCAL: case Lwip_file_handle::LOCAL:
case Lwip_file_handle::BIND: case Lwip_file_handle::BIND:
if (state != CLOSED) { if (state != CLOSED) {
if (count < ENDPOINT_STRLEN_MAX) if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
char const *ip_str = ipaddr_ntoa(&_pcb->local_ip); char const *ip_str = ipaddr_ntoa(&_pcb->local_ip);
/* TODO: [IPv6]:port */ /* TODO: [IPv6]:port */
out_count = Genode::snprintf( out_count = Genode::snprintf(dst.start, dst.num_bytes,
dst, count, "%s:%d\n", ip_str, _pcb->local_port); "%s:%d\n", ip_str, _pcb->local_port);
return Read_result::READ_OK; return Read_result::READ_OK;
} }
break; break;
@ -1431,10 +1425,10 @@ class Lwip::Tcp_socket_dir final :
case Lwip_file_handle::CONNECT: case Lwip_file_handle::CONNECT:
switch (state) { switch (state) {
case READY: case READY:
out_count = Genode::snprintf(dst, count, "connected"); out_count = Genode::snprintf(dst.start, dst.num_bytes, "connected");
break; break;
default: default:
out_count = Genode::snprintf(dst, count, "connection refused"); out_count = Genode::snprintf(dst.start, dst.num_bytes, "connection refused");
break; break;
} }
return Read_result::READ_OK; return Read_result::READ_OK;
@ -1469,9 +1463,8 @@ class Lwip::Tcp_socket_dir final :
return false; return false;
} }
Write_result write(Lwip_file_handle &handle, Write_result write(Lwip_file_handle &handle, Const_byte_range_ptr const &src,
char const *src, file_size count, size_t &out_count) override
file_size &out_count) override
{ {
if (_pcb == NULL) { if (_pcb == NULL) {
/* socket is closed */ /* socket is closed */
@ -1482,7 +1475,10 @@ class Lwip::Tcp_socket_dir final :
case Lwip_file_handle::DATA: case Lwip_file_handle::DATA:
if (state == READY) { if (state == READY) {
Write_result res = Write_result::WRITE_ERR_WOULD_BLOCK; Write_result res = Write_result::WRITE_ERR_WOULD_BLOCK;
file_size out = 0; size_t out = 0;
size_t count = src.num_bytes;
char const *src_ptr = src.start;
/* /*
* write in a loop to account for LwIP chunking * write in a loop to account for LwIP chunking
* and the availability of send buffer * and the availability of send buffer
@ -1491,7 +1487,7 @@ class Lwip::Tcp_socket_dir final :
u16_t n = min(count, tcp_sndbuf(_pcb)); u16_t n = min(count, tcp_sndbuf(_pcb));
/* queue data to outgoing TCP buffer */ /* queue data to outgoing TCP buffer */
err_t err = tcp_write(_pcb, src, n, TCP_WRITE_FLAG_COPY); err_t err = tcp_write(_pcb, src_ptr, n, TCP_WRITE_FLAG_COPY);
if (err != ERR_OK) { if (err != ERR_OK) {
Genode::error("lwIP: tcp_write failed, error ", (int)-err); Genode::error("lwIP: tcp_write failed, error ", (int)-err);
res = Write_result::WRITE_ERR_IO; res = Write_result::WRITE_ERR_IO;
@ -1499,8 +1495,9 @@ class Lwip::Tcp_socket_dir final :
} }
count -= n; count -= n;
src += n; src_ptr += n;
out += n; out += n;
/* pending_ack += n; */ /* pending_ack += n; */
res = Write_result::WRITE_OK; res = Write_result::WRITE_OK;
} }
@ -1520,12 +1517,12 @@ class Lwip::Tcp_socket_dir final :
break; break;
case Lwip_file_handle::BIND: case Lwip_file_handle::BIND:
if ((state == NEW) && (count < ENDPOINT_STRLEN_MAX)) { if ((state == NEW) && (src.num_bytes < ENDPOINT_STRLEN_MAX)) {
char buf[ENDPOINT_STRLEN_MAX]; char buf[ENDPOINT_STRLEN_MAX];
ip_addr_t addr; ip_addr_t addr;
u16_t port = 0; u16_t port = 0;
Genode::copy_cstring(buf, src, min(count+1, sizeof(buf))); Genode::copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
port = remove_port(buf); port = remove_port(buf);
if (!ipaddr_aton(buf, &addr)) if (!ipaddr_aton(buf, &addr))
@ -1534,19 +1531,19 @@ class Lwip::Tcp_socket_dir final :
err_t err = tcp_bind(_pcb, &addr, port); err_t err = tcp_bind(_pcb, &addr, port);
if (err == ERR_OK) { if (err == ERR_OK) {
state = BOUND; state = BOUND;
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
} }
break; break;
case Lwip_file_handle::CONNECT: case Lwip_file_handle::CONNECT:
if (((state == NEW) || (state == BOUND)) && (count < ENDPOINT_STRLEN_MAX-1)) { if (((state == NEW) || (state == BOUND)) && (src.num_bytes < ENDPOINT_STRLEN_MAX-1)) {
char buf[ENDPOINT_STRLEN_MAX]; char buf[ENDPOINT_STRLEN_MAX];
ip_addr_t addr; ip_addr_t addr;
u16_t port = 0; u16_t port = 0;
copy_cstring(buf, src, min(count+1, sizeof(buf))); copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
port = remove_port(buf); port = remove_port(buf);
if (!ipaddr_aton(buf, &addr)) if (!ipaddr_aton(buf, &addr))
break; break;
@ -1557,17 +1554,17 @@ class Lwip::Tcp_socket_dir final :
return Write_result::WRITE_ERR_IO; return Write_result::WRITE_ERR_IO;
} }
state = CONNECT; state = CONNECT;
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
break; break;
case Lwip_file_handle::LISTEN: case Lwip_file_handle::LISTEN:
if ((state == BOUND) && (count < 11)) { if ((state == BOUND) && (src.num_bytes < 11)) {
unsigned long backlog = TCP_DEFAULT_LISTEN_BACKLOG; unsigned long backlog = TCP_DEFAULT_LISTEN_BACKLOG;
char buf[12]; char buf[12];
copy_cstring(buf, src, min(count+1, sizeof(buf))); copy_cstring(buf, src.start, min(src.num_bytes + 1, sizeof(buf)));
Genode::ascii_to_unsigned(buf, backlog, 10); Genode::ascii_to_unsigned(buf, backlog, 10);
/* this replaces the PCB so set the callbacks again */ /* this replaces the PCB so set the callbacks again */
@ -1575,7 +1572,7 @@ class Lwip::Tcp_socket_dir final :
tcp_arg(_pcb, this); tcp_arg(_pcb, this);
tcp_accept(_pcb, tcp_accept_callback); tcp_accept(_pcb, tcp_accept_callback);
state = LISTEN; state = LISTEN;
out_count = count; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} }
break; break;
@ -1849,7 +1846,7 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
** Lwip::Directory ** ** Lwip::Directory **
*********************/ *********************/
Read_result readdir(char *, file_size, file_size &) override Read_result readdir(Byte_range_ptr const &, size_t &) override
{ {
Genode::warning(__func__, " NOT_IMPLEMENTED"); Genode::warning(__func__, " NOT_IMPLEMENTED");
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
@ -2012,9 +2009,8 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Write_result write(Vfs_handle *vfs_handle, Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
char const *src, file_size count, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
@ -2022,20 +2018,20 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
return Write_result::WRITE_ERR_INVALID; return Write_result::WRITE_ERR_INVALID;
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle)) if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle))
return handle->write(src, count, out_count); return handle->write(src, out_count);
return Write_result::WRITE_ERR_INVALID; return Write_result::WRITE_ERR_INVALID;
} }
Read_result complete_read(Vfs_handle *vfs_handle, Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
char *dst, file_size count, size_t &out_count) override
file_size &out_count) override
{ {
/* /*
* LwIP buffer operations are limited to sizes that * LwIP buffer operations are limited to sizes that
* can be expressed in sixteen bits * can be expressed in sixteen bits
*/ */
count = Genode::min(count, 0xffffU); Byte_range_ptr const
clipped_dst { dst.start, Genode::min(dst.num_bytes, 0xffffU) };
out_count = 0; out_count = 0;
@ -2045,14 +2041,14 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
} }
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle)) if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle))
return handle->read(dst, count, out_count); return handle->read(clipped_dst, out_count);
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
} }
/** /**
* All reads are unavailable while the network is down * All reads are unavailable while the network is down
*/ */
bool queue_read(Vfs_handle *, file_size) override bool queue_read(Vfs_handle *, size_t) override
{ {
if (_netif.ready()) if (_netif.ready())
return true; return true;

View File

@ -450,7 +450,7 @@ struct Vfs::Oss_file_system::Audio
return false; return false;
} }
bool read(char *buf, file_size buf_size, file_size &out_size) bool read(Byte_range_ptr const &dst, size_t &out_size)
{ {
out_size = 0; out_size = 0;
@ -461,7 +461,7 @@ struct Vfs::Oss_file_system::Audio
return true; return true;
} }
buf_size = min(buf_size, _info.ifrag_bytes); size_t const buf_size = min(dst.num_bytes, _info.ifrag_bytes);
unsigned samples_to_read = buf_size / CHANNELS / sizeof(int16_t); unsigned samples_to_read = buf_size / CHANNELS / sizeof(int16_t);
@ -497,7 +497,7 @@ struct Vfs::Oss_file_system::Audio
for (unsigned c = 0; c < CHANNELS; c++) { for (unsigned c = 0; c < CHANNELS; c++) {
unsigned const buf_index = out_size / sizeof(int16_t); unsigned const buf_index = out_size / sizeof(int16_t);
((int16_t*)buf)[buf_index] = p->content()[_read_sample_offset] * 32768; ((int16_t*)dst.start)[buf_index] = p->content()[_read_sample_offset] * 32768;
out_size += sizeof(int16_t); out_size += sizeof(int16_t);
} }
@ -517,7 +517,7 @@ struct Vfs::Oss_file_system::Audio
return true; return true;
} }
Write_result write(char const *buf, file_size buf_size, file_size &out_size) Write_result write(Const_byte_range_ptr const &src, size_t &out_size)
{ {
using namespace Genode; using namespace Genode;
@ -528,6 +528,8 @@ struct Vfs::Oss_file_system::Audio
bool block_write = false; bool block_write = false;
size_t buf_size = src.num_bytes;
if (buf_size > _info.ofrag_bytes) { if (buf_size > _info.ofrag_bytes) {
buf_size = _info.ofrag_bytes; buf_size = _info.ofrag_bytes;
block_write = true; block_write = true;
@ -584,7 +586,7 @@ struct Vfs::Oss_file_system::Audio
for (unsigned c = 0; c < CHANNELS; c++) { for (unsigned c = 0; c < CHANNELS; c++) {
unsigned const buf_index = out_size / sizeof(int16_t); unsigned const buf_index = out_size / sizeof(int16_t);
int16_t src_sample = ((int16_t const*)buf)[buf_index]; int16_t src_sample = ((int16_t const*)src.start)[buf_index];
dest[c][_write_sample_offset] = ((float)src_sample) / 32768.0f; dest[c][_write_sample_offset] = ((float)src_sample) / 32768.0f;
out_size += sizeof(int16_t); out_size += sizeof(int16_t);
} }
@ -648,17 +650,17 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
_audio { audio } _audio { audio }
{ } { }
Read_result read(char *buf, file_size buf_size, file_size &out_count) override Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
{ {
if (!buf) if (!dst.start)
return READ_ERR_INVALID; return READ_ERR_INVALID;
if (buf_size == 0) { if (dst.num_bytes == 0) {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
bool success = _audio.read(buf, buf_size, out_count); bool success = _audio.read(dst, out_count);
if (success) { if (success) {
if (out_count == 0) { if (out_count == 0) {
@ -670,10 +672,9 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
Write_result write(char const *buf, file_size buf_size, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
Write_result const result = _audio.write(buf, buf_size, out_count); Write_result const result = _audio.write(src, out_count);
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) { if (result == Write_result::WRITE_ERR_WOULD_BLOCK) {
blocked = true; blocked = true;

View File

@ -197,13 +197,15 @@ struct Genode::Directory : Noncopyable, Interface
_io.commit_and_wait(); _io.commit_and_wait();
Vfs::File_io_service::Read_result read_result; Vfs::File_io_service::Read_result read_result;
Vfs::file_size out_count = 0;
size_t out_count = 0;
for (;;) { for (;;) {
read_result = _handle->fs().complete_read(_handle, Byte_range_ptr const dst { (char*)&entry._dirent,
(char*)&entry._dirent, sizeof(entry._dirent) };
sizeof(entry._dirent),
read_result = _handle->fs().complete_read(_handle, dst,
out_count); out_count);
if (read_result != Vfs::File_io_service::READ_QUEUED) if (read_result != Vfs::File_io_service::READ_QUEUED)
@ -297,8 +299,8 @@ struct Genode::Directory : Noncopyable, Interface
char buf[MAX_PATH_LEN]; char buf[MAX_PATH_LEN];
Vfs::file_size count = sizeof(buf)-1; size_t count = sizeof(buf)-1;
Vfs::file_size out_count = 0; size_t out_count = 0;
while (!link_handle->fs().queue_read(link_handle, count)) { while (!link_handle->fs().queue_read(link_handle, count)) {
_io.commit_and_wait(); _io.commit_and_wait();
@ -308,7 +310,7 @@ struct Genode::Directory : Noncopyable, Interface
for (;;) { for (;;) {
result = link_handle->fs().complete_read( result = link_handle->fs().complete_read(
link_handle, buf, count, out_count); link_handle, Byte_range_ptr(buf, count), out_count);
if (result != File_io_service::READ_QUEUED) if (result != File_io_service::READ_QUEUED)
break; break;
@ -470,12 +472,14 @@ class Genode::Readonly_file : public File
Vfs::File_io_service::Read_result result; Vfs::File_io_service::Read_result result;
Vfs::file_size read_bytes { }; /* byte count for this iteration */ size_t read_bytes = 0; /* byte count for this iteration */
for (;;) { for (;;) {
result = _handle->fs().complete_read(_handle,
range.start + total, Byte_range_ptr const partial_range { range.start + total,
range.num_bytes - total, range.num_bytes - total };
result = _handle->fs().complete_read(_handle, partial_range,
read_bytes); read_bytes);
if (result != Vfs::File_io_service::READ_QUEUED) if (result != Vfs::File_io_service::READ_QUEUED)
@ -759,21 +763,25 @@ class Genode::Writeable_file : Noncopyable
} }
static Append_result _append(Vfs::Vfs_handle &handle, Vfs::Env::Io &io, static Append_result _append(Vfs::Vfs_handle &handle, Vfs::Env::Io &io,
char const *src, size_t size) Const_byte_range_ptr const &src)
{ {
bool write_error = false; bool write_error = false;
size_t remaining_bytes = size; size_t remaining_bytes = src.num_bytes;
char const * src_ptr = src.start;
while (remaining_bytes > 0 && !write_error) { while (remaining_bytes > 0 && !write_error) {
bool stalled = false; bool stalled = false;
Vfs::file_size out_count = 0; size_t out_count = 0;
using Write_result = Vfs::File_io_service::Write_result; using Write_result = Vfs::File_io_service::Write_result;
switch (handle.fs().write(&handle, src, remaining_bytes, out_count)) { Const_byte_range_ptr const partial_src { src_ptr, remaining_bytes };
switch (handle.fs().write(&handle, partial_src, out_count)) {
case Write_result::WRITE_ERR_WOULD_BLOCK: case Write_result::WRITE_ERR_WOULD_BLOCK:
stalled = true; stalled = true;
@ -785,9 +793,9 @@ class Genode::Writeable_file : Noncopyable
break; break;
case Write_result::WRITE_OK: case Write_result::WRITE_OK:
out_count = min((Vfs::file_size)remaining_bytes, out_count); out_count = min(remaining_bytes, out_count);
remaining_bytes -= (size_t)out_count; remaining_bytes -= (size_t)out_count;
src += out_count; src_ptr += out_count;
handle.advance_seek(out_count); handle.advance_seek(out_count);
break; break;
}; };
@ -834,8 +842,11 @@ class Genode::Append_file : public Writeable_file
_handle.ds().close(&_handle); _handle.ds().close(&_handle);
} }
Append_result append(Const_byte_range_ptr const &src) {
return _append(_handle, _io, src); }
Append_result append(char const *src, size_t size) { Append_result append(char const *src, size_t size) {
return _append(_handle, _io, src, size); } return _append(_handle, _io, Const_byte_range_ptr(src, size)); }
}; };
@ -873,8 +884,11 @@ class Genode::New_file : public Writeable_file
_handle.ds().close(&_handle); _handle.ds().close(&_handle);
} }
Append_result append(Const_byte_range_ptr const &src) {
return _append(_handle, _io, src); }
Append_result append(char const *src, size_t size) { Append_result append(char const *src, size_t size) {
return _append(_handle, _io, src, size); } return _append(_handle, _io, Const_byte_range_ptr(src, size)); }
}; };

View File

@ -42,28 +42,34 @@ class File_system::Chunk_base : Noncopyable
class Index_out_of_range { }; class Index_out_of_range { };
/*
* Use 'size_t' instead of 'seek_off_t' because we can never seek
* outside the addressable RAM
*/
struct Seek { size_t value; };
protected: protected:
seek_off_t const _base_offset; Seek const _base_offset { ~0UL };
size_t _num_entries; /* corresponds to last used entry */
size_t _num_entries = 0; /* corresponds to last used entry */
/** /**
* Test if specified range lies within the chunk * Test if specified range lies within the chunk
*/ */
void assert_valid_range(seek_off_t start, size_t len, void assert_valid_range(Seek start, size_t len,
file_size_t chunk_size) const size_t chunk_size) const
{ {
if (zero()) return; if (zero()) return;
if (start < _base_offset) if (start.value < _base_offset.value)
throw Index_out_of_range(); throw Index_out_of_range();
if (start + len > _base_offset + chunk_size) if (start.value + len > _base_offset.value + chunk_size)
throw Index_out_of_range(); throw Index_out_of_range();
} }
Chunk_base(seek_off_t base_offset) Chunk_base(Seek base_offset) : _base_offset(base_offset) { }
: _base_offset(base_offset), _num_entries(0) { }
/** /**
* Construct zero chunk * Construct zero chunk
@ -73,19 +79,19 @@ class File_system::Chunk_base : Noncopyable
* for each chunk type, the base offset is meaningless. We use a * for each chunk type, the base offset is meaningless. We use a
* base offset of ~0 as marker to identify zero chunks. * base offset of ~0 as marker to identify zero chunks.
*/ */
Chunk_base() : _base_offset(~0L), _num_entries(0) { } Chunk_base() { }
public: public:
/** /**
* Return absolute base offset of chunk in bytes * Return absolute base offset of chunk in bytes
*/ */
seek_off_t base_offset() const { return _base_offset; } Seek base_offset() const { return _base_offset; }
/** /**
* Return true if chunk is a read-only zero chunk * Return true if chunk is a read-only zero chunk
*/ */
bool zero() const { return _base_offset == (seek_off_t)(~0L); } bool zero() const { return _base_offset.value == ~0UL; }
/** /**
* Return true if chunk has no allocated sub chunks * Return true if chunk has no allocated sub chunks
@ -117,7 +123,7 @@ class File_system::Chunk : public Chunk_base
* signature of the constructor compatible to the constructor * signature of the constructor compatible to the constructor
* of 'Chunk_index'. * of 'Chunk_index'.
*/ */
Chunk(Allocator &, seek_off_t base_offset) Chunk(Allocator &, Seek base_offset)
: :
Chunk_base(base_offset) Chunk_base(base_offset)
{ {
@ -136,43 +142,43 @@ class File_system::Chunk : public Chunk_base
* entry + 1. It does not correlate to the number of actually * entry + 1. It does not correlate to the number of actually
* allocated entries (there may be ranges of zero blocks). * allocated entries (there may be ranges of zero blocks).
*/ */
file_size_t used_size() const { return _num_entries; } size_t used_size() const { return _num_entries; }
void write(char const *src, size_t len, seek_off_t seek_offset) void write(Const_byte_range_ptr const &src, Seek at)
{ {
assert_valid_range(seek_offset, len, SIZE); assert_valid_range(at, src.num_bytes, SIZE);
/* offset relative to this chunk */ /* offset relative to this chunk */
seek_off_t const local_offset = seek_offset - base_offset(); size_t const local_offset = at.value - base_offset().value;
memcpy(&_data[local_offset], src, len); memcpy(&_data[local_offset], src.start, src.num_bytes);
_num_entries = max(_num_entries, (size_t)(local_offset + len)); _num_entries = max(_num_entries, local_offset + src.num_bytes);
} }
void read(char *dst, size_t len, seek_off_t seek_offset) const void read(Byte_range_ptr const &dst, Seek at) const
{ {
assert_valid_range(seek_offset, len, SIZE); assert_valid_range(at, dst.num_bytes, SIZE);
memcpy(dst, &_data[seek_offset - base_offset()], len); memcpy(dst.start, &_data[at.value - base_offset().value], dst.num_bytes);
} }
void truncate(file_size_t size) void truncate(Seek at)
{ {
assert_valid_range(size, 0, SIZE); assert_valid_range(at, 0, SIZE);
/* /*
* Offset of the first free position (relative to the beginning * Offset of the first free position (relative to the beginning
* this chunk). * this chunk).
*/ */
seek_off_t const local_offset = size - base_offset(); size_t const local_offset = at.value - base_offset().value;
if (local_offset >= _num_entries) if (local_offset >= _num_entries)
return; return;
memset(&_data[local_offset], 0, (size_t)(_num_entries - local_offset)); memset(&_data[local_offset], 0, _num_entries - local_offset);
_num_entries = (size_t)local_offset; _num_entries = local_offset;
} }
}; };
@ -223,7 +229,7 @@ class File_system::Chunk_index : public Chunk_base
if (_entries[index]) if (_entries[index])
return *_entries[index]; return *_entries[index];
seek_off_t entry_offset = base_offset() + index*ENTRY_SIZE; Seek const entry_offset { base_offset().value + index*ENTRY_SIZE };
_entries[index] = new (&_alloc) Entry(_alloc, entry_offset); _entries[index] = new (&_alloc) Entry(_alloc, entry_offset);
@ -255,17 +261,17 @@ class File_system::Chunk_index : public Chunk_base
* The caller of this function must make sure that the offset * The caller of this function must make sure that the offset
* parameter is within the bounds of the chunk. * parameter is within the bounds of the chunk.
*/ */
unsigned _index_by_offset(seek_off_t offset) const unsigned _index_by_offset(Seek offset) const
{ {
return (unsigned)((offset - base_offset()) / ENTRY_SIZE); return (unsigned)((offset.value - base_offset().value) / ENTRY_SIZE);
} }
/** /**
* Apply operation 'func' to a range of entries * Apply operation 'func' to a range of entries
*/ */
template <typename THIS, typename DATA, typename FUNC> template <typename THIS, typename RANGE_PTR, typename FUNC>
static void _range_op(THIS &obj, DATA *data, size_t len, static void _range_op(THIS &obj, RANGE_PTR const &range_ptr,
seek_off_t seek_offset, FUNC const &func) Seek at, FUNC const &func)
{ {
/* /*
* Depending on whether this function is called for reading * Depending on whether this function is called for reading
@ -275,11 +281,14 @@ class File_system::Chunk_index : public Chunk_base
*/ */
typedef typename FUNC::Entry Const_qualified_entry; typedef typename FUNC::Entry Const_qualified_entry;
obj.assert_valid_range(seek_offset, len, SIZE); auto data_ptr = range_ptr.start;
size_t len = range_ptr.num_bytes;
obj.assert_valid_range(at, len, SIZE);
while (len > 0) { while (len > 0) {
unsigned const index = obj._index_by_offset(seek_offset); unsigned const index = obj._index_by_offset(at);
Const_qualified_entry &entry = FUNC::lookup(obj, index); Const_qualified_entry &entry = FUNC::lookup(obj, index);
@ -291,20 +300,20 @@ class File_system::Chunk_index : public Chunk_base
* zero chunk, which has no defined base offset. Therefore, * zero chunk, which has no defined base offset. Therefore,
* we calculate the base offset via index*ENTRY_SIZE. * we calculate the base offset via index*ENTRY_SIZE.
*/ */
seek_off_t const local_seek_offset = size_t const local_seek_offset =
seek_offset - obj.base_offset() - index*ENTRY_SIZE; at.value - obj.base_offset().value - index*ENTRY_SIZE;
/* available capacity at 'entry' starting at seek offset */ /* available capacity at 'entry' starting at seek offset */
size_t const capacity = ENTRY_SIZE - (size_t)local_seek_offset; size_t const capacity = ENTRY_SIZE - local_seek_offset;
size_t const curr_len = min(len, capacity); size_t const curr_len = min(len, capacity);
/* apply functor (read or write) to entry */ /* apply functor (read or write) to entry */
func(entry, data, (size_t)curr_len, seek_offset); func(entry, RANGE_PTR(data_ptr, curr_len), at);
/* advance to next entry */ /* advance to next entry */
len -= curr_len; len -= curr_len;
data += curr_len; data_ptr += curr_len;
seek_offset += curr_len; at.value += curr_len;
} }
} }
@ -315,10 +324,9 @@ class File_system::Chunk_index : public Chunk_base
static Entry &lookup(Chunk_index &chunk, unsigned i) { static Entry &lookup(Chunk_index &chunk, unsigned i) {
return chunk._entry_for_writing(i); } return chunk._entry_for_writing(i); }
void operator () (Entry &entry, char const *src, size_t len, void operator () (Entry &entry, Const_byte_range_ptr const &src, Seek at) const
seek_off_t seek_offset) const
{ {
entry.write(src, len, seek_offset); entry.write(src, at);
} }
}; };
@ -329,13 +337,12 @@ class File_system::Chunk_index : public Chunk_base
static Entry &lookup(Chunk_index const &chunk, unsigned i) { static Entry &lookup(Chunk_index const &chunk, unsigned i) {
return chunk._entry_for_reading(i); } return chunk._entry_for_reading(i); }
void operator () (Entry &entry, char *dst, size_t len, void operator () (Entry &entry, Byte_range_ptr const &dst, Seek at) const
seek_off_t seek_offset) const
{ {
if (entry.zero()) if (entry.zero())
memset(dst, 0, len); memset(dst.start, 0, dst.num_bytes);
else else
entry.read(dst, len, seek_offset); entry.read(dst, at);
} }
}; };
@ -362,7 +369,7 @@ class File_system::Chunk_index : public Chunk_base
* indices and chunks * indices and chunks
* \param base_offset absolute offset of the chunk in bytes * \param base_offset absolute offset of the chunk in bytes
*/ */
Chunk_index(Allocator &alloc, seek_off_t base_offset) Chunk_index(Allocator &alloc, Seek base_offset)
: Chunk_base(base_offset), _alloc(alloc) { _init_entries(); } : Chunk_base(base_offset), _alloc(alloc) { _init_entries(); }
/** /**
@ -385,13 +392,13 @@ class File_system::Chunk_index : public Chunk_base
* The returned value corresponds to the position after the highest * The returned value corresponds to the position after the highest
* offset that was written to. * offset that was written to.
*/ */
file_size_t used_size() const size_t used_size() const
{ {
if (_num_entries == 0) if (_num_entries == 0)
return 0; return 0;
/* size of entries that lie completely within the used range */ /* size of entries that lie completely within the used range */
file_size_t const size_whole_entries = ENTRY_SIZE*(_num_entries - 1); size_t const size_whole_entries = ENTRY_SIZE*(_num_entries - 1);
Entry *last_entry = _entries[_num_entries - 1]; Entry *last_entry = _entries[_num_entries - 1];
if (!last_entry) if (!last_entry)
@ -403,17 +410,17 @@ class File_system::Chunk_index : public Chunk_base
/** /**
* Write data to chunk * Write data to chunk
*/ */
void write(char const *src, size_t len, seek_off_t seek_offset) void write(Const_byte_range_ptr const &src, Seek at)
{ {
_range_op(*this, src, len, seek_offset, Write_func()); _range_op(*this, src, at, Write_func());
} }
/** /**
* Read data from chunk * Read data from chunk
*/ */
void read(char *dst, size_t len, seek_off_t seek_offset) const void read(Byte_range_ptr const &dst, Seek at) const
{ {
_range_op(*this, dst, len, seek_offset, Read_func()); _range_op(*this, dst, at, Read_func());
} }
/** /**
@ -424,9 +431,9 @@ class File_system::Chunk_index : public Chunk_base
* by 'used_size' refers always to the position of the last byte * by 'used_size' refers always to the position of the last byte
* written to the chunk. * written to the chunk.
*/ */
void truncate(file_size_t size) void truncate(Seek at)
{ {
unsigned const trunc_index = _index_by_offset(size); unsigned const trunc_index = _index_by_offset(at);
if (trunc_index >= _num_entries) if (trunc_index >= _num_entries)
return; return;
@ -436,7 +443,7 @@ class File_system::Chunk_index : public Chunk_base
/* traverse into sub chunks */ /* traverse into sub chunks */
if (_entries[trunc_index]) if (_entries[trunc_index])
_entries[trunc_index]->truncate(size); _entries[trunc_index]->truncate(at);
_num_entries = trunc_index + 1; _num_entries = trunc_index + 1;

View File

@ -330,8 +330,8 @@ class Vfs::Dir_file_system : public File_system
} }
Read_result _complete_read_of_file_systems(Dir_vfs_handle *dir_vfs_handle, Read_result _complete_read_of_file_systems(Dir_vfs_handle *dir_vfs_handle,
char *dst, file_size count, Byte_range_ptr const &dst,
file_size &out_count) size_t &out_count)
{ {
if (!dir_vfs_handle->queued_read_handle) { if (!dir_vfs_handle->queued_read_handle) {
@ -340,10 +340,10 @@ class Vfs::Dir_file_system : public File_system
* fs->opendir() failed * fs->opendir() failed
*/ */
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
Dirent &dirent = *(Dirent*)dst; Dirent &dirent = *(Dirent*)dst.start;
dirent = Dirent { }; dirent = Dirent { };
out_count = sizeof(Dirent); out_count = sizeof(Dirent);
@ -353,7 +353,7 @@ class Vfs::Dir_file_system : public File_system
Read_result result = dir_vfs_handle->queued_read_handle->fs(). Read_result result = dir_vfs_handle->queued_read_handle->fs().
complete_read(dir_vfs_handle->queued_read_handle, complete_read(dir_vfs_handle->queued_read_handle,
dst, count, out_count); dst, out_count);
if (result == READ_QUEUED) if (result == READ_QUEUED)
return result; return result;
@ -893,12 +893,12 @@ class Vfs::Dir_file_system : public File_system
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Write_result write(Vfs_handle *, char const *, file_size, file_size &) override Write_result write(Vfs_handle *, Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
bool queue_read(Vfs_handle *vfs_handle, file_size) override bool queue_read(Vfs_handle *vfs_handle, size_t) override
{ {
Dir_vfs_handle *dir_vfs_handle = Dir_vfs_handle *dir_vfs_handle =
static_cast<Dir_vfs_handle*>(vfs_handle); static_cast<Dir_vfs_handle*>(vfs_handle);
@ -913,23 +913,23 @@ class Vfs::Dir_file_system : public File_system
} }
Read_result complete_read(Vfs_handle *vfs_handle, Read_result complete_read(Vfs_handle *vfs_handle,
char *dst, file_size count, Byte_range_ptr const &dst,
file_size &out_count) override size_t &out_count) override
{ {
out_count = 0; out_count = 0;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
Dir_vfs_handle *dir_vfs_handle = Dir_vfs_handle *dir_vfs_handle =
static_cast<Dir_vfs_handle*>(vfs_handle); static_cast<Dir_vfs_handle*>(vfs_handle);
if (_vfs_root) if (_vfs_root)
return _complete_read_of_file_systems(dir_vfs_handle, dst, count, out_count); return _complete_read_of_file_systems(dir_vfs_handle, dst, out_count);
if (_top_dir(dir_vfs_handle->path.base())) { if (_top_dir(dir_vfs_handle->path.base())) {
Dirent &dirent = *(Dirent*)dst; Dirent &dirent = *(Dirent*)dst.start;
file_offset const index = vfs_handle->seek() / sizeof(Dirent); file_offset const index = vfs_handle->seek() / sizeof(Dirent);
@ -957,7 +957,7 @@ class Vfs::Dir_file_system : public File_system
return READ_OK; return READ_OK;
} }
return _complete_read_of_file_systems(dir_vfs_handle, dst, count, out_count); return _complete_read_of_file_systems(dir_vfs_handle, dst, out_count);
} }
Ftruncate_result ftruncate(Vfs_handle *, file_size) override Ftruncate_result ftruncate(Vfs_handle *, file_size) override

View File

@ -30,9 +30,8 @@ struct Vfs::File_io_service : Interface
enum Write_result { WRITE_ERR_WOULD_BLOCK, WRITE_ERR_INVALID, enum Write_result { WRITE_ERR_WOULD_BLOCK, WRITE_ERR_INVALID,
WRITE_ERR_IO, WRITE_OK }; WRITE_ERR_IO, WRITE_OK };
virtual Write_result write(Vfs_handle *vfs_handle, virtual Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &,
char const *buf, file_size buf_size, size_t &out_count) = 0;
file_size &out_count) = 0;
/********** /**********
@ -51,14 +50,13 @@ struct Vfs::File_io_service : Interface
* If the queue is full, the caller can try again after a previous VFS * If the queue is full, the caller can try again after a previous VFS
* request is completed. * request is completed.
*/ */
virtual bool queue_read(Vfs_handle *, file_size) virtual bool queue_read(Vfs_handle *, size_t)
{ {
return true; return true;
} }
virtual Read_result complete_read(Vfs_handle *, char * /* dst */, virtual Read_result complete_read(Vfs_handle *, Byte_range_ptr const &dst,
file_size /* in count */, size_t &out_count) = 0;
file_size & /* out count */) = 0;
/** /**
* Return true if the handle has readable data * Return true if the handle has readable data

View File

@ -51,8 +51,7 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system
Single_vfs_handle(ds, fs, alloc, 0), _buffer(buffer) Single_vfs_handle(ds, fs, alloc, 0), _buffer(buffer)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
@ -60,14 +59,14 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system
return READ_ERR_INVALID; return READ_ERR_INVALID;
char const * const src = _buffer.string() + seek(); char const * const src = _buffer.string() + seek();
size_t const len = min((size_t)(_buffer.length() - seek()), (size_t)count); size_t const len = min(size_t(_buffer.length() - seek()), dst.num_bytes);
Genode::memcpy(dst, src, len); Genode::memcpy(dst.start, src, len);
out_count = len; out_count = len;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -37,11 +37,9 @@ class Vfs::Single_file_system : public File_system
{ {
using Vfs_handle::Vfs_handle; using Vfs_handle::Vfs_handle;
virtual Read_result read(char *dst, file_size count, virtual Read_result read(Byte_range_ptr const &, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual Write_result write(char const *src, file_size count, virtual Write_result write(Const_byte_range_ptr const &, size_t &out_count) = 0;
file_size &out_count) = 0;
virtual Sync_result sync() virtual Sync_result sync()
{ {
@ -83,17 +81,16 @@ class Vfs::Single_file_system : public File_system
_type(type), _rwx(rwx), _filename(filename) _type(type), _rwx(rwx), _filename(filename)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
file_size index = seek() / sizeof(Dirent); file_size index = seek() / sizeof(Dirent);
Dirent &out = *(Dirent*)dst; Dirent &out = *(Dirent*)dst.start;
auto dirent_type = [&] () auto dirent_type = [&] ()
{ {
@ -127,7 +124,7 @@ class Vfs::Single_file_system : public File_system
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
@ -255,27 +252,26 @@ class Vfs::Single_file_system : public File_system
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
file_size count, size_t &out_count) override
file_size &out_count) override
{ {
Single_vfs_handle *handle = Single_vfs_handle *handle =
static_cast<Single_vfs_handle*>(vfs_handle); static_cast<Single_vfs_handle*>(vfs_handle);
if (handle) if (handle)
return handle->read(dst, count, out_count); return handle->read(dst, out_count);
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
Write_result write(Vfs_handle *vfs_handle, char const *src, file_size count, Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
file_size &out_count) override size_t &out_count) override
{ {
Single_vfs_handle *handle = Single_vfs_handle *handle =
static_cast<Single_vfs_handle*>(vfs_handle); static_cast<Single_vfs_handle*>(vfs_handle);
if (handle) if (handle)
return handle->write(src, count, out_count); return handle->write(src, out_count);
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }

View File

@ -47,6 +47,8 @@ namespace Vfs {
using Genode::Interface; using Genode::Interface;
using Genode::String; using Genode::String;
using Genode::size_t; using Genode::size_t;
using Genode::Byte_range_ptr;
using Genode::Const_byte_range_ptr;
struct Timestamp struct Timestamp
{ {

View File

@ -52,8 +52,7 @@ class Vfs::Value_file_system : public Vfs::Single_file_system
_value_fs(value_fs) _value_fs(value_fs)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
@ -61,21 +60,23 @@ class Vfs::Value_file_system : public Vfs::Single_file_system
return READ_ERR_INVALID; return READ_ERR_INVALID;
char const * const src = _buffer.string() + seek(); char const * const src = _buffer.string() + seek();
Genode::size_t const len = min((size_t)(_buffer.length() - seek()), (size_t)count); size_t const len = min((size_t)(_buffer.length() - seek()), dst.num_bytes);
Genode::memcpy(dst, src, len);
memcpy(dst.start, src, len);
out_count = len; out_count = len;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, file_size count, file_size &out_count) override Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
{ {
out_count = 0; out_count = 0;
if (seek() > BUF_SIZE) if (seek() > BUF_SIZE)
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
Genode::size_t const len = min((size_t)(BUF_SIZE- seek()), (size_t)count); size_t const len = min(size_t(BUF_SIZE- seek()), src.num_bytes);
_buffer = Buffer(Genode::Cstring(src, len));
_buffer = Buffer(Genode::Cstring(src.start, len));
out_count = len; out_count = len;
/* inform watchers */ /* inform watchers */

View File

@ -84,7 +84,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
Block_vfs_handle(Block_vfs_handle const &); Block_vfs_handle(Block_vfs_handle const &);
Block_vfs_handle &operator = (Block_vfs_handle const &); Block_vfs_handle &operator = (Block_vfs_handle const &);
file_size _block_io(file_size nr, void *buf, file_size sz, size_t _block_io(file_size nr, void *buf, file_size sz,
bool write, bool bulk = false) bool write, bool bulk = false)
{ {
Block::Packet_descriptor::Opcode op; Block::Packet_descriptor::Opcode op;
@ -164,22 +164,23 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
_writeable(writeable) _writeable(writeable)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
file_size seek_offset = seek(); file_size seek_offset = seek();
file_size read = 0; size_t count = dst.num_bytes;
size_t read = 0;
while (count > 0) { while (count > 0) {
file_size displ = 0; file_size displ = 0;
file_size length = 0;
file_size nbytes = 0;
file_size blk_nr = seek_offset / _block_size; file_size blk_nr = seek_offset / _block_size;
size_t length = 0;
displ = seek_offset % _block_size; displ = seek_offset % _block_size;
if ((displ + count) > _block_size) if ((displ + count) > _block_size)
length = (_block_size - displ); length = size_t(_block_size - displ);
else else
length = count; length = count;
@ -195,7 +196,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
if (displ == 0 && !(count < _block_size)) { if (displ == 0 && !(count < _block_size)) {
file_size bytes_left = count - (count % _block_size); file_size bytes_left = count - (count % _block_size);
nbytes = _block_io(blk_nr, dst + read, bytes_left, false, true); size_t const nbytes = _block_io(blk_nr, dst.start + read, bytes_left, false, true);
if (nbytes == 0) { if (nbytes == 0) {
Genode::error("error while reading block:", blk_nr, " from block device"); Genode::error("error while reading block:", blk_nr, " from block device");
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -208,13 +209,13 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
continue; continue;
} }
nbytes = _block_io(blk_nr, _block_buffer, _block_size, false); size_t const nbytes = _block_io(blk_nr, _block_buffer, _block_size, false);
if ((unsigned)nbytes != _block_size) { if (nbytes != _block_size) {
Genode::error("error while reading block:", blk_nr, " from block device"); Genode::error("error while reading block:", blk_nr, " from block device");
return READ_ERR_INVALID; return READ_ERR_INVALID;
} }
Genode::memcpy(dst + read, _block_buffer + displ, (size_t)length); Genode::memcpy(dst.start + read, _block_buffer + displ, length);
read += length; read += length;
count -= length; count -= length;
@ -227,8 +228,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
} }
Write_result write(char const *buf, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (!_writeable) { if (!_writeable) {
Genode::error("block device is not writeable"); Genode::error("block device is not writeable");
@ -237,17 +237,19 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
file_size seek_offset = seek(); file_size seek_offset = seek();
file_size written = 0; size_t written = 0;
size_t count = src.num_bytes;
while (count > 0) { while (count > 0) {
file_size displ = 0; file_size displ = 0;
file_size length = 0;
file_size nbytes = 0;
file_size blk_nr = seek_offset / _block_size; file_size blk_nr = seek_offset / _block_size;
size_t length = 0;
displ = seek_offset % _block_size; displ = seek_offset % _block_size;
if ((displ + count) > _block_size) if ((displ + count) > _block_size)
length = (_block_size - displ); length = size_t(_block_size - displ);
else else
length = count; length = count;
@ -263,7 +265,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
if (displ == 0 && !(count < _block_size)) { if (displ == 0 && !(count < _block_size)) {
file_size bytes_left = count - (count % _block_size); file_size bytes_left = count - (count % _block_size);
nbytes = _block_io(blk_nr, (void*)(buf + written), size_t const nbytes = _block_io(blk_nr, (void*)(src.start + written),
bytes_left, true, true); bytes_left, true, true);
if (nbytes == 0) { if (nbytes == 0) {
Genode::error("error while write block:", blk_nr, " to block device"); Genode::error("error while write block:", blk_nr, " to block device");
@ -287,10 +289,10 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
if (displ > 0 || length < _block_size) if (displ > 0 || length < _block_size)
_block_io(blk_nr, _block_buffer, _block_size, false); _block_io(blk_nr, _block_buffer, _block_size, false);
Genode::memcpy(_block_buffer + displ, buf + written, (size_t)length); Genode::memcpy(_block_buffer + displ, src.start + written, length);
nbytes = _block_io(blk_nr, _block_buffer, _block_size, true); size_t const nbytes = _block_io(blk_nr, _block_buffer, _block_size, true);
if ((unsigned)nbytes != _block_size) { if (nbytes != _block_size) {
Genode::error("error while writing block:", blk_nr, " to block_device"); Genode::error("error while writing block:", blk_nr, " to block_device");
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }

View File

@ -70,19 +70,20 @@ class Vfs_capture::Data_file_system : public Single_file_system
bool read_ready() const override { return true; } bool read_ready() const override { return true; }
bool write_ready() const override { return true; } bool write_ready() const override { return true; }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
_capture->capture_at(Point(0, 0)); _capture->capture_at(Point(0, 0));
Genode::memcpy(dst, _capture_ds->local_addr<char>(), (size_t)count); size_t const len = min(dst.num_bytes, _capture_ds->size());
out_count = count; Genode::memcpy(dst.start, _capture_ds->local_addr<char>(), len);
out_count = len;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -149,7 +149,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
Fs_file_system &_vfs_fs; Fs_file_system &_vfs_fs;
bool _queue_read(file_size count, file_size const seek_offset) bool _queue_read(size_t count, file_size const seek_offset)
{ {
if (queued_read_state != Handle_state::Queued_state::IDLE) if (queued_read_state != Handle_state::Queued_state::IDLE)
return false; return false;
@ -160,8 +160,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
if (!source.ready_to_submit()) if (!source.ready_to_submit())
return false; return false;
file_size const max_packet_size = source.bulk_buffer_size() / 2; size_t const max_packet_size = source.bulk_buffer_size() / 2;
file_size const clipped_count = min(max_packet_size, count); size_t const clipped_count = min(max_packet_size, count);
::File_system::Packet_descriptor p; ::File_system::Packet_descriptor p;
try { try {
@ -184,8 +184,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
return true; return true;
} }
Read_result _complete_read(void *dst, file_size count, Read_result _complete_read(Byte_range_ptr const &dst, size_t &out_count)
file_size &out_count)
{ {
if (queued_read_state != Handle_state::Queued_state::ACK) if (queued_read_state != Handle_state::Queued_state::ACK)
return READ_QUEUED; return READ_QUEUED;
@ -199,9 +198,9 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
Read_result result = packet.succeeded() ? READ_OK : READ_ERR_IO; Read_result result = packet.succeeded() ? READ_OK : READ_ERR_IO;
if (result == READ_OK) { if (result == READ_OK) {
file_size const read_num_bytes = min((file_size)packet.length(), count); size_t const read_num_bytes = min(packet.length(), dst.num_bytes);
memcpy(dst, source.packet_content(packet), (size_t)read_num_bytes); memcpy(dst.start, source.packet_content(packet), (size_t)read_num_bytes);
out_count = read_num_bytes; out_count = read_num_bytes;
} }
@ -227,15 +226,14 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
::File_system::File_handle file_handle() const ::File_system::File_handle file_handle() const
{ return ::File_system::File_handle { id().value }; } { return ::File_system::File_handle { id().value }; }
virtual bool queue_read(file_size /* count */) virtual bool queue_read(size_t /* count */)
{ {
Genode::error("Fs_vfs_handle::queue_read() called"); Genode::error("Fs_vfs_handle::queue_read() called");
return true; return true;
} }
virtual Read_result complete_read(char *, virtual Read_result complete_read(Byte_range_ptr const &,
file_size /* in count */, size_t & /* out count */)
file_size & /* out count */)
{ {
Genode::error("Fs_vfs_handle::complete_read() called"); Genode::error("Fs_vfs_handle::complete_read() called");
return READ_ERR_INVALID; return READ_ERR_INVALID;
@ -320,15 +318,14 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
{ {
using Fs_vfs_handle::Fs_vfs_handle; using Fs_vfs_handle::Fs_vfs_handle;
bool queue_read(file_size count) override bool queue_read(size_t count) override
{ {
return _queue_read(count, seek()); return _queue_read(count, seek());
} }
Read_result complete_read(char *dst, file_size count, Read_result complete_read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
return _complete_read(dst, count, out_count); return _complete_read(dst, out_count);
} }
}; };
@ -338,7 +335,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
using Fs_vfs_handle::Fs_vfs_handle; using Fs_vfs_handle::Fs_vfs_handle;
bool queue_read(file_size count) override bool queue_read(size_t count) override
{ {
if (count < sizeof(Dirent)) if (count < sizeof(Dirent))
return true; return true;
@ -347,26 +344,27 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
(seek() / sizeof(Dirent) * DIRENT_SIZE)); (seek() / sizeof(Dirent) * DIRENT_SIZE));
} }
Read_result complete_read(char *dst, file_size count, Read_result complete_read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
using ::File_system::Directory_entry; using ::File_system::Directory_entry;
Directory_entry entry { }; Directory_entry entry { };
file_size entry_out_count = 0;
size_t entry_out_count = 0;
Read_result const read_result = Read_result const read_result =
_complete_read(&entry, DIRENT_SIZE, entry_out_count); _complete_read(Byte_range_ptr((char *)(&entry), DIRENT_SIZE),
entry_out_count);
if (read_result != READ_OK) if (read_result != READ_OK)
return read_result; return read_result;
entry.sanitize(); entry.sanitize();
Dirent &dirent = *(Dirent*)dst; Dirent &dirent = *(Dirent*)dst.start;
if (entry_out_count < DIRENT_SIZE) { if (entry_out_count < DIRENT_SIZE) {
@ -398,15 +396,15 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
{ {
using Fs_vfs_handle::Fs_vfs_handle; using Fs_vfs_handle::Fs_vfs_handle;
bool queue_read(file_size count) override bool queue_read(size_t count) override
{ {
return _queue_read(count, seek()); return _queue_read(count, seek());
} }
Read_result complete_read(char *dst, file_size count, Read_result complete_read(Byte_range_ptr const &dst,
file_size &out_count) override size_t &out_count) override
{ {
return _complete_read(dst, count, out_count); return _complete_read(dst, out_count);
} }
}; };
@ -449,7 +447,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
}; };
Write_result _write(Fs_vfs_handle &handle, file_size const seek_offset, Write_result _write(Fs_vfs_handle &handle, file_size const seek_offset,
const char *buf, file_size count, file_size &out_count) Const_byte_range_ptr const &src, size_t &out_count)
{ {
/* reclaim as much space in the packet stream as possible */ /* reclaim as much space in the packet stream as possible */
_handle_ack(); _handle_ack();
@ -457,8 +455,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
::File_system::Session::Tx::Source &source = *_fs.tx(); ::File_system::Session::Tx::Source &source = *_fs.tx();
using ::File_system::Packet_descriptor; using ::File_system::Packet_descriptor;
file_size const max_packet_size = source.bulk_buffer_size() / 2; size_t const max_packet_size = source.bulk_buffer_size() / 2;
count = min(max_packet_size, count); size_t const count = min(max_packet_size, src.num_bytes);
if (!source.ready_to_submit()) { if (!source.ready_to_submit()) {
_write_would_block = true; _write_would_block = true;
@ -466,13 +464,13 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
} }
try { try {
Packet_descriptor packet_in(source.alloc_packet((size_t)count), Packet_descriptor packet_in(source.alloc_packet(count),
handle.file_handle(), handle.file_handle(),
Packet_descriptor::WRITE, Packet_descriptor::WRITE,
(size_t)count, count,
seek_offset); seek_offset);
memcpy(source.packet_content(packet_in), buf, (size_t)count); memcpy(source.packet_content(packet_in), src.start, count);
_submit_packet(packet_in); _submit_packet(packet_in);
} }
@ -889,29 +887,29 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Write_result write(Vfs_handle *vfs_handle, char const *buf, Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
file_size count, file_size &out_count) override size_t &out_count) override
{ {
Fs_vfs_handle &handle = static_cast<Fs_vfs_handle &>(*vfs_handle); Fs_vfs_handle &handle = static_cast<Fs_vfs_handle &>(*vfs_handle);
return _write(handle, handle.seek(), buf, count, out_count); return _write(handle, handle.seek(), src, out_count);
} }
bool queue_read(Vfs_handle *vfs_handle, file_size count) override bool queue_read(Vfs_handle *vfs_handle, size_t count) override
{ {
Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle); Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
return handle->queue_read(count); return handle->queue_read(count);
} }
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, file_size count, Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
file_size &out_count) override size_t &out_count) override
{ {
out_count = 0; out_count = 0;
Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle); Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
return handle->complete_read(dst, count, out_count); return handle->complete_read(dst, out_count);
} }
bool read_ready(Vfs_handle const &vfs_handle) const override bool read_ready(Vfs_handle const &vfs_handle) const override

View File

@ -28,62 +28,26 @@ class Vfs::Inline_file_system : public Single_file_system
Xml_node _node; Xml_node _node;
class Inline_vfs_handle : public Single_vfs_handle class Handle : public Single_vfs_handle
{ {
private: private:
char const * const _base; Inline_file_system const &_fs;
file_size const _size;
/*
* Noncopyable
*/
Inline_vfs_handle(Inline_vfs_handle const &);
Inline_vfs_handle &operator = (Inline_vfs_handle const &);
public: public:
Inline_vfs_handle(Directory_service &ds, Handle(Directory_service &ds,
File_io_service &fs, File_io_service &fs,
Genode::Allocator &alloc, Allocator &alloc,
char const * const base, Inline_file_system const &inline_fs)
file_size const size) :
: Single_vfs_handle(ds, fs, alloc, 0), Single_vfs_handle(ds, fs, alloc, 0), _fs(inline_fs)
_base(base), _size(size)
{ } { }
Read_result read(char *dst, file_size count, inline Read_result read(Byte_range_ptr const &, size_t &) override;
file_size &out_count) override
{
/* file read limit is the size of the dataspace */
file_size const max_size = _size;
/* current read offset */ Write_result write(Const_byte_range_ptr const &,
file_size const read_offset = seek(); size_t &out_count) override
/* maximum read offset, clamped to dataspace size */
file_size const end_offset = min(count + read_offset, max_size);
/* source address within the dataspace */
char const *src = _base + read_offset;
/* check if end of file is reached */
if (read_offset >= end_offset) {
out_count = 0;
return READ_OK;
}
/* copy-out bytes from ROM dataspace */
size_t const num_bytes = (size_t)(end_offset - read_offset);
memcpy(dst, src, num_bytes);
out_count = num_bytes;
return READ_OK;
}
Write_result write(char const *, file_size,
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
@ -123,22 +87,13 @@ class Vfs::Inline_file_system : public Single_file_system
if (!_single_file(path)) if (!_single_file(path))
return OPEN_ERR_UNACCESSIBLE; return OPEN_ERR_UNACCESSIBLE;
/* empty node */
if (_node.content_size() == 0) {
*out_handle = new (alloc)
Inline_vfs_handle(*this, *this, alloc, nullptr, 0);
return OPEN_OK;
}
try { try {
_node.with_raw_content([&] (char const *base, size_t size) { *out_handle = new (alloc) Handle(*this, *this, alloc, *this);
*out_handle = new (alloc)
Inline_vfs_handle(*this, *this, alloc, base, size);
});
return OPEN_OK;
} }
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; } catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; } catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
return OPEN_OK;
} }
Stat_result stat(char const *path, Stat &out) override Stat_result stat(char const *path, Stat &out) override
@ -152,4 +107,38 @@ class Vfs::Inline_file_system : public Single_file_system
} }
}; };
Vfs::File_io_service::Read_result
Vfs::Inline_file_system::Handle::read(Byte_range_ptr const &dst, size_t &out_count)
{
_fs._node.with_raw_content([&] (char const *start, size_t const len) {
/* file read limit is the size of the XML-node content */
size_t const max_size = len;
/* current read offset */
size_t const read_offset = size_t(seek());
/* maximum read offset, clamped to dataspace size */
size_t const end_offset = min(dst.num_bytes + read_offset, max_size);
/* source address within the XML content */
char const * const src = start + read_offset;
/* check if end of file is reached */
if (read_offset >= end_offset) {
out_count = 0;
return;
}
/* copy-out bytes from ROM dataspace */
size_t const num_bytes = end_offset - read_offset;
memcpy(dst.start, src, num_bytes);
out_count = num_bytes;
});
return READ_OK;
}
#endif /* _INCLUDE__VFS__INLINE_FILE_SYSTEM_H_ */ #endif /* _INCLUDE__VFS__INLINE_FILE_SYSTEM_H_ */

View File

@ -52,7 +52,7 @@ class Vfs::Log_file_system : public Single_file_system
char _line_buf[Genode::Log_session::MAX_STRING_LEN]; char _line_buf[Genode::Log_session::MAX_STRING_LEN];
file_offset _line_pos = 0; size_t _line_pos = 0;
Genode::Log_session &_log; Genode::Log_session &_log;
@ -83,37 +83,40 @@ class Vfs::Log_file_system : public Single_file_system
File_io_service &fs, File_io_service &fs,
Genode::Allocator &alloc, Genode::Allocator &alloc,
Genode::Log_session &log) Genode::Log_session &log)
: Single_vfs_handle(ds, fs, alloc, 0), :
_log(log) { } Single_vfs_handle(ds, fs, alloc, 0), _log(log)
{ }
~Log_vfs_handle() ~Log_vfs_handle()
{ {
if (_line_pos > 0) _flush(); if (_line_pos > 0) _flush();
} }
Read_result read(char *, file_size, file_size &) override Read_result read(Byte_range_ptr const &, size_t &) override
{ {
/* block indefinitely - mimics stdout resp. stdin w/o input */ /* block indefinitely - mimics stdout resp. stdin w/o input */
return READ_QUEUED; return READ_QUEUED;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &buf, size_t &out_count) override
file_size &out_count) override
{ {
size_t count = buf.num_bytes;
char const * src = buf.start;
out_count = count; out_count = count;
/* count does not include the trailing '\0' */ /* count does not include the trailing '\0' */
while (count > 0) { while (count > 0) {
file_size curr_count = min(count, (file_size)((sizeof(_line_buf) - 1) - _line_pos)); size_t curr_count = min(count, sizeof(_line_buf) - 1 - _line_pos);
for (file_size i = 0; i < curr_count; ++i) { for (size_t i = 0; i < curr_count; ++i) {
if (src[i] == '\n') { if (src[i] == '\n') {
curr_count = i + 1; curr_count = i + 1;
break; break;
} }
} }
memcpy(_line_buf + _line_pos, src, (size_t)curr_count); memcpy(_line_buf + _line_pos, src, curr_count);
_line_pos += curr_count; _line_pos += curr_count;
if ((_line_pos == sizeof(_line_buf) - 1) || if ((_line_pos == sizeof(_line_buf) - 1) ||

View File

@ -36,19 +36,20 @@ struct Vfs::Null_file_system : Single_file_system
Null_vfs_handle(Directory_service &ds, Null_vfs_handle(Directory_service &ds,
File_io_service &fs, File_io_service &fs,
Genode::Allocator &alloc) Genode::Allocator &alloc)
: Single_vfs_handle(ds, fs, alloc, 0) { } :
Single_vfs_handle(ds, fs, alloc, 0)
{ }
Read_result read(char *, file_size, file_size &out_count) override Read_result read(Byte_range_ptr const &, size_t &out_count) override
{ {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }

View File

@ -56,6 +56,7 @@ namespace Vfs_ram {
return start; return start;
} }
using Seek = File_system::Chunk_base::Seek;
} }
@ -135,7 +136,7 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>
char const *name() { return _name; } char const *name() { return _name; }
void name(char const *name) { copy_cstring(_name, name, MAX_NAME_LEN); } void name(char const *name) { copy_cstring(_name, name, MAX_NAME_LEN); }
virtual Vfs::file_size length() = 0; virtual size_t length() = 0;
void open(Io_handle &handle) { _io_handles.insert(&handle); } void open(Io_handle &handle) { _io_handles.insert(&handle); }
void open(Watch_handle &handle) { _watch_handles.insert(&handle); } void open(Watch_handle &handle) { _watch_handles.insert(&handle); }
@ -172,28 +173,27 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>
.executable = true }; .executable = true };
} }
virtual size_t read(char*, size_t, file_size) virtual size_t read(Byte_range_ptr const &, Seek)
{ {
Genode::error("Vfs_ram::Node::read() called"); Genode::error("Vfs_ram::Node::read() called");
return 0; return 0;
} }
virtual Vfs::File_io_service::Read_result complete_read(char *, virtual Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &,
file_size, Seek,
file_size, size_t & /* out count */)
file_size &)
{ {
Genode::error("Vfs_ram::Node::complete_read() called"); Genode::error("Vfs_ram::Node::complete_read() called");
return Vfs::File_io_service::READ_ERR_INVALID; return Vfs::File_io_service::READ_ERR_INVALID;
} }
virtual size_t write(char const *, size_t, file_size) virtual size_t write(Const_byte_range_ptr const &, Seek)
{ {
Genode::error("Vfs_ram::Node::write() called"); Genode::error("Vfs_ram::Node::write() called");
return 0; return 0;
} }
virtual void truncate(file_size) virtual void truncate(Seek)
{ {
Genode::error("Vfs_ram::Node::truncate() called"); Genode::error("Vfs_ram::Node::truncate() called");
} }
@ -209,7 +209,7 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>
* Find index N by walking down the tree N times, * Find index N by walking down the tree N times,
* not the most efficient way to do this. * not the most efficient way to do this.
*/ */
Node *index(file_offset &i) Node *index(size_t &i)
{ {
if (i-- == 0) if (i-- == 0)
return this; return this;
@ -250,18 +250,19 @@ class Vfs_ram::File : public Vfs_ram::Node
typedef Chunk_index<num_level_0_entries(), Chunk_level_1> Chunk_level_0; typedef Chunk_index<num_level_0_entries(), Chunk_level_1> Chunk_level_0;
Chunk_level_0 _chunk; Chunk_level_0 _chunk;
file_size _length = 0;
size_t _length = 0;
public: public:
File(char const * const name, Allocator &alloc) File(char const * const name, Allocator &alloc)
: Node(name), _chunk(alloc, 0) { } : Node(name), _chunk(alloc, Seek{0}) { }
size_t read(char * const dst, size_t len, file_size const seek_offset) override size_t read(Byte_range_ptr const &dst, Seek seek) override
{ {
file_size const chunk_used_size = _chunk.used_size(); size_t const chunk_used_size = _chunk.used_size();
if (seek_offset >= _length) if (seek.value >= _length)
return 0; return 0;
/* /*
@ -270,45 +271,46 @@ class Vfs_ram::File : public Vfs_ram::Node
* Note that 'chunk_used_size' may be lower than '_length' * Note that 'chunk_used_size' may be lower than '_length'
* because 'Chunk' may have truncated tailing zeros. * because 'Chunk' may have truncated tailing zeros.
*/ */
if (seek_offset + len >= _length)
len = (size_t)(_length - seek_offset);
file_size read_len = len; size_t const len = (seek.value + dst.num_bytes >= _length)
? _length - min(_length, seek.value)
: dst.num_bytes;
if (seek_offset + read_len > chunk_used_size) { size_t read_len = len;
if (chunk_used_size >= seek_offset)
read_len = chunk_used_size - seek_offset; if (seek.value + read_len > chunk_used_size) {
if (chunk_used_size >= seek.value)
read_len = chunk_used_size - seek.value;
else else
read_len = 0; read_len = 0;
} }
_chunk.read(dst, (size_t)read_len, (size_t)seek_offset); _chunk.read(Byte_range_ptr(dst.start, read_len), seek);
/* add zero padding if needed */ /* add zero padding if needed */
if (read_len < len) if (read_len < dst.num_bytes)
memset(dst + read_len, 0, (size_t)(len - read_len)); memset(dst.start + read_len, 0, len - read_len);
return len; return len;
} }
Vfs::File_io_service::Read_result complete_read(char *dst, Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &dst,
file_size count, Seek seek, size_t &out_count) override
file_size seek_offset,
file_size &out_count) override
{ {
out_count = read(dst, (size_t)count, (size_t)seek_offset); out_count = read(dst, seek);
return Vfs::File_io_service::READ_OK; return Vfs::File_io_service::READ_OK;
} }
size_t write(char const *src, size_t len, file_size seek_offset) override size_t write(Const_byte_range_ptr const &src, Seek const seek) override
{ {
if (seek_offset == (file_size)(~0)) size_t const at = (seek.value == ~0UL) ? _chunk.used_size() : seek.value;
seek_offset = _chunk.used_size();
if (seek_offset + len >= Chunk_level_0::SIZE) size_t len = src.num_bytes;
len = Chunk_level_0::SIZE - (size_t)(seek_offset + len);
try { _chunk.write(src, len, (size_t)seek_offset); } if (at + src.num_bytes >= Chunk_level_0::SIZE)
len = Chunk_level_0::SIZE - at + src.num_bytes;
try { _chunk.write(src, Seek{at}); }
catch (Out_of_memory) { return 0; } catch (Out_of_memory) { return 0; }
/* /*
@ -316,19 +318,19 @@ class Vfs_ram::File : public Vfs_ram::Node
* as file length because trailing zeros may by represented * as file length because trailing zeros may by represented
* by zero chunks, which do not contribute to 'used_size()'. * by zero chunks, which do not contribute to 'used_size()'.
*/ */
_length = max(_length, seek_offset + len); _length = max(_length, at + len);
return len; return len;
} }
file_size length() override { return _length; } size_t length() override { return _length; }
void truncate(file_size size) override void truncate(Seek size) override
{ {
if (size < _chunk.used_size()) if (size.value < _chunk.used_size())
_chunk.truncate(size); _chunk.truncate(size);
_length = size; _length = size.value;
} }
}; };
@ -344,43 +346,34 @@ class Vfs_ram::Symlink : public Vfs_ram::Node
Symlink(char const *name) : Node(name) { } Symlink(char const *name) : Node(name) { }
file_size length() override { return _len; } size_t length() override { return _len; }
void set(char const *target, size_t len) Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &dst, Seek,
size_t &out_count) override
{ {
out_count = min(dst.num_bytes, _len);
memcpy(dst.start, _target, out_count);
return Vfs::File_io_service::READ_OK;
}
size_t write(Const_byte_range_ptr const &src, Seek) override
{
if (src.num_bytes > MAX_PATH_LEN)
return 0;
size_t len = src.num_bytes;
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
if (target[i] == '\0') { if (src.start[i] == '\0') {
len = i; len = i + 1; /* number of characters + terminating zero */
break; break;
} }
} }
_len = len; _len = len;
memcpy(_target, target, _len); memcpy(_target, src.start, _len);
}
size_t get(char *buf, size_t len)
{
size_t out = min(len, _len);
memcpy(buf, _target, out);
return out;
}
Vfs::File_io_service::Read_result complete_read(char *dst,
file_size count,
file_size,
file_size &out_count) override
{
out_count = get(dst, (size_t)count);
return Vfs::File_io_service::READ_OK;
}
size_t write(char const *src, size_t len, file_size) override
{
if (len > MAX_PATH_LEN)
return 0;
set(src, len);
return len; return len;
} }
@ -392,7 +385,8 @@ class Vfs_ram::Directory : public Vfs_ram::Node
private: private:
Avl_tree<Node> _entries { }; Avl_tree<Node> _entries { };
file_size _count = 0;
size_t _count = 0;
public: public:
@ -430,21 +424,20 @@ class Vfs_ram::Directory : public Vfs_ram::Node
--_count; --_count;
} }
file_size length() override { return _count; } size_t length() override { return _count; }
Vfs::File_io_service::Read_result complete_read(char *dst, Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &dst,
file_size count, Seek const seek,
file_size seek_offset, size_t &out_count) override
file_size &out_count) override
{ {
typedef Vfs::Directory_service::Dirent Dirent; typedef Vfs::Directory_service::Dirent Dirent;
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return Vfs::File_io_service::READ_ERR_INVALID; return Vfs::File_io_service::READ_ERR_INVALID;
file_offset index = seek_offset / sizeof(Dirent); size_t index = seek.value / sizeof(Dirent);
Dirent &dirent = *(Dirent*)dst; Dirent &dirent = *(Dirent*)dst.start;
using Dirent_type = Vfs::Directory_service::Dirent_type; using Dirent_type = Vfs::Directory_service::Dirent_type;
@ -883,14 +876,14 @@ class Vfs::Ram_file_system : public Vfs::File_system
if (!file) if (!file)
return ds_cap; return ds_cap;
size_t len = (size_t)file->length(); size_t len = file->length();
char *local_addr = nullptr; char *local_addr = nullptr;
try { try {
ds_cap = _env.env().ram().alloc(len); ds_cap = _env.env().ram().alloc(len);
local_addr = _env.env().rm().attach(ds_cap); local_addr = _env.env().rm().attach(ds_cap);
file->read(local_addr, (size_t)file->length(), 0); file->read(Byte_range_ptr(local_addr, file->length()), Seek{0});
_env.env().rm().detach(local_addr); _env.env().rm().detach(local_addr);
} catch(...) { } catch(...) {
@ -940,30 +933,34 @@ class Vfs::Ram_file_system : public Vfs::File_system
************************/ ************************/
Write_result write(Vfs_handle * const vfs_handle, Write_result write(Vfs_handle * const vfs_handle,
char const * const buf, file_size len, Const_byte_range_ptr const &buf,
Vfs::file_size &out) override size_t &out) override
{ {
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY) if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
Vfs_ram::Io_handle * const handle = Vfs_ram::Io_handle &handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle); *static_cast<Vfs_ram::Io_handle *>(vfs_handle);
out = handle->node.write(buf, (size_t)len, handle->seek()); Vfs_ram::Seek const seek { size_t(handle.seek()) };
handle->modifying = true;
out = handle.node.write(buf, seek);
handle.modifying = true;
return WRITE_OK; return WRITE_OK;
} }
Read_result complete_read(Vfs_handle * const vfs_handle, char *dst, Read_result complete_read(Vfs_handle * const vfs_handle,
file_size count, file_size &out_count) override Byte_range_ptr const &dst, size_t &out_count) override
{ {
out_count = 0; out_count = 0;
Vfs_ram::Io_handle const * const handle = Vfs_ram::Io_handle const &handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle); *static_cast<Vfs_ram::Io_handle *>(vfs_handle);
return handle->node.complete_read(dst, count, handle->seek(), out_count); Vfs_ram::Seek const seek { size_t(handle.seek()) };
return handle.node.complete_read(dst, seek, out_count);
} }
bool read_ready (Vfs_handle const &) const override { return true; } bool read_ready (Vfs_handle const &) const override { return true; }
@ -974,10 +971,12 @@ class Vfs::Ram_file_system : public Vfs::File_system
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY) if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
return FTRUNCATE_ERR_NO_PERM; return FTRUNCATE_ERR_NO_PERM;
Vfs_ram::Io_handle const * const handle = Vfs_ram::Io_handle const &handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle); *static_cast<Vfs_ram::Io_handle *>(vfs_handle);
try { handle->node.truncate(len); } Vfs_ram::Seek const at { size_t(len) };
try { handle.node.truncate(at); }
catch (Vfs_ram::Out_of_memory) { return FTRUNCATE_ERR_NO_SPACE; } catch (Vfs_ram::Out_of_memory) { return FTRUNCATE_ERR_NO_SPACE; }
return FTRUNCATE_OK; return FTRUNCATE_OK;
} }
@ -987,13 +986,14 @@ class Vfs::Ram_file_system : public Vfs::File_system
*/ */
Sync_result complete_sync(Vfs_handle * const vfs_handle) override Sync_result complete_sync(Vfs_handle * const vfs_handle) override
{ {
Vfs_ram::Io_handle * const handle = Vfs_ram::Io_handle &handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle); *static_cast<Vfs_ram::Io_handle *>(vfs_handle);
if (handle->modifying) {
handle->modifying = false; if (handle.modifying) {
handle->node.close(*handle); handle.modifying = false;
handle->node.notify(); handle.node.close(handle);
handle->node.open(*handle); handle.node.notify();
handle.node.open(handle);
} }
return SYNC_OK; return SYNC_OK;
} }
@ -1004,11 +1004,12 @@ class Vfs::Ram_file_system : public Vfs::File_system
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY) if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
return false; return false;
Vfs_ram::Io_handle * const handle = Vfs_ram::Io_handle &handle =
static_cast<Vfs_ram::Io_handle *>(vfs_handle); *static_cast<Vfs_ram::Io_handle *>(vfs_handle);
handle->modifying = true;
return handle->node.update_modification_timestamp(time); handle.modifying = true;
return handle.node.update_modification_timestamp(time);
} }

View File

@ -39,17 +39,17 @@ class Vfs::Rom_file_system : public Single_file_system
Genode::Attached_rom_dataspace _rom { _env, _label.string() }; Genode::Attached_rom_dataspace _rom { _env, _label.string() };
file_size _init_content_size() size_t _init_content_size()
{ {
if (!_binary) if (!_binary)
for (file_size pos = 0; pos < _rom.size(); pos++) for (size_t pos = 0; pos < _rom.size(); pos++)
if (_rom.local_addr<char>()[pos] == 0x00) if (_rom.local_addr<char>()[pos] == 0x00)
return pos; return pos;
return _rom.size(); return _rom.size();
} }
file_size _content_size = _init_content_size(); size_t _content_size = _init_content_size();
void _update() void _update()
{ {
@ -63,7 +63,7 @@ class Vfs::Rom_file_system : public Single_file_system
Genode::Attached_rom_dataspace &_rom; Genode::Attached_rom_dataspace &_rom;
file_size const &_content_size; size_t const &_content_size;
public: public:
@ -71,23 +71,22 @@ class Vfs::Rom_file_system : public Single_file_system
File_io_service &fs, File_io_service &fs,
Genode::Allocator &alloc, Genode::Allocator &alloc,
Genode::Attached_rom_dataspace &rom, Genode::Attached_rom_dataspace &rom,
file_size const &content_size) size_t const &content_size)
: :
Single_vfs_handle(ds, fs, alloc, 0), Single_vfs_handle(ds, fs, alloc, 0),
_rom(rom), _content_size(content_size) _rom(rom), _content_size(content_size)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
/* file read limit is the size of the dataspace */ /* file read limit is the size of the dataspace */
file_size const max_size = _content_size; size_t const max_size = _content_size;
/* current read offset */ /* current read offset */
file_size const read_offset = seek(); size_t const read_offset = size_t(seek());
/* maximum read offset, clamped to dataspace size */ /* maximum read offset, clamped to dataspace size */
file_size const end_offset = min(count + read_offset, max_size); size_t const end_offset = min(dst.num_bytes + read_offset, max_size);
/* check if end of file is reached */ /* check if end of file is reached */
if (read_offset >= end_offset) { if (read_offset >= end_offset) {
@ -99,16 +98,15 @@ class Vfs::Rom_file_system : public Single_file_system
char const *src = _rom.local_addr<char>() + read_offset; char const *src = _rom.local_addr<char>() + read_offset;
/* copy-out bytes from ROM dataspace */ /* copy-out bytes from ROM dataspace */
file_size const num_bytes = end_offset - read_offset; size_t const num_bytes = end_offset - read_offset;
memcpy(dst, src, (size_t)num_bytes); memcpy(dst.start, src, num_bytes);
out_count = num_bytes; out_count = num_bytes;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, Write_result write(Const_byte_range_ptr const &, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;

View File

@ -51,8 +51,7 @@ class Vfs::Rtc_file_system : public Single_file_system
* On each read the current time is queried and afterwards formated * On each read the current time is queried and afterwards formated
* as '%Y-%m-%d %H:%M:%S\n' resp. '%F %T\n'. * as '%Y-%m-%d %H:%M:%S\n' resp. '%F %T\n'.
*/ */
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (seek() >= TIMESTAMP_LEN) { if (seek() >= TIMESTAMP_LEN) {
out_count = 0; out_count = 0;
@ -63,20 +62,20 @@ class Vfs::Rtc_file_system : public Single_file_system
char buf[TIMESTAMP_LEN+1]; char buf[TIMESTAMP_LEN+1];
char *b = buf; char *b = buf;
Genode::size_t n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u\n", size_t n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u\n",
ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second); ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
n -= (size_t)seek(); n -= size_t(seek());
b += seek(); b += seek();
file_size len = count > n ? n : count; size_t const len = min(n, dst.num_bytes);
Genode::memcpy(dst, b, (size_t)len); memcpy(dst.start, b, len);
out_count = len; out_count = len;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size, file_size &) override Write_result write(Const_byte_range_ptr const &, size_t &) override
{ {
return WRITE_ERR_IO; return WRITE_ERR_IO;
} }

View File

@ -39,18 +39,15 @@ class Vfs::Symlink_file_system : public Single_file_system
: Single_vfs_handle(ds, fs, alloc, 0), _target(target) : Single_vfs_handle(ds, fs, alloc, 0), _target(target)
{ } { }
Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
Read_result read(char *dst, file_size count,
file_size &out_count) override
{ {
auto n = min(count, _target.length()); size_t const n = min(dst.num_bytes, _target.length());
copy_cstring(dst, _target.string(), (size_t)n); copy_cstring(dst.start, _target.string(), n);
out_count = n - 1; out_count = (n > 0) ? n - 1 : 0;
return READ_OK; return READ_OK;
} }
Write_result write(char const*, file_size, Write_result write(Const_byte_range_ptr const &, size_t &) override {
file_size&) override {
return WRITE_ERR_INVALID; } return WRITE_ERR_INVALID; }
bool read_ready() const override { return true; } bool read_ready() const override { return true; }

View File

@ -148,8 +148,7 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
return _link_state; return _link_state;
} }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (!read_ready()) { if (!read_ready()) {
_blocked = true; _blocked = true;
@ -167,8 +166,8 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
const char *const rx_pkt_base { const char *const rx_pkt_base {
_nic.rx()->packet_content(rx_pkt) }; _nic.rx()->packet_content(rx_pkt) };
out_count = static_cast<file_size>(min(rx_pkt.size(), static_cast<size_t>(count))); out_count = min(rx_pkt.size(), dst.num_bytes);
memcpy(dst, rx_pkt_base, static_cast<size_t>(out_count)); memcpy(dst.start, rx_pkt_base, out_count);
_nic.rx()->acknowledge_packet(rx_pkt); _nic.rx()->acknowledge_packet(rx_pkt);
} }
@ -176,8 +175,7 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
return Read_result::READ_OK; return Read_result::READ_OK;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
out_count = 0; out_count = 0;
@ -187,18 +185,16 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
return Write_result::WRITE_ERR_WOULD_BLOCK; return Write_result::WRITE_ERR_WOULD_BLOCK;
} }
try { try {
size_t tx_pkt_size { static_cast<size_t>(count) };
Packet_descriptor tx_pkt { Packet_descriptor tx_pkt {
_nic.tx()->alloc_packet(tx_pkt_size) }; _nic.tx()->alloc_packet(src.num_bytes) };
void *tx_pkt_base { void *tx_pkt_base {
_nic.tx()->packet_content(tx_pkt) }; _nic.tx()->packet_content(tx_pkt) };
memcpy(tx_pkt_base, src, tx_pkt_size); memcpy(tx_pkt_base, src.start, src.num_bytes);
_nic.tx()->submit_packet(tx_pkt); _nic.tx()->submit_packet(tx_pkt);
out_count = tx_pkt_size; out_count = src.num_bytes;
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
} catch (...) { } catch (...) {

View File

@ -136,8 +136,7 @@ class Vfs::Uplink_file_system::Uplink_vfs_handle : public Single_vfs_handle,
return _drv_link_state; return _drv_link_state;
} }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (!_conn.constructed()) if (!_conn.constructed())
return Read_result::READ_ERR_INVALID; return Read_result::READ_ERR_INVALID;
@ -158,8 +157,8 @@ class Vfs::Uplink_file_system::Uplink_vfs_handle : public Single_vfs_handle,
const char *const conn_rx_pkt_base { const char *const conn_rx_pkt_base {
_conn->rx()->packet_content(conn_rx_pkt) }; _conn->rx()->packet_content(conn_rx_pkt) };
out_count = static_cast<file_size>(min(conn_rx_pkt.size(), static_cast<size_t>(count))); out_count = min(conn_rx_pkt.size(), dst.num_bytes);
memcpy(dst, conn_rx_pkt_base, static_cast<size_t>(out_count)); memcpy(dst.start, conn_rx_pkt_base, out_count);
_conn->rx()->acknowledge_packet(conn_rx_pkt); _conn->rx()->acknowledge_packet(conn_rx_pkt);
} }
@ -167,20 +166,19 @@ class Vfs::Uplink_file_system::Uplink_vfs_handle : public Single_vfs_handle,
return Read_result::READ_OK; return Read_result::READ_OK;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
if (!_conn.constructed()) if (!_conn.constructed())
return Write_result::WRITE_ERR_INVALID; return Write_result::WRITE_ERR_INVALID;
out_count = 0; out_count = 0;
_drv_rx_handle_pkt(static_cast<size_t>(count), [&] (void * dst, size_t dst_size) { _drv_rx_handle_pkt(src.num_bytes, [&] (void * dst, size_t dst_size) {
out_count = dst_size; out_count = dst_size;
memcpy(dst, src, dst_size); memcpy(dst, src.start, dst_size);
return Uplink_client_base::Write_result::WRITE_SUCCEEDED; return Uplink_client_base::Write_result::WRITE_SUCCEEDED;
}); });
if (out_count == count) if (out_count == src.num_bytes)
return Write_result::WRITE_OK; return Write_result::WRITE_OK;
else else
return Write_result::WRITE_ERR_WOULD_BLOCK; return Write_result::WRITE_ERR_WOULD_BLOCK;

View File

@ -165,8 +165,7 @@ class Vfs::Tar_file_system : public File_system
: Vfs_handle(fs, fs, alloc, status_flags), _node(node) : Vfs_handle(fs, fs, alloc, status_flags), _node(node)
{ } { }
virtual Read_result read(char *dst, file_size count, virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
file_size &out_count) = 0;
}; };
@ -174,19 +173,18 @@ class Vfs::Tar_file_system : public File_system
{ {
using Tar_vfs_handle::Tar_vfs_handle; using Tar_vfs_handle::Tar_vfs_handle;
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
file_size const record_size = _node->record->size(); file_size const record_size = _node->record->size();
file_size const record_bytes_left = record_size >= seek() file_size const record_bytes_left = record_size >= seek()
? record_size - seek() : 0; ? record_size - seek() : 0;
count = min(record_bytes_left, count); size_t const count = min(size_t(record_bytes_left), dst.num_bytes);
char const *data = (char *)_node->record->data() + seek(); char const *data = (char *)_node->record->data() + seek();
memcpy(dst, data, (size_t)count); memcpy(dst.start, data, count);
out_count = count; out_count = count;
return READ_OK; return READ_OK;
@ -197,13 +195,12 @@ class Vfs::Tar_file_system : public File_system
{ {
using Tar_vfs_handle::Tar_vfs_handle; using Tar_vfs_handle::Tar_vfs_handle;
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (count < sizeof(Dirent)) if (dst.num_bytes < sizeof(Dirent))
return READ_ERR_INVALID; return READ_ERR_INVALID;
Dirent &dirent = *(Dirent*)dst; Dirent &dirent = *(Dirent*)dst.start;
unsigned const index = (unsigned)(seek() / sizeof(Dirent)); unsigned const index = (unsigned)(seek() / sizeof(Dirent));
@ -272,14 +269,13 @@ class Vfs::Tar_file_system : public File_system
{ {
using Tar_vfs_handle::Tar_vfs_handle; using Tar_vfs_handle::Tar_vfs_handle;
Read_result read(char *buf, file_size buf_size, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
Record const *record = _node->record; Record const *record = _node->record;
file_size const count = min(buf_size, 100ULL); size_t const count = min(dst.num_bytes, 100UL);
memcpy(buf, record->linked_name(), (size_t)count); memcpy(dst.start, record->linked_name(), count);
out_count = count; out_count = count;
@ -751,23 +747,19 @@ class Vfs::Tar_file_system : public File_system
** File I/O service interface ** ** File I/O service interface **
********************************/ ********************************/
Write_result write(Vfs_handle *, char const *, file_size, Write_result write(Vfs_handle *, Const_byte_range_ptr const &, size_t &) override
file_size &) override
{ {
return WRITE_ERR_INVALID; return WRITE_ERR_INVALID;
} }
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
file_size count, file_size &out_count) override size_t &out_count) override
{ {
out_count = 0; out_count = 0;
Tar_vfs_handle *handle = static_cast<Tar_vfs_handle *>(vfs_handle); Tar_vfs_handle &handle = *static_cast<Tar_vfs_handle *>(vfs_handle);
if (!handle) return handle.read(dst, out_count);
return READ_ERR_INVALID;
return handle->read(dst, count, out_count);
} }
Ftruncate_result ftruncate(Vfs_handle *, file_size) override Ftruncate_result ftruncate(Vfs_handle *, file_size) override

View File

@ -149,8 +149,7 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
return true; return true;
} }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
if (_read_buffer.empty()) if (_read_buffer.empty())
_fetch_data_from_terminal(_terminal, _read_buffer, _fetch_data_from_terminal(_terminal, _read_buffer,
@ -160,18 +159,17 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
return READ_QUEUED; return READ_QUEUED;
unsigned consumed = 0; unsigned consumed = 0;
for (; consumed < count && !_read_buffer.empty(); consumed++) for (; consumed < dst.num_bytes && !_read_buffer.empty(); consumed++)
dst[consumed] = _read_buffer.get(); dst.start[consumed] = _read_buffer.get();
out_count = consumed; out_count = consumed;
return READ_OK; return READ_OK;
} }
Write_result write(char const *src, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
out_count = _terminal.write(src, (size_t)count); out_count = _terminal.write(src.start, src.num_bytes);
return WRITE_OK; return WRITE_OK;
} }
}; };

View File

@ -48,35 +48,35 @@ struct Vfs::Zero_file_system : Single_file_system
_size(size) _size(size)
{ } { }
Read_result read(char *dst, file_size count, Read_result read(Byte_range_ptr const &dst, size_t &out_count) override
file_size &out_count) override
{ {
size_t count = dst.num_bytes;
if (_size) { if (_size) {
/* current read offset */ /* current read offset */
file_size const read_offset = seek(); file_size const read_offset = seek();
/* maximum read offset */ /* maximum read offset */
file_size const end_offset = min(count + read_offset, _size); file_size const end_offset = min(dst.num_bytes + read_offset, _size);
if (read_offset >= end_offset) { if (read_offset >= end_offset) {
out_count = 0; out_count = 0;
return READ_OK; return READ_OK;
} }
count = size_t(end_offset - read_offset);
count = end_offset - read_offset;
} }
memset(dst, 0, (size_t)count); memset(dst.start, 0, count);
out_count = count; out_count = count;
return READ_OK; return READ_OK;
} }
Write_result write(char const *, file_size count, Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
file_size &out_count) override
{ {
out_count = count; out_count = src.num_bytes;
return WRITE_OK; return WRITE_OK;
} }

View File

@ -153,12 +153,14 @@ class Fs_report::Session_component : public Genode::Rpc_object<Report::Session>
size_t offset = 0; size_t offset = 0;
while (offset < length) { while (offset < length) {
file_size n = 0; size_t n = 0;
handle->seek(offset); handle->seek(offset);
Write_result res = handle->fs().write(
handle, _ds.local_addr<char const>() + offset, Const_byte_range_ptr const src(_ds.local_addr<char>() + offset,
length - offset, n); length - offset);
Write_result res = handle->fs().write(handle, src, n);
if (res != Write_result::WRITE_OK) { if (res != Write_result::WRITE_OK) {
/* do not spam the log */ /* do not spam the log */
@ -169,7 +171,7 @@ class Fs_report::Session_component : public Genode::Rpc_object<Report::Session>
return; return;
} }
offset += (size_t)n; offset += n;
} }
_file_size = length; _file_size = length;

View File

@ -378,10 +378,12 @@ class Vfs_server::Io_node : public Vfs_server::Node,
void _execute_read() void _execute_read()
{ {
file_size out_count = 0; size_t out_count = 0;
Byte_range_ptr dst { _payload_ptr.ptr, _packet.length() };
switch (_handle.fs().complete_read(&_handle, dst, out_count)) {
switch (_handle.fs().complete_read(&_handle, _payload_ptr.ptr,
_packet.length(), out_count)) {
case Read_result::READ_OK: case Read_result::READ_OK:
_acknowledge_as_success((size_t)out_count); _acknowledge_as_success((size_t)out_count);
break; break;
@ -402,13 +404,13 @@ class Vfs_server::Io_node : public Vfs_server::Node,
* *
* \return number of consumed bytes * \return number of consumed bytes
*/ */
size_t _execute_write(char const *src_ptr, size_t length, size_t _execute_write(Const_byte_range_ptr const &src, seek_off_t write_pos)
seek_off_t write_pos)
{ {
file_size out_count = 0; size_t out_count = 0;
_handle.seek(_initial_write_seek_offset + write_pos); _handle.seek(_initial_write_seek_offset + write_pos);
switch (_handle.fs().write(&_handle, src_ptr, length, out_count)) { switch (_handle.fs().write(&_handle, src, out_count)) {
case Write_result::WRITE_ERR_WOULD_BLOCK: case Write_result::WRITE_ERR_WOULD_BLOCK:
break; break;
@ -423,7 +425,7 @@ class Vfs_server::Io_node : public Vfs_server::Node,
_modified = true; _modified = true;
return (size_t)out_count; return out_count;
} }
void _execute_sync() void _execute_sync()
@ -669,10 +671,11 @@ struct Vfs_server::Symlink : Io_node
*/ */
case Packet_descriptor::WRITE: case Packet_descriptor::WRITE:
{ {
size_t const count = _write_buffer.length(); Const_byte_range_ptr const src { _write_buffer.string(),
_write_buffer.length() };
if (_execute_write(_write_buffer.string(), count, 0) == count) if (_execute_write(src, 0) == src.num_bytes)
_acknowledge_as_success(count); _acknowledge_as_success(src.num_bytes);
else else
_acknowledge_as_failure(); _acknowledge_as_failure();
break; break;
@ -736,7 +739,7 @@ class Vfs_server::File : public Io_node
* *
* Used for the incremental write to continuous files. * Used for the incremental write to continuous files.
*/ */
seek_off_t _write_pos = 0; size_t _write_pos = 0;
bool _watch_read_ready = false; bool _watch_read_ready = false;
@ -800,13 +803,13 @@ class Vfs_server::File : public Io_node
case Packet_descriptor::WRITE: case Packet_descriptor::WRITE:
{ {
size_t const count = (size_t)(_packet.length() - _write_pos); Const_byte_range_ptr const src { _payload_ptr.ptr + _write_pos,
char const * const src_ptr = _payload_ptr.ptr + _write_pos; _packet.length() - _write_pos };
size_t const consumed = _execute_write(src_ptr, count,
_write_pos);
if (consumed == count) { size_t const consumed = _execute_write(src, _write_pos);
_acknowledge_as_success(count);
if (consumed == src.num_bytes) {
_acknowledge_as_success(src.num_bytes);
break; break;
} }

View File

@ -18,6 +18,7 @@ namespace Vfs_block {
using file_size = Vfs::file_size; using file_size = Vfs::file_size;
using file_offset = Vfs::file_offset; using file_offset = Vfs::file_offset;
using size_t = Genode::size_t;
struct Job struct Job
{ {
@ -57,7 +58,7 @@ namespace Vfs_block {
State state; State state;
file_offset const base_offset; file_offset const base_offset;
file_offset current_offset; file_offset current_offset;
file_size current_count; size_t current_count;
bool success; bool success;
bool complete; bool complete;
@ -82,12 +83,13 @@ namespace Vfs_block {
using Result = Vfs::File_io_service::Read_result; using Result = Vfs::File_io_service::Read_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Genode::Byte_range_ptr const dst { data + current_offset,
current_count };
Result const result = _handle.fs().complete_read(&_handle, dst, out);
Result const result =
_handle.fs().complete_read(&_handle,
data + current_offset,
current_count, out);
if (result == Result::READ_QUEUED if (result == Result::READ_QUEUED
|| result == Result::READ_ERR_WOULD_BLOCK) { || result == Result::READ_ERR_WOULD_BLOCK) {
return progress; return progress;
@ -142,11 +144,13 @@ namespace Vfs_block {
using Result = Vfs::File_io_service::Write_result; using Result = Vfs::File_io_service::Write_result;
bool completed = false; bool completed = false;
file_size out = 0; size_t out = 0;
Genode::Const_byte_range_ptr const src { data + current_offset,
current_count };
Result result = _handle.fs().write(&_handle, src, out);
Result result = _handle.fs().write(&_handle,
data + current_offset,
current_count, out);
switch (result) { switch (result) {
case Result::WRITE_ERR_WOULD_BLOCK: case Result::WRITE_ERR_WOULD_BLOCK:
return progress; return progress;
@ -243,7 +247,7 @@ namespace Vfs_block {
Block::Request request, Block::Request request,
file_offset base_offset, file_offset base_offset,
char *data, char *data,
file_size length) size_t length)
: :
_handle { handle }, _handle { handle },
request { request }, request { request },

View File

@ -26,7 +26,7 @@ using Chunk_level_1 = Chunk_index<4, Chunk_level_2>;
struct Chunk_level_0 : Chunk_index<5, Chunk_level_1> struct Chunk_level_0 : Chunk_index<5, Chunk_level_1>
{ {
Chunk_level_0(Allocator &alloc, seek_off_t off) : Chunk_index(alloc, off) { } Chunk_level_0(Allocator &alloc, Seek off) : Chunk_index(alloc, off) { }
void print(Output &out) const void print(Output &out) const
{ {
@ -34,7 +34,7 @@ struct Chunk_level_0 : Chunk_index<5, Chunk_level_1>
if (used_size() > Chunk_level_0::SIZE) { if (used_size() > Chunk_level_0::SIZE) {
throw Index_out_of_range(); } throw Index_out_of_range(); }
read(read_buf, (size_t)used_size(), 0); read(Byte_range_ptr(read_buf, (size_t)used_size()), Seek { 0 });
Genode::print(out, "content (size=", used_size(), "): "); Genode::print(out, "content (size=", used_size(), "): ");
Genode::print(out, "\""); Genode::print(out, "\"");
for (unsigned i = 0; i < used_size(); i++) { for (unsigned i = 0; i < used_size(); i++) {
@ -98,6 +98,8 @@ struct Allocator_tracer : Allocator
struct Main struct Main
{ {
using Seek = Chunk_base::Seek;
Env &env; Env &env;
Heap heap { env.ram(), env.rm() }; Heap heap { env.ram(), env.rm() };
Allocator_tracer alloc { heap }; Allocator_tracer alloc { heap };
@ -111,34 +113,35 @@ struct Main
log(" level 2: payload=", (int)Chunk_level_2::SIZE, " sizeof=", sizeof(Chunk_level_2)); log(" level 2: payload=", (int)Chunk_level_2::SIZE, " sizeof=", sizeof(Chunk_level_2));
log(" level 3: payload=", (int)Chunk_level_3::SIZE, " sizeof=", sizeof(Chunk_level_3)); log(" level 3: payload=", (int)Chunk_level_3::SIZE, " sizeof=", sizeof(Chunk_level_3));
{ {
Chunk_level_0 chunk(alloc, 0); Chunk_level_0 chunk(alloc, Seek { 0 });
write(chunk, "five-o-one", 0); write(chunk, "five-o-one", Seek { 0 });
/* overwrite part of the file */ /* overwrite part of the file */
write(chunk, "five", 7); write(chunk, "five", Seek { 7 });
/* write to position beyond current file length */ /* write to position beyond current file length */
write(chunk, "Nuance", 17); write(chunk, "Nuance", Seek { 17 });
write(chunk, "YM-2149", 35); write(chunk, "YM-2149", Seek { 35 });
truncate(chunk, 30); truncate(chunk, Seek { 30 });
for (unsigned i = 29; i > 0; i--) for (unsigned i = 29; i > 0; i--)
truncate(chunk, i); truncate(chunk, Seek { i });
} }
log("allocator: sum=", alloc.sum); log("allocator: sum=", alloc.sum);
log("--- RAM filesystem chunk test finished ---"); log("--- RAM filesystem chunk test finished ---");
} }
void write(Chunk_level_0 &chunk, char const *str, off_t seek_offset) void write(Chunk_level_0 &chunk, char const *str, Seek seek)
{ {
chunk.write(str, strlen(str), seek_offset); chunk.write(Const_byte_range_ptr(str, strlen(str)), seek);
log("write \"", str, "\" at offset ", seek_offset, " -> ", chunk);
log("write \"", str, "\" at offset ", seek.value, " -> ", chunk);
} }
void truncate(Chunk_level_0 &chunk, file_size_t size) void truncate(Chunk_level_0 &chunk, Seek size)
{ {
chunk.truncate(size); chunk.truncate(size);
log("trunc(", size, ") -> ", chunk); log("trunc(", size.value, ") -> ", chunk);
} }
}; };

View File

@ -290,9 +290,9 @@ struct Write_test : public Stress_test
path.base(), Directory_service::OPEN_MODE_WRONLY, &handle, alloc)); path.base(), Directory_service::OPEN_MODE_WRONLY, &handle, alloc));
Vfs_handle::Guard guard(handle); Vfs_handle::Guard guard(handle);
file_size n; size_t n;
assert_write(handle->fs().write( assert_write(handle->fs().write(
handle, path.base(), path_len, n)); handle, Const_byte_range_ptr(path.base(), path_len), n));
handle->fs().queue_sync(handle); handle->fs().queue_sync(handle);
while (handle->fs().complete_sync(handle) == while (handle->fs().complete_sync(handle) ==
Vfs::File_io_service::SYNC_QUEUED) Vfs::File_io_service::SYNC_QUEUED)
@ -366,13 +366,15 @@ struct Read_test : public Stress_test
Vfs_handle::Guard guard(handle); Vfs_handle::Guard guard(handle);
char tmp[MAX_PATH_LEN]; char tmp[MAX_PATH_LEN];
file_size n; size_t n;
handle->fs().queue_read(handle, sizeof(tmp)); handle->fs().queue_read(handle, sizeof(tmp));
Vfs::File_io_service::Read_result read_result; Vfs::File_io_service::Read_result read_result;
Byte_range_ptr const dst { tmp, sizeof(tmp) };
while ((read_result = while ((read_result =
handle->fs().complete_read(handle, tmp, sizeof(tmp), n)) == handle->fs().complete_read(handle, dst, n)) ==
Vfs::File_io_service::READ_QUEUED) Vfs::File_io_service::READ_QUEUED)
_io.commit_and_wait(); _io.commit_and_wait();
@ -444,10 +446,11 @@ struct Unlink_test : public Stress_test
for (Vfs::file_size i = vfs.num_dirent(path); i;) { for (Vfs::file_size i = vfs.num_dirent(path); i;) {
dir_handle->seek(--i * sizeof(dirent)); dir_handle->seek(--i * sizeof(dirent));
dir_handle->fs().queue_read(dir_handle, sizeof(dirent)); dir_handle->fs().queue_read(dir_handle, sizeof(dirent));
Vfs::file_size out_count;
while (dir_handle->fs().complete_read(dir_handle, (char*)&dirent, Byte_range_ptr const dst { (char*)&dirent, sizeof(dirent) };
sizeof(dirent), out_count) == size_t out_count;
while (dir_handle->fs().complete_read(dir_handle, dst, out_count) ==
Vfs::File_io_service::READ_QUEUED) Vfs::File_io_service::READ_QUEUED)
_io.commit_and_wait(); _io.commit_and_wait();