mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
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:
parent
6e1517ca3c
commit
bdf47785b8
@ -183,16 +183,14 @@ struct Vfs::File : Vfs::Node
|
||||
virtual bool poll() { return true; }
|
||||
|
||||
virtual Lxip::ssize_t write(Lxip_vfs_file_handle &,
|
||||
char const *src, Genode::size_t len,
|
||||
file_size)
|
||||
Const_byte_range_ptr const &, file_size)
|
||||
{
|
||||
Genode::error(name(), " not writeable");
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual Lxip::ssize_t read(Lxip_vfs_file_handle &,
|
||||
char *dst, Genode::size_t len,
|
||||
file_size)
|
||||
Byte_range_ptr const &, file_size)
|
||||
{
|
||||
Genode::error(name(), " not readable");
|
||||
return -1;
|
||||
@ -217,8 +215,7 @@ struct Vfs::Directory : Vfs::Node
|
||||
Genode::Allocator &alloc,
|
||||
char const*, unsigned, Vfs::Vfs_handle**) = 0;
|
||||
|
||||
virtual Lxip::ssize_t read(char *dst, Genode::size_t len,
|
||||
file_size seek_offset) = 0;
|
||||
virtual Lxip::ssize_t read(Byte_range_ptr const &, file_size seek_offset) = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -269,10 +266,8 @@ struct Vfs::Lxip_vfs_handle : Vfs::Vfs_handle
|
||||
*/
|
||||
virtual bool read_ready() const = 0;
|
||||
|
||||
virtual Read_result read(char *dst,
|
||||
file_size count, file_size &out_count) = 0;
|
||||
virtual Write_result write(char const *src,
|
||||
file_size count, file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
|
||||
virtual Write_result write(Const_byte_range_ptr const &src, size_t &out_count) = 0;
|
||||
|
||||
virtual Sync_result sync() {
|
||||
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 {
|
||||
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;
|
||||
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;
|
||||
out_count = res;
|
||||
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;
|
||||
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;
|
||||
out_count = res;
|
||||
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;
|
||||
|
||||
Genode::memcpy(content_buffer, buf, len);
|
||||
content_buffer[len+0] = '\n';
|
||||
content_buffer[len+1] = '\0';
|
||||
Genode::memcpy(content_buffer, src.start, src.num_bytes);
|
||||
content_buffer[src.num_bytes + 0] = '\n';
|
||||
content_buffer[src.num_bytes + 1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -359,15 +354,15 @@ struct Vfs::Lxip_vfs_dir_handle final : Vfs::Lxip_vfs_handle
|
||||
|
||||
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;
|
||||
out_count = res;
|
||||
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; }
|
||||
};
|
||||
|
||||
@ -462,19 +457,19 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
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(),
|
||||
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;
|
||||
|
||||
@ -482,18 +477,18 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
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)
|
||||
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 &,
|
||||
char const *, Genode::size_t,
|
||||
file_size) override
|
||||
Const_byte_range_ptr const &, file_size) override
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
if (!_sock_valid()) return -1;
|
||||
|
||||
iovec iov { dst, len };
|
||||
iovec iov { dst.start, dst.num_bytes };
|
||||
|
||||
msghdr msg = create_msghdr(nullptr, 0, len, &iov);
|
||||
|
||||
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT|MSG_PEEK);
|
||||
msghdr msg = create_msghdr(nullptr, 0, dst.num_bytes, &iov);
|
||||
|
||||
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, dst.num_bytes,
|
||||
MSG_DONTWAIT|MSG_PEEK);
|
||||
if (ret == -EAGAIN)
|
||||
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,
|
||||
char const *src, Genode::size_t len,
|
||||
Const_byte_range_ptr const &src,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
@ -576,7 +570,7 @@ class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
|
||||
/* already bound to port */
|
||||
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 */
|
||||
long port = get_port(handle.content_buffer);
|
||||
@ -598,18 +592,18 @@ class Vfs::Lxip_bind_file final : public Vfs::Lxip_file
|
||||
|
||||
_parent.bind(true);
|
||||
|
||||
return len;
|
||||
return src.num_bytes;
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
if (len < sizeof(handle.content_buffer))
|
||||
if (dst.num_bytes < sizeof(handle.content_buffer))
|
||||
return -1;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -632,7 +626,7 @@ class Vfs::Lxip_listen_file final : public Vfs::Lxip_file
|
||||
********************/
|
||||
|
||||
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
|
||||
{
|
||||
if (!_sock_valid()) return -1;
|
||||
@ -640,7 +634,7 @@ class Vfs::Lxip_listen_file final : public Vfs::Lxip_file
|
||||
/* write-once */
|
||||
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(
|
||||
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);
|
||||
if (_write_err != 0) {
|
||||
handle.write_content_line("", 0);
|
||||
handle.write_content_line(Const_byte_range_ptr("", 0));
|
||||
return -1;
|
||||
}
|
||||
|
||||
_parent.listen(true);
|
||||
|
||||
return len;
|
||||
return src.num_bytes;
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
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,
|
||||
char const *src, Genode::size_t len,
|
||||
Const_byte_range_ptr const &src,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
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);
|
||||
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:
|
||||
_connecting = true;
|
||||
_write_err = 0;
|
||||
return len;
|
||||
return src.num_bytes;
|
||||
|
||||
case Lxip::Io_result::LINUX_EALREADY:
|
||||
return -1;
|
||||
@ -752,11 +746,11 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
|
||||
|
||||
_parent.connect(true);
|
||||
|
||||
return len;
|
||||
return src.num_bytes;
|
||||
}
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
int so_error = 0;
|
||||
@ -770,11 +764,11 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
|
||||
|
||||
switch (so_error) {
|
||||
case 0:
|
||||
return Genode::snprintf(dst, len, "connected");
|
||||
return Genode::snprintf(dst.start, dst.num_bytes, "connected");
|
||||
case Linux::ECONNREFUSED:
|
||||
return Genode::snprintf(dst, len, "connection refused");
|
||||
return Genode::snprintf(dst.start, dst.num_bytes, "connection refused");
|
||||
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,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
|
||||
if (!_sock_valid()) return -1;
|
||||
|
||||
if (len < sizeof(handle.content_buffer))
|
||||
if (dst.num_bytes < sizeof(handle.content_buffer))
|
||||
return -1;
|
||||
|
||||
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;
|
||||
unsigned char const *a = (unsigned char *)&i_addr.s_addr;
|
||||
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",
|
||||
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,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
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;
|
||||
unsigned char const *a = (unsigned char *)&i_addr.s_addr;
|
||||
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",
|
||||
a[0], a[1], a[2], a[3], (p[0]<<8)|(p[1]<<0));
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
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_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,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
using namespace Linux;
|
||||
@ -948,8 +942,8 @@ class Vfs::Lxip_accept_file final : public Vfs::Lxip_file
|
||||
f.f_flags = 0;
|
||||
|
||||
if (_sock.ops->poll(&f, &_sock, nullptr) & (POLLIN)) {
|
||||
copy_cstring(dst, "1\n", len);
|
||||
return Genode::strlen(dst);
|
||||
copy_cstring(dst.start, "1\n", dst.num_bytes);
|
||||
return Genode::strlen(dst.start);
|
||||
}
|
||||
|
||||
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(); }
|
||||
|
||||
Lxip::ssize_t read(char *dst, Genode::size_t len,
|
||||
Lxip::ssize_t read(Byte_range_ptr const &dst,
|
||||
file_size seek_offset) override
|
||||
{
|
||||
typedef Vfs::Directory_service::Dirent Dirent;
|
||||
|
||||
if (len < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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;
|
||||
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; }
|
||||
|
||||
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(
|
||||
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;
|
||||
}
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
@ -1457,17 +1451,17 @@ class Lxip::Protocol_dir_impl : public Protocol_dir
|
||||
|
||||
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
|
||||
{
|
||||
typedef Vfs::Directory_service::Dirent Dirent;
|
||||
|
||||
if (len < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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;
|
||||
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) { }
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
enum {
|
||||
@ -1536,10 +1530,10 @@ class Vfs::Lxip_address_file final : public Vfs::File
|
||||
Net::Ipv4_address(&_numeric_address)
|
||||
};
|
||||
|
||||
Lxip::size_t n = min(len, strlen(address.string()));
|
||||
memcpy(dst, address.string(), n);
|
||||
if (n < len)
|
||||
dst[n++] = '\n';
|
||||
Lxip::size_t n = min(dst.num_bytes, strlen(address.string()));
|
||||
memcpy(dst.start, address.string(), n);
|
||||
if (n < dst.num_bytes)
|
||||
dst.start[n++] = '\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) { }
|
||||
|
||||
Lxip::ssize_t read(Lxip_vfs_file_handle &handle,
|
||||
char *dst, Genode::size_t len,
|
||||
Byte_range_ptr const &dst,
|
||||
file_size /* ignored */) override
|
||||
{
|
||||
enum {
|
||||
@ -1569,10 +1563,10 @@ class Vfs::Lxip_link_state_file final : public Vfs::File
|
||||
_numeric_link_state ? "up" : "down"
|
||||
};
|
||||
|
||||
Lxip::size_t n = min(len, strlen(link_state.string()));
|
||||
memcpy(dst, link_state.string(), n);
|
||||
if (n < len)
|
||||
dst[n++] = '\n';
|
||||
Lxip::size_t n = min(dst.num_bytes, strlen(link_state.string()));
|
||||
memcpy(dst.start, link_state.string(), n);
|
||||
if (n < dst.num_bytes)
|
||||
dst.start[n++] = '\n';
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -1649,14 +1643,13 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
|
||||
return (strcmp(path, "") == 0) || (strcmp(path, "/") == 0);
|
||||
}
|
||||
|
||||
Read_result _read(Vfs::Vfs_handle *vfs_handle, char *dst,
|
||||
Vfs::file_size count,
|
||||
Vfs::file_size &out_count)
|
||||
Read_result _read(Vfs::Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count)
|
||||
{
|
||||
Vfs::Lxip_vfs_handle *handle =
|
||||
static_cast<Vfs::Lxip_vfs_handle*>(vfs_handle);
|
||||
|
||||
return handle->read(dst, count, out_count);
|
||||
return handle->read(dst, out_count);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1731,10 +1724,9 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
|
||||
char const*, unsigned, Vfs::Vfs_handle**) override {
|
||||
return Vfs::Directory::Open_result::OPEN_ERR_UNACCESSIBLE; }
|
||||
|
||||
Lxip::ssize_t read(char *dst, Genode::size_t len,
|
||||
file_size seek_offset) override
|
||||
Lxip::ssize_t read(Byte_range_ptr const &dst, file_size seek_offset) override
|
||||
{
|
||||
if (len < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return -1;
|
||||
|
||||
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)];
|
||||
|
||||
Dirent &out = *(Dirent*)dst;
|
||||
Dirent &out = *(Dirent*)dst.start;
|
||||
|
||||
out = {
|
||||
.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 **
|
||||
*************************************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle, char const *src,
|
||||
file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle,
|
||||
Vfs::Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Vfs::Lxip_vfs_handle *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; }
|
||||
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Vfs::Byte_range_ptr const &dst,
|
||||
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; }
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ class Backend
|
||||
.type = (op & RUMPUSER_BIO_WRITE)
|
||||
? Block::Operation::Type::WRITE
|
||||
: Block::Operation::Type::READ,
|
||||
.block_number = offset / _info.block_size,
|
||||
.block_number = block_number_t(offset / _info.block_size),
|
||||
.count = length / _info.block_size };
|
||||
|
||||
bool const success = _synchronous_io(data, operation);
|
||||
|
@ -80,16 +80,16 @@ class Vfs::Rump_file_system : public File_system
|
||||
{
|
||||
using Vfs_handle::Vfs_handle;
|
||||
|
||||
virtual Read_result read(char *buf, file_size buf_size,
|
||||
file_size seek_offset, file_size &out_count)
|
||||
virtual Read_result read(Byte_range_ptr const &dst,
|
||||
file_size seek_offset, size_t &out_count)
|
||||
{
|
||||
Genode::error("Rump_vfs_handle::read() called");
|
||||
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 &out_count)
|
||||
size_t &out_count)
|
||||
{
|
||||
Genode::error("Rump_vfs_handle::write() called");
|
||||
return WRITE_ERR_INVALID;
|
||||
@ -131,10 +131,10 @@ class Vfs::Rump_file_system : public File_system
|
||||
return FTRUNCATE_OK;
|
||||
}
|
||||
|
||||
Read_result read(char *buf, file_size buf_size,
|
||||
file_size seek_offset, file_size &out_count) override
|
||||
Read_result read(Byte_range_ptr const &dst,
|
||||
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) {
|
||||
case EWOULDBLOCK: return READ_ERR_WOULD_BLOCK;
|
||||
case EINVAL: return READ_ERR_INVALID;
|
||||
@ -148,13 +148,12 @@ class Vfs::Rump_file_system : public File_system
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *buf, file_size buf_size,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src,
|
||||
file_size seek_offset, size_t &out_count) override
|
||||
{
|
||||
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) {
|
||||
case EWOULDBLOCK: return WRITE_ERR_WOULD_BLOCK;
|
||||
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); }
|
||||
|
||||
Read_result read(char *dst, file_size count,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Read_result read(Byte_range_ptr const &dst,
|
||||
file_size seek_offset, size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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);
|
||||
|
||||
@ -289,9 +287,8 @@ class Vfs::Rump_file_system : public File_system
|
||||
int status_flags, char const *path)
|
||||
: Rump_vfs_handle(fs, fs, alloc, status_flags), _path(path) { }
|
||||
|
||||
Read_result read(char *buf, file_size buf_size,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Read_result read(Byte_range_ptr const &dst,
|
||||
file_size seek_offset, size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
|
||||
@ -300,7 +297,7 @@ class Vfs::Rump_file_system : public File_system
|
||||
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)
|
||||
return READ_ERR_IO;
|
||||
|
||||
@ -309,18 +306,17 @@ class Vfs::Rump_file_system : public File_system
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *buf, file_size buf_size,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src,
|
||||
file_size seek_offset, size_t &out_count) override
|
||||
{
|
||||
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;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
out_count = buf_size;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
};
|
||||
@ -781,28 +777,27 @@ class Vfs::Rump_file_system : public File_system
|
||||
** File io service interface **
|
||||
*******************************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle,
|
||||
char const *buf, file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Rump_vfs_handle *handle =
|
||||
static_cast<Rump_vfs_handle *>(vfs_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;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, char *buf,
|
||||
file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||
Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Rump_vfs_handle *handle =
|
||||
static_cast<Rump_vfs_handle *>(vfs_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;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ namespace Cbe_crypto {
|
||||
using uint32_t = Genode::uint32_t;
|
||||
using uint64_t = Genode::uint64_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;
|
||||
|
||||
@ -103,17 +105,15 @@ struct Cbe_crypto::Interface
|
||||
|
||||
virtual bool submit_encryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) = 0;
|
||||
Const_byte_range_ptr const &src) = 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,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) = 0;
|
||||
Const_byte_range_ptr const &src) = 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_ */
|
||||
|
@ -23,13 +23,16 @@ namespace Util {
|
||||
|
||||
using file_size = Vfs::file_size;
|
||||
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 Buffer
|
||||
{
|
||||
char *base;
|
||||
file_size size;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
enum class Operation { INVALID, READ, WRITE, SYNC };
|
||||
@ -83,7 +86,7 @@ namespace Util {
|
||||
char *_data;
|
||||
file_offset const _base_offset;
|
||||
file_offset _current_offset;
|
||||
file_size _current_count;
|
||||
size_t _current_count;
|
||||
|
||||
bool const _allow_partial;
|
||||
|
||||
@ -110,12 +113,11 @@ namespace Util {
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
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
|
||||
|| result == Result::READ_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
@ -170,12 +172,11 @@ namespace Util {
|
||||
using Result = Vfs::File_io_service::Write_result;
|
||||
|
||||
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) {
|
||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||
return progress;
|
||||
|
@ -66,13 +66,15 @@ Crypto::Result Crypto::add_key(Key const &key)
|
||||
key.value, sizeof (key.value));
|
||||
|
||||
_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;
|
||||
|
||||
Const_byte_range_ptr const src(buffer, sizeof(buffer));
|
||||
|
||||
Write_result const result =
|
||||
_add_key_handle.fs().write(&_add_key_handle, buffer, sizeof (buffer),
|
||||
nr_of_written_bytes);
|
||||
_add_key_handle.fs().write(&_add_key_handle, src, written_bytes);
|
||||
|
||||
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||
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)
|
||||
{
|
||||
Vfs::file_size written = 0;
|
||||
size_t written_bytes = 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;
|
||||
|
||||
Write_result const result =
|
||||
_remove_key_handle.fs().write(&_remove_key_handle,
|
||||
(char const*)&key_id.value,
|
||||
sizeof (key_id.value),
|
||||
written);
|
||||
_remove_key_handle.fs().write(&_remove_key_handle, src, written_bytes);
|
||||
|
||||
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||
return Result::RETRY_LATER;
|
||||
@ -195,14 +197,14 @@ void Crypto::_execute_decrypt_block(Job &job,
|
||||
case Job_state::SUBMITTED:
|
||||
{
|
||||
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
||||
file_size nr_of_written_bytes { 0 };
|
||||
|
||||
job.handle->fs().write(
|
||||
job.handle,
|
||||
reinterpret_cast<char const*>(
|
||||
&cipher_buf.item(job.cipher_buf_idx)),
|
||||
file_size(sizeof (Cbe::Block_data)),
|
||||
nr_of_written_bytes);
|
||||
size_t written_bytes = 0;
|
||||
|
||||
Const_byte_range_ptr const src(
|
||||
reinterpret_cast<char const*>(&cipher_buf.item(job.cipher_buf_idx)),
|
||||
sizeof(Cbe::Block_data));
|
||||
|
||||
job.handle->fs().write( job.handle, src, written_bytes);
|
||||
|
||||
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
||||
progress = true;
|
||||
@ -224,14 +226,14 @@ void Crypto::_execute_decrypt_block(Job &job,
|
||||
}
|
||||
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 =
|
||||
job.handle->fs().complete_read(
|
||||
job.handle,
|
||||
reinterpret_cast<char *>(
|
||||
&plain_buf.item(job.plain_buf_idx)),
|
||||
sizeof (Cbe::Block_data),
|
||||
nr_of_read_bytes);
|
||||
job.handle->fs().complete_read(job.handle, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Read_result::READ_QUEUED: return;
|
||||
@ -259,14 +261,15 @@ void Crypto::_execute_encrypt_block(Job &job,
|
||||
case Job_state::SUBMITTED:
|
||||
{
|
||||
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
||||
file_size nr_of_written_bytes { 0 };
|
||||
|
||||
job.handle->fs().write(
|
||||
job.handle,
|
||||
size_t written_bytes = 0;
|
||||
|
||||
Const_byte_range_ptr const src(
|
||||
reinterpret_cast<char const*>(
|
||||
&plain_buf.item(job.plain_buf_idx)),
|
||||
file_size(sizeof (Cbe::Block_data)),
|
||||
nr_of_written_bytes);
|
||||
sizeof(Cbe::Block_data));
|
||||
|
||||
job.handle->fs().write(job.handle, src, written_bytes);
|
||||
|
||||
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
||||
progress = true;
|
||||
@ -288,14 +291,14 @@ void Crypto::_execute_encrypt_block(Job &job,
|
||||
}
|
||||
case Job_state::READING_VFS_HANDLE_SUCCEEDED:
|
||||
{
|
||||
file_size nr_of_read_bytes { 0 };
|
||||
Read_result const result {
|
||||
job.handle->fs().complete_read(
|
||||
job.handle,
|
||||
reinterpret_cast<char *>(
|
||||
&cipher_buf.item(job.cipher_buf_idx)),
|
||||
sizeof (Cbe::Block_data),
|
||||
nr_of_read_bytes) };
|
||||
size_t read_bytes = 0;
|
||||
|
||||
Byte_range_ptr const dst(
|
||||
reinterpret_cast<char *>(&cipher_buf.item(job.cipher_buf_idx)),
|
||||
sizeof (Cbe::Block_data));
|
||||
|
||||
Read_result const result =
|
||||
job.handle->fs().complete_read(job.handle, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Read_result::READ_QUEUED: return;
|
||||
|
@ -298,17 +298,17 @@ class Vfs_block_io_job
|
||||
|
||||
case State::IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_read_bytes { 0 };
|
||||
size_t read_bytes = 0;
|
||||
|
||||
char *const data {
|
||||
reinterpret_cast<char *>(
|
||||
&io_data.item(_cbe_req_io_buf_idx(_cbe_req))) };
|
||||
|
||||
Result const result {
|
||||
_handle.fs().complete_read(&_handle,
|
||||
data + _nr_of_processed_bytes,
|
||||
_nr_of_remaining_bytes,
|
||||
nr_of_read_bytes) };
|
||||
Byte_range_ptr const dst(data + _nr_of_processed_bytes,
|
||||
_nr_of_remaining_bytes);
|
||||
|
||||
Result const result =
|
||||
_handle.fs().complete_read(&_handle, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Result::READ_QUEUED:
|
||||
@ -318,8 +318,8 @@ class Vfs_block_io_job
|
||||
|
||||
case Result::READ_OK:
|
||||
|
||||
_nr_of_processed_bytes += nr_of_read_bytes;
|
||||
_nr_of_remaining_bytes -= nr_of_read_bytes;
|
||||
_nr_of_processed_bytes += read_bytes;
|
||||
_nr_of_remaining_bytes -= read_bytes;
|
||||
|
||||
if (_nr_of_remaining_bytes == 0) {
|
||||
|
||||
@ -385,17 +385,17 @@ class Vfs_block_io_job
|
||||
|
||||
case State::IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_written_bytes { 0 };
|
||||
size_t written_bytes = 0;
|
||||
|
||||
char const *const data {
|
||||
reinterpret_cast<char *>(
|
||||
&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 =
|
||||
_handle.fs().write(&_handle,
|
||||
data + _nr_of_processed_bytes,
|
||||
_nr_of_remaining_bytes,
|
||||
nr_of_written_bytes);
|
||||
_handle.fs().write(&_handle, src, written_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||
@ -403,8 +403,8 @@ class Vfs_block_io_job
|
||||
|
||||
case Result::WRITE_OK:
|
||||
|
||||
_nr_of_processed_bytes += nr_of_written_bytes;
|
||||
_nr_of_remaining_bytes -= nr_of_written_bytes;
|
||||
_nr_of_processed_bytes += written_bytes;
|
||||
_nr_of_remaining_bytes -= written_bytes;
|
||||
|
||||
if (_nr_of_remaining_bytes == 0) {
|
||||
|
||||
|
@ -36,10 +36,12 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
|
||||
|
||||
case Job_state::WRITE_IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_written_bytes { 0 };
|
||||
Write_result const result =
|
||||
file.fs().write(&file, write_buf + _job.fl_offset,
|
||||
_job.fl_size, nr_of_written_bytes);
|
||||
size_t written_bytes { 0 };
|
||||
|
||||
Const_byte_range_ptr const src(write_buf + _job.fl_offset, _job.fl_size);
|
||||
|
||||
Write_result const result = file.fs().write(&file, src, written_bytes);
|
||||
|
||||
switch (result) {
|
||||
|
||||
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:
|
||||
|
||||
_job.fl_offset += nr_of_written_bytes;
|
||||
_job.fl_size -= nr_of_written_bytes;
|
||||
_job.fl_offset += written_bytes;
|
||||
_job.fl_size -= written_bytes;
|
||||
|
||||
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:
|
||||
{
|
||||
file_size nr_of_read_bytes { 0 };
|
||||
Read_result const result {
|
||||
file.fs().complete_read(
|
||||
&file, read_buf + _job.fl_offset, _job.fl_size,
|
||||
nr_of_read_bytes) };
|
||||
size_t read_bytes = 0;
|
||||
|
||||
Byte_range_ptr const dst(read_buf + _job.fl_offset, _job.fl_size);
|
||||
|
||||
Read_result const result = file.fs().complete_read( &file, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Read_result::READ_QUEUED:
|
||||
@ -98,8 +100,8 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
|
||||
|
||||
case Read_result::READ_OK:
|
||||
|
||||
_job.fl_offset += nr_of_read_bytes;
|
||||
_job.fl_size -= nr_of_read_bytes;
|
||||
_job.fl_offset += read_bytes;
|
||||
_job.fl_size -= read_bytes;
|
||||
_job.request.success(true);
|
||||
|
||||
if (_job.fl_size > 0) {
|
||||
@ -142,11 +144,11 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
|
||||
|
||||
case Job_state::WRITE_IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_written_bytes { 0 };
|
||||
Write_result const result =
|
||||
file.fs().write(
|
||||
&file, write_buf + _job.fl_offset,
|
||||
_job.fl_size, nr_of_written_bytes);
|
||||
size_t written_bytes = 0;
|
||||
|
||||
Const_byte_range_ptr const src(write_buf + _job.fl_offset, _job.fl_size);
|
||||
|
||||
Write_result const result = file.fs().write( &file, src, written_bytes);
|
||||
|
||||
switch (result) {
|
||||
|
||||
@ -155,8 +157,8 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
|
||||
|
||||
case Write_result::WRITE_OK:
|
||||
|
||||
_job.fl_offset += nr_of_written_bytes;
|
||||
_job.fl_size -= nr_of_written_bytes;
|
||||
_job.fl_offset += written_bytes;
|
||||
_job.fl_size -= written_bytes;
|
||||
|
||||
if (_job.fl_size > 0) {
|
||||
|
||||
@ -192,11 +194,11 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
|
||||
|
||||
case Job_state::READ_IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_read_bytes { 0 };
|
||||
Read_result const result {
|
||||
file.fs().complete_read(
|
||||
&file, _read_buf + _job.fl_offset, _job.fl_size,
|
||||
nr_of_read_bytes) };
|
||||
size_t read_bytes = 0;
|
||||
|
||||
Byte_range_ptr const dst(_read_buf + _job.fl_offset, _job.fl_size);
|
||||
|
||||
Read_result const result = file.fs().complete_read(&file, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Read_result::READ_QUEUED:
|
||||
@ -206,8 +208,8 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
|
||||
|
||||
case Read_result::READ_OK:
|
||||
|
||||
_job.fl_offset += nr_of_read_bytes;
|
||||
_job.fl_size -= nr_of_read_bytes;
|
||||
_job.fl_offset += read_bytes;
|
||||
_job.fl_size -= read_bytes;
|
||||
_job.request.success(true);
|
||||
|
||||
if (_job.fl_size > 0) {
|
||||
@ -254,11 +256,11 @@ void Trust_anchor::_execute_read_operation(Vfs_handle &file,
|
||||
|
||||
case Job_state::READ_IN_PROGRESS:
|
||||
{
|
||||
file_size nr_of_read_bytes { 0 };
|
||||
Read_result const result {
|
||||
file.fs().complete_read(
|
||||
&file, read_buf + _job.fl_offset, _job.fl_size,
|
||||
nr_of_read_bytes) };
|
||||
size_t read_bytes = 0;
|
||||
|
||||
Byte_range_ptr const dst(read_buf + _job.fl_offset, _job.fl_size);
|
||||
|
||||
Read_result const result = file.fs().complete_read(&file, dst, read_bytes);
|
||||
|
||||
switch (result) {
|
||||
case Read_result::READ_QUEUED:
|
||||
@ -268,8 +270,8 @@ void Trust_anchor::_execute_read_operation(Vfs_handle &file,
|
||||
|
||||
case Read_result::READ_OK:
|
||||
|
||||
_job.fl_offset += nr_of_read_bytes;
|
||||
_job.fl_size -= nr_of_read_bytes;
|
||||
_job.fl_offset += read_bytes;
|
||||
_job.fl_size -= read_bytes;
|
||||
_job.request.success(true);
|
||||
|
||||
if (_job.fl_size > 0) {
|
||||
|
@ -97,11 +97,11 @@ class Vfs_replay
|
||||
Type type;
|
||||
State state;
|
||||
file_offset offset;
|
||||
file_size count;
|
||||
file_size out_count;
|
||||
size_t count;
|
||||
size_t out_count;
|
||||
|
||||
file_offset current_offset;
|
||||
file_size current_count;
|
||||
size_t current_count;
|
||||
|
||||
bool success;
|
||||
bool complete;
|
||||
@ -174,12 +174,14 @@ class Vfs_replay
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
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 =
|
||||
_vfs_handle->fs().complete_read(_vfs_handle,
|
||||
_read_buffer.local_addr<char>(),
|
||||
request.current_count, out);
|
||||
_vfs_handle->fs().complete_read(_vfs_handle, dst, out);
|
||||
|
||||
if (result == Result::READ_QUEUED
|
||||
|| result == Result::READ_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
@ -244,12 +246,13 @@ class Vfs_replay
|
||||
using Result = Vfs::File_io_service::Write_result;
|
||||
|
||||
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) {
|
||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||
return progress;
|
||||
@ -342,7 +345,7 @@ class Vfs_replay
|
||||
if (!_current_request.pending()) {
|
||||
|
||||
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>;
|
||||
Type_String const type_string = node.attribute_value("type", Type_String());
|
||||
|
@ -218,15 +218,14 @@ class Vfs_audit::File_system : public Vfs::File_system
|
||||
**********************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle,
|
||||
const char *buf, file_size len,
|
||||
file_size &out) override
|
||||
Const_byte_range_ptr const &src, size_t &out) override
|
||||
{
|
||||
Handle &h = *static_cast<Handle*>(vfs_handle);
|
||||
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)
|
||||
_log("wrote to ", h.path, " ", out, " / ", len);
|
||||
_log("wrote to ", h.path, " ", out, " / ", src.num_bytes);
|
||||
else if (result == WRITE_ERR_WOULD_BLOCK)
|
||||
_log("write stalled for ", h.path);
|
||||
else
|
||||
@ -235,7 +234,7 @@ class Vfs_audit::File_system : public Vfs::File_system
|
||||
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);
|
||||
h.sync_state();
|
||||
@ -244,13 +243,12 @@ class Vfs_audit::File_system : public Vfs::File_system
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||
char *buf, file_size len,
|
||||
file_size &out) override
|
||||
Byte_range_ptr const &dst, size_t &out) override
|
||||
{
|
||||
Handle &h = *static_cast<Handle*>(vfs_handle);
|
||||
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)
|
||||
_log("completed read from ", h.path, " ", out);
|
||||
|
@ -19,6 +19,9 @@ namespace Vfs_cbe {
|
||||
|
||||
using file_size = Vfs::file_size;
|
||||
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
|
||||
{
|
||||
@ -84,14 +87,14 @@ namespace Vfs_cbe {
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
bool completed = false;
|
||||
file_size out = 0;
|
||||
size_t out = 0;
|
||||
|
||||
char * const data = reinterpret_cast<char *const>(&io_data.item(_index));
|
||||
|
||||
Result const result =
|
||||
_handle.fs().complete_read(&_handle,
|
||||
data + _current_offset,
|
||||
_current_count, out);
|
||||
Byte_range_ptr const dst(data + _current_offset, _current_count);
|
||||
|
||||
Result const result = _handle.fs().complete_read(&_handle, dst, out);
|
||||
|
||||
if (result == Result::READ_QUEUED
|
||||
|| result == Result::READ_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
@ -148,14 +151,15 @@ namespace Vfs_cbe {
|
||||
using Result = Vfs::File_io_service::Write_result;
|
||||
|
||||
bool completed = false;
|
||||
file_size out = 0;
|
||||
size_t out = 0;
|
||||
|
||||
char const * const data =
|
||||
reinterpret_cast<char const * const>(&io_data.item(_index));
|
||||
|
||||
Result const result =
|
||||
_handle.fs().write(&_handle, data + _current_offset,
|
||||
_current_count, out);
|
||||
Const_byte_range_ptr const src(data + _current_offset, _current_count);
|
||||
|
||||
Result const result = _handle.fs().write(&_handle, src, out);
|
||||
|
||||
switch (result) {
|
||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||
return progress;
|
||||
|
@ -516,8 +516,7 @@ class Vfs_cbe::Wrapper
|
||||
}
|
||||
|
||||
bool submit_frontend_request(Vfs_handle &handle,
|
||||
char *data,
|
||||
file_size count,
|
||||
Byte_range_ptr const &data,
|
||||
Cbe::Request::Operation op,
|
||||
uint32_t snap_id)
|
||||
{
|
||||
@ -550,7 +549,9 @@ class Vfs_cbe::Wrapper
|
||||
|
||||
/* unaligned request if any condition is true */
|
||||
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 &&
|
||||
!unaligned_request)
|
||||
@ -589,7 +590,7 @@ class Vfs_cbe::Wrapper
|
||||
op,
|
||||
false,
|
||||
offset / Cbe::BLOCK_SIZE,
|
||||
(uint64_t)data,
|
||||
(uint64_t)data.start,
|
||||
(uint32_t)(count / Cbe::BLOCK_SIZE),
|
||||
0,
|
||||
0);
|
||||
@ -1125,14 +1126,15 @@ class Vfs_cbe::Wrapper
|
||||
memcpy(buffer, &key.id.value, sizeof (key.id.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);
|
||||
|
||||
using Write_result = Vfs::File_io_service::Write_result;
|
||||
|
||||
Const_byte_range_ptr const src(buffer, sizeof(buffer));
|
||||
|
||||
Write_result const result =
|
||||
_add_key_handle->fs().write(_add_key_handle,
|
||||
buffer, sizeof (buffer), written);
|
||||
_add_key_handle->fs().write(_add_key_handle, src, written);
|
||||
|
||||
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||
break; /* try again later */
|
||||
@ -1217,16 +1219,16 @@ class Vfs_cbe::Wrapper
|
||||
break;
|
||||
}
|
||||
|
||||
file_size written = 0;
|
||||
size_t written = 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;
|
||||
|
||||
Write_result const result =
|
||||
_remove_key_handle->fs().write(_remove_key_handle,
|
||||
(char const*)&key_id.value,
|
||||
sizeof (key_id.value),
|
||||
written);
|
||||
_remove_key_handle->fs().write(_remove_key_handle, src, written);
|
||||
|
||||
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||
break; /* try again later */
|
||||
@ -1345,10 +1347,12 @@ class Vfs_cbe::Wrapper
|
||||
data = reinterpret_cast<char const*>(&cipher.item(cipher_index));
|
||||
}
|
||||
|
||||
file_size out = 0;
|
||||
size_t out = 0;
|
||||
_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) {
|
||||
cbe.crypto_cipher_data_requested(plain_index);
|
||||
@ -1377,7 +1381,7 @@ class Vfs_cbe::Wrapper
|
||||
{
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
file_size out = 0;
|
||||
size_t out = 0;
|
||||
char *data = nullptr;
|
||||
|
||||
if (op == Crypto_job::Operation::ENCRYPT) {
|
||||
@ -1388,9 +1392,10 @@ class Vfs_cbe::Wrapper
|
||||
data = reinterpret_cast<char *>(&plain.item(plain_index));
|
||||
}
|
||||
|
||||
Result const res =
|
||||
_handle->fs().complete_read(_handle, data,
|
||||
sizeof (Cbe::Block_data), out);
|
||||
Byte_range_ptr const dst(data, sizeof (Cbe::Block_data));
|
||||
|
||||
Result const res = _handle->fs().complete_read(_handle, dst, out);
|
||||
|
||||
if (_read_queued(res)) {
|
||||
break;
|
||||
}
|
||||
@ -1815,8 +1820,7 @@ class Vfs_cbe::Data_file_system : public Single_file_system
|
||||
_w(w), _snap_id(snap_id)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
bool const accepted =
|
||||
_w.submit_frontend_request(*this, dst, count,
|
||||
Op::READ, _snap_id);
|
||||
_w.submit_frontend_request(*this, dst, Op::READ, _snap_id);
|
||||
if (!accepted) { return READ_ERR_IO; }
|
||||
}
|
||||
|
||||
@ -1865,8 +1868,8 @@ class Vfs_cbe::Data_file_system : public Single_file_system
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
bool const accepted =
|
||||
_w.submit_frontend_request(*this, const_cast<char*>(src),
|
||||
count, Op::WRITE, _snap_id);
|
||||
_w.submit_frontend_request(*this,
|
||||
Byte_range_ptr(
|
||||
const_cast<char*>(src.start),
|
||||
src.num_bytes),
|
||||
Op::WRITE, _snap_id);
|
||||
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;
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
@ -2080,23 +2087,22 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
|
||||
_w(w)
|
||||
{ }
|
||||
|
||||
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 (seek() != 0) {
|
||||
out_count = 0;
|
||||
return READ_OK;
|
||||
}
|
||||
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;
|
||||
out_count = count > length_without_nul - 1 ?
|
||||
length_without_nul : count;
|
||||
out_count = dst.num_bytes > length_without_nul - 1 ?
|
||||
length_without_nul : dst.num_bytes;
|
||||
|
||||
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 State = Wrapper::Extending::State;
|
||||
@ -2105,13 +2111,13 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
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);
|
||||
if (type == Type::INVALID) {
|
||||
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) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
@ -2121,7 +2127,7 @@ class Vfs_cbe::Extend_file_system : public Vfs::Single_file_system
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -2271,23 +2277,22 @@ class Vfs_cbe::Rekey_file_system : public Vfs::Single_file_system
|
||||
_w(w)
|
||||
{ }
|
||||
|
||||
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 (seek() != 0) {
|
||||
out_count = 0;
|
||||
return READ_OK;
|
||||
}
|
||||
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;
|
||||
out_count = count > length_without_nul - 1 ?
|
||||
length_without_nul : count;
|
||||
out_count = dst.num_bytes > length_without_nul - 1 ?
|
||||
length_without_nul : dst.num_bytes;
|
||||
|
||||
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;
|
||||
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 };
|
||||
Genode::ascii_to(src, start_rekeying);
|
||||
Genode::ascii_to(src.start, start_rekeying);
|
||||
|
||||
if (!start_rekeying) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -2305,7 +2310,7 @@ class Vfs_cbe::Rekey_file_system : public Vfs::Single_file_system
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -2455,23 +2460,22 @@ class Vfs_cbe::Deinitialize_file_system : public Vfs::Single_file_system
|
||||
_w(w)
|
||||
{ }
|
||||
|
||||
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 (seek() != 0) {
|
||||
out_count = 0;
|
||||
return READ_OK;
|
||||
}
|
||||
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;
|
||||
out_count = count > length_without_nul - 1 ?
|
||||
length_without_nul : count;
|
||||
out_count = dst.num_bytes > length_without_nul - 1 ?
|
||||
length_without_nul : dst.num_bytes;
|
||||
|
||||
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;
|
||||
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 };
|
||||
Genode::ascii_to(src, start_deinitialize);
|
||||
Genode::ascii_to(src.start, start_deinitialize);
|
||||
|
||||
if (!start_deinitialize) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -2489,7 +2493,7 @@ class Vfs_cbe::Deinitialize_file_system : public Vfs::Single_file_system
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -2605,17 +2609,16 @@ class Vfs_cbe::Create_snapshot_file_system : public Vfs::Single_file_system
|
||||
_w(w)
|
||||
{ }
|
||||
|
||||
Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result read(Byte_range_ptr const &, size_t &) override
|
||||
{
|
||||
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 };
|
||||
Genode::ascii_to(src, create_snapshot);
|
||||
Genode::String<64> str(Genode::Cstring(src, count));
|
||||
Genode::ascii_to(src.start, create_snapshot);
|
||||
Genode::String<64> str(Genode::Cstring(src.start, src.num_bytes));
|
||||
|
||||
if (!create_snapshot) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -2626,7 +2629,7 @@ class Vfs_cbe::Create_snapshot_file_system : public Vfs::Single_file_system
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -2705,18 +2708,18 @@ class Vfs_cbe::Discard_snapshot_file_system : public Vfs::Single_file_system
|
||||
_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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Genode::uint64_t id { 0 };
|
||||
Genode::ascii_to(src, id);
|
||||
Genode::ascii_to(src.start, id);
|
||||
if (id == 0) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
@ -2983,11 +2986,9 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
|
||||
{
|
||||
using Vfs_handle::Vfs_handle;
|
||||
|
||||
virtual Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &, size_t &out_count) = 0;
|
||||
|
||||
virtual Write_result write(char const *src, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Write_result write(Const_byte_range_ptr const &, size_t &out_count) = 0;
|
||||
|
||||
virtual Sync_result sync()
|
||||
{
|
||||
@ -3004,8 +3005,8 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
|
||||
|
||||
bool const _root_dir { false };
|
||||
|
||||
Read_result _query_snapshots(file_size index,
|
||||
file_size &out_count,
|
||||
Read_result _query_snapshots(size_t index,
|
||||
size_t &out_count,
|
||||
Dirent &out)
|
||||
{
|
||||
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,
|
||||
file_size &out_count,
|
||||
Read_result _query_root(size_t index,
|
||||
size_t &out_count,
|
||||
Dirent &out)
|
||||
{
|
||||
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)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -3347,32 +3347,30 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
|
||||
********************************/
|
||||
|
||||
Write_result write(Vfs::Vfs_handle *vfs_handle,
|
||||
char const *buf, file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Const_byte_range_ptr const &, size_t &out_count) override
|
||||
{
|
||||
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 =
|
||||
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
|
||||
if (dh) {
|
||||
return dh->vfs_handle.fs().queue_read(&dh->vfs_handle,
|
||||
size);
|
||||
return dh->vfs_handle.fs().queue_read(&dh->vfs_handle, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs::Vfs_handle *vfs_handle,
|
||||
char *dst, file_size count,
|
||||
file_size & out_count) override
|
||||
Byte_range_ptr const &dst,
|
||||
size_t & out_count) override
|
||||
{
|
||||
Snap_vfs_handle *sh =
|
||||
dynamic_cast<Snap_vfs_handle*>(vfs_handle);
|
||||
if (sh) {
|
||||
Read_result const res = sh->read(dst, count, out_count);
|
||||
Read_result const res = sh->read(dst, out_count);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -3380,7 +3378,7 @@ class Vfs_cbe::Snapshots_file_system : public Vfs::File_system
|
||||
dynamic_cast<Dir_snap_vfs_handle*>(vfs_handle);
|
||||
if (dh) {
|
||||
return dh->vfs_handle.fs().complete_read(&dh->vfs_handle,
|
||||
dst, count, out_count);
|
||||
dst, out_count);
|
||||
}
|
||||
|
||||
return READ_ERR_IO;
|
||||
|
@ -160,10 +160,9 @@ struct Crypto : Cbe_crypto::Interface
|
||||
|
||||
bool submit_encryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
Const_byte_range_ptr const &src) override
|
||||
{
|
||||
if (!src || src_len != sizeof (Cbe::Block_data)) {
|
||||
if (!src.start || src.num_bytes != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
@ -179,7 +178,7 @@ struct Crypto : Cbe_crypto::Interface
|
||||
uint64_t block_id = job.request.block_number();
|
||||
|
||||
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);
|
||||
|
||||
/* paranoia */
|
||||
@ -190,13 +189,12 @@ struct Crypto : Cbe_crypto::Interface
|
||||
});
|
||||
}
|
||||
|
||||
Complete_request encryption_request_complete(char * const dst,
|
||||
size_t const dst_len) override
|
||||
Complete_request encryption_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::Plaintext), "size mismatch");
|
||||
|
||||
if (dst_len != sizeof (Cbe::Block_data)) {
|
||||
if (dst.num_bytes != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
@ -204,7 +202,7 @@ struct Crypto : Cbe_crypto::Interface
|
||||
uint64_t block_id = 0;
|
||||
|
||||
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();
|
||||
|
||||
@ -217,10 +215,9 @@ struct Crypto : Cbe_crypto::Interface
|
||||
|
||||
bool submit_decryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
Const_byte_range_ptr const &src) override
|
||||
{
|
||||
if (src_len != sizeof (Cbe::Block_data)) {
|
||||
if (src.num_bytes != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
throw Buffer_size_mismatch();
|
||||
}
|
||||
@ -233,17 +230,17 @@ struct Crypto : Cbe_crypto::Interface
|
||||
return jobs.queue_decrypt([&] (auto &job) {
|
||||
job.request = Cbe::Request(Cbe::Request::Operation::READ,
|
||||
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::Plaintext), "size mismatch");
|
||||
|
||||
if (dst_len != sizeof (Cbe::Block_data)) {
|
||||
if (dst.num_bytes != sizeof (Cbe::Block_data)) {
|
||||
error("buffer has wrong size");
|
||||
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::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 */
|
||||
static_assert(sizeof(ciphertext) == sizeof(job.data), "size mismatch");
|
||||
|
@ -65,14 +65,13 @@ struct Crypto : Cbe_crypto::Interface
|
||||
|
||||
bool _submit_request(uint64_t const block_number,
|
||||
uint32_t const /* key_id */,
|
||||
char const *src,
|
||||
size_t const src_len)
|
||||
Const_byte_range_ptr const &src)
|
||||
{
|
||||
if (_request.pending) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (src_len < sizeof (_internal_buffer)) {
|
||||
if (src.num_bytes < sizeof (_internal_buffer)) {
|
||||
error("buffer too small");
|
||||
throw Buffer_too_small();
|
||||
}
|
||||
@ -80,30 +79,29 @@ struct Crypto : Cbe_crypto::Interface
|
||||
_request.pending = true;
|
||||
_request.block_number = block_number;
|
||||
|
||||
Genode::memcpy(_internal_buffer, src, sizeof (_internal_buffer));
|
||||
Genode::memcpy(_internal_buffer, src.start, sizeof (_internal_buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool submit_encryption_request(uint64_t const block_number,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
Const_byte_range_ptr const &src) 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) {
|
||||
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");
|
||||
throw Buffer_too_small();
|
||||
}
|
||||
|
||||
Genode::memcpy(dst, _internal_buffer, sizeof (_internal_buffer));
|
||||
Genode::memcpy(dst.start, _internal_buffer, sizeof (_internal_buffer));
|
||||
|
||||
_request.pending = false;
|
||||
|
||||
@ -112,22 +110,21 @@ struct Crypto : Cbe_crypto::Interface
|
||||
.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,
|
||||
uint32_t const key_id,
|
||||
char const *src,
|
||||
size_t const src_len) override
|
||||
Const_byte_range_ptr const &src) 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -71,8 +71,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
|
||||
_state { State::NONE }
|
||||
{ }
|
||||
|
||||
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 (_state != State::PENDING) {
|
||||
return READ_ERR_IO;
|
||||
@ -82,14 +81,14 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
Cbe_crypto::Interface::Complete_request const cr =
|
||||
_crypto.encryption_request_complete(dst, count);
|
||||
_crypto.encryption_request_complete(dst);
|
||||
if (!cr.valid) {
|
||||
return READ_ERR_INVALID;
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
|
||||
out_count = count;
|
||||
out_count = dst.num_bytes;
|
||||
return READ_OK;
|
||||
} catch (Cbe_crypto::Interface::Buffer_too_small) {
|
||||
return READ_ERR_INVALID;
|
||||
@ -98,8 +97,8 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
|
||||
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
|
||||
{
|
||||
if (_state != State::NONE) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -108,7 +107,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
|
||||
try {
|
||||
uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE;
|
||||
bool const ok =
|
||||
_crypto.submit_encryption_request(block_number, _key_id, src, count);
|
||||
_crypto.submit_encryption_request(block_number, _key_id, src);
|
||||
if (!ok) {
|
||||
out_count = 0;
|
||||
return WRITE_OK;
|
||||
@ -119,7 +118,7 @@ class Vfs_cbe_crypto::Encrypt_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_crypto.execute();
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -206,8 +205,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
|
||||
_state { State::NONE }
|
||||
{ }
|
||||
|
||||
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 (_state != State::PENDING) {
|
||||
return READ_ERR_IO;
|
||||
@ -217,12 +215,12 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
Cbe_crypto::Interface::Complete_request const cr =
|
||||
_crypto.decryption_request_complete(dst, count);
|
||||
_crypto.decryption_request_complete(dst);
|
||||
if (cr.valid) {
|
||||
}
|
||||
_state = State::NONE;
|
||||
|
||||
out_count = count;
|
||||
out_count = dst.num_bytes;
|
||||
return READ_OK;
|
||||
} catch (Cbe_crypto::Interface::Buffer_too_small) {
|
||||
return READ_ERR_INVALID;
|
||||
@ -231,8 +229,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
|
||||
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
|
||||
{
|
||||
if (_state != State::NONE) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -241,7 +238,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
|
||||
try {
|
||||
uint64_t const block_number = seek() / Cbe_crypto::BLOCK_SIZE;
|
||||
bool const ok =
|
||||
_crypto.submit_decryption_request(block_number, _key_id, src, count);
|
||||
_crypto.submit_decryption_request(block_number, _key_id, src);
|
||||
if (!ok) {
|
||||
out_count = 0;
|
||||
return WRITE_OK;
|
||||
@ -252,7 +249,7 @@ class Vfs_cbe_crypto::Decrypt_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_crypto.execute();
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -499,11 +496,11 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
|
||||
{
|
||||
using Vfs_handle::Vfs_handle;
|
||||
|
||||
virtual Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &dst,
|
||||
size_t &out_count) = 0;
|
||||
|
||||
virtual Write_result write(char const *src, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Write_result write(Const_byte_range_ptr const &src,
|
||||
size_t &out_count) = 0;
|
||||
|
||||
virtual Sync_result sync()
|
||||
{
|
||||
@ -520,8 +517,8 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
|
||||
|
||||
bool const _root_dir { false };
|
||||
|
||||
Read_result _query_keys(file_size index,
|
||||
file_size &out_count,
|
||||
Read_result _query_keys(size_t index,
|
||||
size_t &out_count,
|
||||
Dirent &out)
|
||||
{
|
||||
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,
|
||||
file_size &out_count,
|
||||
Read_result _query_root(size_t index,
|
||||
size_t &out_count,
|
||||
Dirent &out)
|
||||
{
|
||||
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)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -851,13 +847,13 @@ class Vfs_cbe_crypto::Keys_file_system : public Vfs::File_system
|
||||
** File I/O service interface **
|
||||
********************************/
|
||||
|
||||
Write_result write(Vfs::Vfs_handle *, char const *,
|
||||
file_size, file_size &) override
|
||||
Write_result write(Vfs::Vfs_handle *,
|
||||
Const_byte_range_ptr const &, size_t &) override
|
||||
{
|
||||
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 =
|
||||
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,
|
||||
char *dst, file_size count,
|
||||
file_size & out_count) override
|
||||
Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Local_vfs_handle *lh =
|
||||
dynamic_cast<Local_vfs_handle*>(vfs_handle);
|
||||
if (lh) {
|
||||
Read_result const res = lh->read(dst, count, out_count);
|
||||
Read_result const res = lh->read(dst, out_count);
|
||||
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);
|
||||
if (dh) {
|
||||
return dh->vfs_handle.fs().complete_read(&dh->vfs_handle,
|
||||
dst, count, out_count);
|
||||
dst, out_count);
|
||||
}
|
||||
|
||||
return READ_ERR_IO;
|
||||
@ -949,13 +945,13 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
|
||||
_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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -963,26 +959,26 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t id = *reinterpret_cast<uint32_t const*>(src);
|
||||
uint32_t id = *reinterpret_cast<uint32_t const*>(src.start);
|
||||
if (id == 0) {
|
||||
return WRITE_ERR_INVALID;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
char const * value = src + sizeof (uint32_t);
|
||||
size_t const value_len = count - sizeof (uint32_t);
|
||||
char const * value = src.start + sizeof (uint32_t);
|
||||
size_t const value_len = src.num_bytes - sizeof (uint32_t);
|
||||
if (_crypto.add_key(id, value, value_len)) {
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
} catch (...) { }
|
||||
@ -991,12 +987,12 @@ class Vfs_cbe_crypto::Management_file_system : public Vfs::Single_file_system
|
||||
|
||||
if (_type == Type::REMOVE_KEY) {
|
||||
|
||||
if (count != sizeof (uint32_t)) {
|
||||
if (src.num_bytes != sizeof (uint32_t)) {
|
||||
return WRITE_ERR_INVALID;
|
||||
}
|
||||
|
||||
if (_crypto.remove_key(id)) {
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ class Trust_anchor
|
||||
Trust_anchor &operator=(Trust_anchor const&) = delete;
|
||||
|
||||
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;
|
||||
|
||||
@ -978,7 +980,7 @@ class Trust_anchor
|
||||
return result;
|
||||
}
|
||||
|
||||
bool queue_initialize(char const *src, size_t len)
|
||||
bool queue_initialize(Const_byte_range_ptr const &src)
|
||||
{
|
||||
if (_job != Job::NONE) {
|
||||
return false;
|
||||
@ -987,7 +989,7 @@ class Trust_anchor
|
||||
if (_state != State::UNINITIALIZED) {
|
||||
return false;
|
||||
}
|
||||
SHA256((unsigned char const *)src, len,
|
||||
SHA256((unsigned char const *)src.start, src.num_bytes,
|
||||
(unsigned char *)_passphrase_hash_buffer.base);
|
||||
|
||||
_passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH;
|
||||
@ -1010,7 +1012,7 @@ class Trust_anchor
|
||||
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) {
|
||||
return false;
|
||||
@ -1027,7 +1029,7 @@ class Trust_anchor
|
||||
return true;
|
||||
}
|
||||
|
||||
SHA256((unsigned char const *)src, len,
|
||||
SHA256((unsigned char const *)src.start, src.num_bytes,
|
||||
(unsigned char *)_passphrase_hash_buffer.base);
|
||||
|
||||
_passphrase_hash_buffer.size = SHA256_DIGEST_LENGTH;
|
||||
@ -1065,24 +1067,24 @@ class Trust_anchor
|
||||
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) {
|
||||
return { false, false };
|
||||
}
|
||||
|
||||
if (len < _last_hash.length) {
|
||||
if (dst.num_bytes < _last_hash.length) {
|
||||
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_state = Job_state::NONE;
|
||||
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) {
|
||||
return false;
|
||||
@ -1092,20 +1094,17 @@ class Trust_anchor
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len != _last_hash.length) {
|
||||
if (src.num_bytes != _last_hash.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len > _hash_io_job_buffer.size) {
|
||||
len = _hash_io_job_buffer.size;
|
||||
}
|
||||
size_t const len = Genode::min(src.num_bytes, _hash_io_job_buffer.size);
|
||||
|
||||
_hash_io_job_buffer.size = len;
|
||||
|
||||
Genode::memcpy(_hash_io_job_buffer.buffer, src,
|
||||
_hash_io_job_buffer.size);
|
||||
Genode::memcpy(_hash_io_job_buffer.buffer, src.start, len);
|
||||
|
||||
Genode::memcpy(_last_hash.value, src, len);
|
||||
Genode::memcpy(_last_hash.value, src.start, len);
|
||||
|
||||
_job = Job::UPDATE_HASH;
|
||||
_job_state = Job_state::PENDING;
|
||||
@ -1123,7 +1122,7 @@ class Trust_anchor
|
||||
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) {
|
||||
return false;
|
||||
@ -1133,39 +1132,39 @@ class Trust_anchor
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len != _encrypt_key.length) {
|
||||
if (src.num_bytes != _encrypt_key.length) {
|
||||
Genode::error(__func__, ": key length mismatch, expected: ",
|
||||
_encrypt_key.length, " got: ", len);
|
||||
_encrypt_key.length, " got: ", src.num_bytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
Genode::memcpy(_encrypt_key.value, src, len);
|
||||
Genode::memcpy(_encrypt_key.value, src.start, src.num_bytes);
|
||||
|
||||
_job = Job::ENCRYPT;
|
||||
_job_state = Job_state::PENDING;
|
||||
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) {
|
||||
return { false, false };
|
||||
}
|
||||
|
||||
if (len != _encrypt_key.length) {
|
||||
if (dst.num_bytes != _encrypt_key.length) {
|
||||
Genode::error(__func__, ": key length mismatch, expected: ",
|
||||
_encrypt_key.length, " got: ", len);
|
||||
_encrypt_key.length, " got: ", dst.num_bytes);
|
||||
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_state = Job_state::NONE;
|
||||
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) {
|
||||
return false;
|
||||
@ -1175,32 +1174,32 @@ class Trust_anchor
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len != _decrypt_key.length) {
|
||||
if (src.num_bytes != _decrypt_key.length) {
|
||||
Genode::error(__func__, ": key length mismatch, expected: ",
|
||||
_decrypt_key.length, " got: ", len);
|
||||
_decrypt_key.length, " got: ", src.num_bytes);
|
||||
return false;
|
||||
}
|
||||
|
||||
Genode::memcpy(_decrypt_key.value, src, len);
|
||||
Genode::memcpy(_decrypt_key.value, src.start, src.num_bytes);
|
||||
|
||||
_job = Job::DECRYPT;
|
||||
_job_state = Job_state::PENDING;
|
||||
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) {
|
||||
return { false, false };
|
||||
}
|
||||
|
||||
if (len != _decrypt_key.length) {
|
||||
if (dst.num_bytes != _decrypt_key.length) {
|
||||
Genode::error(__func__, ": key length mismatch, expected: ",
|
||||
_decrypt_key.length, " got: ", len);
|
||||
_decrypt_key.length, " got: ", dst.num_bytes);
|
||||
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_state = Job_state::NONE;
|
||||
@ -1218,21 +1217,21 @@ class Trust_anchor
|
||||
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) {
|
||||
return { false, false };
|
||||
}
|
||||
|
||||
size_t len = dst.num_bytes;
|
||||
|
||||
if (len < _generated_key.length) {
|
||||
Genode::warning("truncate generated key");
|
||||
} else
|
||||
|
||||
if (len > _generated_key.length) {
|
||||
len = _generated_key.length;
|
||||
} else {
|
||||
len = Genode::min(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));
|
||||
|
||||
_job = Job::NONE;
|
||||
@ -1264,8 +1263,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
|
||||
_trust_anchor { ta }
|
||||
{ }
|
||||
|
||||
Read_result read(char *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result read(Byte_range_ptr const &src, size_t &out_count) override
|
||||
{
|
||||
_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) {
|
||||
try {
|
||||
Trust_anchor::Complete_request const cr =
|
||||
_trust_anchor.complete_read_last_hash(src, count);
|
||||
_trust_anchor.complete_read_last_hash(src);
|
||||
if (!cr.valid) {
|
||||
_trust_anchor.execute();
|
||||
return READ_QUEUED;
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return cr.success ? READ_OK : READ_ERR_IO;
|
||||
} catch (...) {
|
||||
return READ_ERR_INVALID;
|
||||
@ -1312,7 +1310,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return cr.success ? READ_OK : READ_ERR_IO;
|
||||
} catch (...) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
_trust_anchor.execute();
|
||||
|
||||
@ -1332,8 +1329,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
try {
|
||||
bool const ok =
|
||||
_trust_anchor.queue_update_last_hash(src, count);
|
||||
bool const ok = _trust_anchor.queue_update_last_hash(src);
|
||||
if (!ok) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
@ -1343,7 +1339,7 @@ class Vfs_cbe_trust_anchor::Hashsum_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_trust_anchor.execute();
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -1425,8 +1421,7 @@ class Vfs_cbe_trust_anchor::Generate_key_file_system : public Vfs::Single_file_s
|
||||
_trust_anchor { ta }
|
||||
{ }
|
||||
|
||||
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 (_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();
|
||||
|
||||
Trust_anchor::Complete_request const cr =
|
||||
_trust_anchor.complete_generate_key(dst, count);
|
||||
_trust_anchor.complete_generate_key(dst);
|
||||
if (!cr.valid) {
|
||||
return READ_QUEUED;
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
out_count = count;
|
||||
out_count = dst.num_bytes;
|
||||
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;
|
||||
}
|
||||
@ -1533,8 +1528,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
|
||||
_state { State::NONE }
|
||||
{ }
|
||||
|
||||
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 (_state != State::PENDING) {
|
||||
return READ_ERR_IO;
|
||||
@ -1544,14 +1538,14 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
Trust_anchor::Complete_request const cr =
|
||||
_trust_anchor.complete_encrypt_key(dst, count);
|
||||
_trust_anchor.complete_encrypt_key(dst);
|
||||
if (!cr.valid) {
|
||||
return READ_QUEUED;
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
|
||||
out_count = count;
|
||||
out_count = dst.num_bytes;
|
||||
return cr.success ? READ_OK : READ_ERR_IO;
|
||||
} catch (...) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 (_state != State::NONE) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -1569,7 +1562,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
bool const ok =
|
||||
_trust_anchor.queue_encrypt_key(src, count);
|
||||
_trust_anchor.queue_encrypt_key(src);
|
||||
if (!ok) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
@ -1579,7 +1572,7 @@ class Vfs_cbe_trust_anchor::Encrypt_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_trust_anchor.execute();
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -1661,8 +1654,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
|
||||
_state { State::NONE }
|
||||
{ }
|
||||
|
||||
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 (_state != State::PENDING) {
|
||||
return READ_ERR_IO;
|
||||
@ -1672,14 +1664,14 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
Trust_anchor::Complete_request const cr =
|
||||
_trust_anchor.complete_decrypt_key(dst, count);
|
||||
_trust_anchor.complete_decrypt_key(dst);
|
||||
if (!cr.valid) {
|
||||
return READ_QUEUED;
|
||||
}
|
||||
|
||||
_state = State::NONE;
|
||||
|
||||
out_count = count;
|
||||
out_count = dst.num_bytes;
|
||||
return cr.success ? READ_OK : READ_ERR_IO;
|
||||
} catch (...) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 (_state != State::NONE) {
|
||||
return WRITE_ERR_IO;
|
||||
@ -1697,7 +1688,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
|
||||
|
||||
try {
|
||||
bool const ok =
|
||||
_trust_anchor.queue_decrypt_key(src, count);
|
||||
_trust_anchor.queue_decrypt_key(src);
|
||||
if (!ok) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
@ -1707,7 +1698,7 @@ class Vfs_cbe_trust_anchor::Decrypt_file_system : public Vfs::Single_file_system
|
||||
}
|
||||
|
||||
_trust_anchor.execute();
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
@ -1790,7 +1781,7 @@ class Vfs_cbe_trust_anchor::Initialize_file_system : public Vfs::Single_file_sys
|
||||
_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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 (_state != State::NONE) {
|
||||
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();
|
||||
|
||||
bool const res = _init_pending ? _trust_anchor.queue_unlock(src, count)
|
||||
: _trust_anchor.queue_initialize(src, count);
|
||||
bool const res = _init_pending ? _trust_anchor.queue_unlock(src)
|
||||
: _trust_anchor.queue_initialize(src);
|
||||
|
||||
if (!res) {
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
_state = State::PENDING;
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
|
@ -63,19 +63,18 @@ struct Vfs_gpu::File_system : Single_file_system
|
||||
_gpu_session.completion_sigh(_completion_sigh);
|
||||
}
|
||||
|
||||
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 (!_complete) return READ_QUEUED;
|
||||
|
||||
_complete = false;
|
||||
dst[0] = 1;
|
||||
dst.start[0] = 1;
|
||||
out_count = 1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -91,17 +91,17 @@ class Vfs_import::File_system : public Vfs::File_system
|
||||
{
|
||||
Flush_guard flush(env.io(), *dst_handle);
|
||||
|
||||
file_size count = target.length();
|
||||
Const_byte_range_ptr const src { target.string(), target.length() };
|
||||
|
||||
for (;;) {
|
||||
file_size out_count = 0;
|
||||
auto wres = dst_handle->fs().write(
|
||||
dst_handle, target.string(), count, out_count);
|
||||
size_t out_count = 0;
|
||||
auto wres = dst_handle->fs().write(dst_handle, src, out_count);
|
||||
|
||||
switch (wres) {
|
||||
case WRITE_ERR_WOULD_BLOCK:
|
||||
break;
|
||||
default:
|
||||
if (out_count < count) {
|
||||
if (out_count < src.num_bytes) {
|
||||
Genode::error("failed to write symlink ", path, ", ", wres);
|
||||
env.root_dir().unlink(path.string());
|
||||
}
|
||||
@ -146,22 +146,26 @@ class Vfs_import::File_system : public Vfs::File_system
|
||||
|
||||
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)));
|
||||
|
||||
if (!bytes_from_source) break;
|
||||
if (!bytes_from_source)
|
||||
break;
|
||||
|
||||
bool write_error { false };
|
||||
Vfs::file_size remaining_bytes { bytes_from_source };
|
||||
char const *src { buf };
|
||||
bool write_error = false;
|
||||
|
||||
size_t remaining_bytes = bytes_from_source;
|
||||
|
||||
char const *src_ptr = buf;
|
||||
|
||||
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:
|
||||
env.io().commit_and_wait();
|
||||
break;
|
||||
@ -175,7 +179,7 @@ class Vfs_import::File_system : public Vfs::File_system
|
||||
case WRITE_OK:
|
||||
out_count = min(remaining_bytes, out_count);
|
||||
remaining_bytes -= out_count;
|
||||
src += out_count;
|
||||
src_ptr += out_count;
|
||||
at.value += out_count;
|
||||
dst_handle->advance_seek(out_count);
|
||||
break;
|
||||
@ -275,14 +279,10 @@ class Vfs_import::File_system : public Vfs::File_system
|
||||
** File I/O service **
|
||||
**********************/
|
||||
|
||||
Write_result write(Vfs_handle*,
|
||||
const char *, file_size,
|
||||
file_size &) override {
|
||||
Write_result write(Vfs_handle*, Const_byte_range_ptr const &, size_t &) override {
|
||||
return WRITE_ERR_INVALID; }
|
||||
|
||||
Read_result complete_read(Vfs_handle*,
|
||||
char*, file_size,
|
||||
file_size&) override {
|
||||
Read_result complete_read(Vfs_handle*, Byte_range_ptr const &, size_t &) override {
|
||||
return READ_ERR_INVALID; }
|
||||
|
||||
bool read_ready(Vfs_handle const &) const override {
|
||||
|
@ -68,13 +68,8 @@ struct Vfs_pipe::Pipe_handle : Vfs::Vfs_handle, private Pipe_handle_registry_ele
|
||||
|
||||
virtual ~Pipe_handle();
|
||||
|
||||
Write_result write(const char *buf,
|
||||
file_size count,
|
||||
file_size &out_count);
|
||||
|
||||
Read_result read(char *buf,
|
||||
file_size count,
|
||||
file_size &out_count);
|
||||
Write_result write(Const_byte_range_ptr const &, size_t &out_count);
|
||||
Read_result read (Byte_range_ptr const &, size_t &out_count);
|
||||
|
||||
bool read_ready() const;
|
||||
bool write_ready() const;
|
||||
@ -197,19 +192,18 @@ struct Vfs_pipe::Pipe
|
||||
return Open_result::OPEN_ERR_UNACCESSIBLE;
|
||||
}
|
||||
|
||||
Write_result write(Pipe_handle &,
|
||||
const char *buf, file_size count,
|
||||
file_size &out_count)
|
||||
Write_result write(Pipe_handle &, Const_byte_range_ptr const &src, size_t &out_count)
|
||||
{
|
||||
file_size out = 0;
|
||||
size_t out = 0;
|
||||
|
||||
if (buffer.avail_capacity() == 0) {
|
||||
out_count = 0;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
|
||||
while (out < count && 0 < buffer.avail_capacity()) {
|
||||
buffer.add(*(buf++));
|
||||
char const *buf_ptr = src.start;
|
||||
while (out < src.num_bytes && 0 < buffer.avail_capacity()) {
|
||||
buffer.add(*(buf_ptr++));
|
||||
++out;
|
||||
}
|
||||
|
||||
@ -221,13 +215,13 @@ struct Vfs_pipe::Pipe
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
|
||||
Read_result read(Pipe_handle &handle,
|
||||
char *buf, file_size count,
|
||||
file_size &out_count)
|
||||
Read_result read(Pipe_handle &handle, Byte_range_ptr const &dst, size_t &out_count)
|
||||
{
|
||||
file_size out = 0;
|
||||
while (out < count && !buffer.empty()) {
|
||||
*(buf++) = buffer.get();
|
||||
size_t out = 0;
|
||||
|
||||
char *buf_ptr = dst.start;
|
||||
while (out < dst.num_bytes && !buffer.empty()) {
|
||||
*(buf_ptr++) = buffer.get();
|
||||
++out;
|
||||
}
|
||||
|
||||
@ -252,21 +246,23 @@ struct Vfs_pipe::Pipe
|
||||
};
|
||||
|
||||
|
||||
Vfs_pipe::Pipe_handle::~Pipe_handle() {
|
||||
pipe.remove(*this); }
|
||||
Vfs_pipe::Pipe_handle::~Pipe_handle()
|
||||
{
|
||||
pipe.remove(*this);
|
||||
}
|
||||
|
||||
|
||||
Vfs_pipe::Write_result
|
||||
Vfs_pipe::Pipe_handle::write(const char *buf,
|
||||
file_size count,
|
||||
file_size &out_count) {
|
||||
return Pipe_handle::pipe.write(*this, buf, count, out_count); }
|
||||
Vfs_pipe::Pipe_handle::write(Const_byte_range_ptr const &src, size_t &out_count)
|
||||
{
|
||||
return Pipe_handle::pipe.write(*this, src, out_count);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
Read_result read(char *buf,
|
||||
file_size count,
|
||||
file_size &out_count)
|
||||
Read_result read(Byte_range_ptr const &dst, size_t &out_count)
|
||||
{
|
||||
auto name = pipe.name();
|
||||
if (name.length() < count) {
|
||||
memcpy(buf, name.string(), name.length());
|
||||
if (name.length() < dst.num_bytes) {
|
||||
memcpy(dst.start, name.string(), name.length());
|
||||
out_count = name.length();
|
||||
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,
|
||||
const char *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Const_byte_range_ptr const &src, size_t &out_count) override
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Byte_range_ptr const &dst, size_t &out_count) override
|
||||
{
|
||||
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))
|
||||
return handle->read(dst, count, out_count);
|
||||
return handle->read(dst, out_count);
|
||||
|
||||
return READ_ERR_INVALID;
|
||||
}
|
||||
|
@ -122,16 +122,15 @@ class Vfs_trace::Trace_buffer_file_system : public Single_file_system
|
||||
: Single_vfs_handle(ds, fs, alloc, 0), _entries(entries)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
_entries.for_each_new_entry([&](Trace::Buffer::Entry entry) {
|
||||
file_size size = min(count - out_count, entry.length());
|
||||
memcpy(dst + out_count, entry.data(), (size_t)size);
|
||||
size_t const size = min(dst.num_bytes - out_count, entry.length());
|
||||
memcpy(dst.start + out_count, entry.data(), size);
|
||||
out_count += size;
|
||||
|
||||
if (out_count == count)
|
||||
if (out_count == dst.num_bytes)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -140,8 +139,7 @@ class Vfs_trace::Trace_buffer_file_system : public Single_file_system
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *, file_size,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &, size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
return WRITE_ERR_INVALID;
|
||||
|
@ -54,17 +54,19 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
|
||||
Single_vfs_handle(ds, fs, alloc, 0), _font(font)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
if (seek() > FILE_SIZE)
|
||||
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) {
|
||||
|
||||
@ -73,10 +75,10 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
|
||||
Glyph_header const header(glyph);
|
||||
|
||||
char const * const src = (char const *)&header + byte_offset;
|
||||
size_t const len = min(sizeof(header) - (size_t)byte_offset, (size_t)count);
|
||||
memcpy(dst, src, len);
|
||||
size_t const len = min(sizeof(header) - byte_offset, count);
|
||||
memcpy(dst_ptr, src, len);
|
||||
|
||||
dst += len;
|
||||
dst_ptr += len;
|
||||
byte_offset += len;
|
||||
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) {
|
||||
char const * const src = (char const *)glyph.values + alpha_offset;
|
||||
size_t const len = min(alpha_values_len - alpha_offset, (size_t)count);
|
||||
memcpy(dst, src, len);
|
||||
size_t const len = min(alpha_values_len - alpha_offset, count);
|
||||
memcpy(dst_ptr, src, len);
|
||||
out_count += len;
|
||||
}
|
||||
});
|
||||
@ -101,7 +103,7 @@ class Vfs::Glyphs_file_system : public Vfs::Single_file_system
|
||||
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;
|
||||
}
|
||||
|
@ -846,12 +846,14 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
||||
|
||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||
|
||||
Vfs::file_size out_count = 0;
|
||||
::size_t out_count = 0;
|
||||
Result out_result = Result::WRITE_OK;
|
||||
|
||||
Const_byte_range_ptr const src { (char const *)buf, count };
|
||||
|
||||
if (fd->flags & O_NONBLOCK) {
|
||||
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;
|
||||
});
|
||||
} else {
|
||||
@ -862,7 +864,7 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
||||
Vfs::Vfs_handle *_handle { handle };
|
||||
void const *_buf { buf };
|
||||
::size_t _count { count };
|
||||
Vfs::file_size &_out_count { out_count };
|
||||
::size_t &_out_count { out_count };
|
||||
Result &_out_result { out_result };
|
||||
::off_t _offset { 0 };
|
||||
unsigned _iteration { 0 };
|
||||
@ -889,10 +891,12 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
||||
for (;;) {
|
||||
|
||||
/* 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;
|
||||
_out_result = _handle->fs().write(_handle, src, _count, partial_out_count);
|
||||
Const_byte_range_ptr const src { (char const *)_buf + _offset,
|
||||
_count };
|
||||
|
||||
_out_result = _handle->fs().write(_handle, src, partial_out_count);
|
||||
|
||||
if (_out_result == Result::WRITE_ERR_WOULD_BLOCK)
|
||||
return Fn::INCOMPLETE;
|
||||
@ -986,11 +990,12 @@ ssize_t Libc::Vfs_plugin::read(File_descriptor *fd, void *buf,
|
||||
if (!succeeded)
|
||||
return Errno(result_errno);
|
||||
|
||||
Vfs::file_size out_count = 0;
|
||||
::size_t out_count = 0;
|
||||
Result out_result;
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
@ -1034,10 +1039,11 @@ ssize_t Libc::Vfs_plugin::getdirentries(File_descriptor *fd, char *buf,
|
||||
});
|
||||
|
||||
Result out_result;
|
||||
Vfs::file_size out_count;
|
||||
::size_t out_count;
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
@ -2072,8 +2078,10 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
|
||||
{
|
||||
Vfs::Vfs_handle *handle { nullptr };
|
||||
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 };
|
||||
@ -2127,10 +2135,12 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
|
||||
|
||||
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)
|
||||
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 };
|
||||
|
||||
Stage stage { Stage::OPEN };
|
||||
Vfs::Vfs_handle *handle { nullptr };
|
||||
Vfs::file_size out_len { 0 };
|
||||
|
||||
bool succeeded { false };
|
||||
int result_errno { 0 };
|
||||
Vfs::Vfs_handle *handle = nullptr;
|
||||
|
||||
::size_t out_count = 0;
|
||||
bool succeeded = false;
|
||||
int result_errno = 0;
|
||||
|
||||
monitor().monitor([&] {
|
||||
|
||||
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:
|
||||
{
|
||||
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 =
|
||||
handle->fs().complete_read(handle, buf, buf_size, out_len);
|
||||
handle->fs().complete_read(handle, dst, out_count);
|
||||
|
||||
switch (out_result) {
|
||||
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)
|
||||
return Errno(result_errno);
|
||||
|
||||
return out_len;
|
||||
return out_count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,9 +88,8 @@ class Fatfs::File_system : public Vfs::File_system
|
||||
{
|
||||
using Vfs_handle::Vfs_handle;
|
||||
|
||||
virtual Read_result complete_read(char *buf,
|
||||
file_size buf_size,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result complete_read(Byte_range_ptr const &dst,
|
||||
size_t &out_count) = 0;
|
||||
};
|
||||
|
||||
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_handle(fs, fs, alloc, status_flags) { }
|
||||
|
||||
Read_result complete_read(char *buf,
|
||||
file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
if (!file) {
|
||||
Genode::error("READ_ERR_INVALID");
|
||||
@ -138,7 +136,7 @@ class Fatfs::File_system : public Vfs::File_system
|
||||
fres = f_lseek(fil, seek());
|
||||
if (fres == FR_OK) {
|
||||
UINT bw = 0;
|
||||
fres = f_read(fil, buf, buf_size, &bw);
|
||||
fres = f_read(fil, dst.start, dst.num_bytes, &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_handle(fs, fs, alloc, 0), path(path) { }
|
||||
|
||||
Read_result complete_read(char *buf,
|
||||
file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
/* not very efficient, just N calls to f_readdir */
|
||||
|
||||
out_count = 0;
|
||||
|
||||
if (buf_size < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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) {
|
||||
/* reset the seek position */
|
||||
f_readdir(&dir, nullptr);
|
||||
cur_index = 0;
|
||||
}
|
||||
|
||||
Dirent &vfs_dirent = *(Dirent*)buf;
|
||||
Dirent &vfs_dirent = *(Dirent*)dst.start;
|
||||
|
||||
FILINFO info;
|
||||
FRESULT res;
|
||||
@ -692,9 +689,8 @@ class Fatfs::File_system : public Vfs::File_system
|
||||
** File io service interface **
|
||||
*******************************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle,
|
||||
char const *buf, file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Fatfs_file_handle *handle = static_cast<Fatfs_file_handle *>(vfs_handle);
|
||||
if (!handle->file)
|
||||
@ -723,7 +719,7 @@ class Fatfs::File_system : public Vfs::File_system
|
||||
|
||||
if (fres == FR_OK) {
|
||||
UINT bw = 0;
|
||||
fres = f_write(fil, buf, buf_size, &bw);
|
||||
fres = f_write(fil, src.start, src.num_bytes, &bw);
|
||||
f_sync(fil);
|
||||
handle->modifying = true;
|
||||
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,
|
||||
file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
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
|
||||
|
@ -67,29 +67,27 @@ class Jitterentropy_file_system : public Vfs::Single_file_system
|
||||
_ec_stir(ec_stir),
|
||||
_initialized(initialized) { }
|
||||
|
||||
Read_result read(char *dst, Vfs::file_size count,
|
||||
Vfs::file_size &out_count) override
|
||||
Read_result read(Genode::Byte_range_ptr const &dst, size_t &out_count) override
|
||||
{
|
||||
if (!_initialized)
|
||||
return READ_ERR_IO;
|
||||
|
||||
enum { MAX_BUF_LEN = 256 };
|
||||
enum { MAX_BUF_LEN = 256UL };
|
||||
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)
|
||||
return READ_ERR_IO;
|
||||
|
||||
Genode::memcpy(dst, buf, len);
|
||||
Genode::memcpy(dst.start, buf, len);
|
||||
|
||||
out_count = len;
|
||||
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *src, Vfs::file_size count,
|
||||
Vfs::file_size &out_count) override
|
||||
Write_result write(Genode::Const_byte_range_ptr const &, size_t &) override
|
||||
{
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
|
@ -86,8 +86,7 @@ class Libusb_file_system : public Vfs::Single_file_system
|
||||
return nonconst_this._usb_connection.source()->ack_avail();
|
||||
}
|
||||
|
||||
Read_result read(char *dst, Vfs::file_size count,
|
||||
Vfs::file_size &out_count) override
|
||||
Read_result read(Genode::Byte_range_ptr const &, Genode::size_t &) override
|
||||
{
|
||||
return READ_ERR_IO;
|
||||
}
|
||||
@ -97,8 +96,7 @@ class Libusb_file_system : public Vfs::Single_file_system
|
||||
return true;
|
||||
}
|
||||
|
||||
Write_result write(char const *src, Vfs::file_size count,
|
||||
Vfs::file_size &out_count) override
|
||||
Write_result write(Genode::Const_byte_range_ptr const &, Genode::size_t &) override
|
||||
{
|
||||
return WRITE_ERR_IO;
|
||||
}
|
||||
|
@ -130,8 +130,7 @@ struct Lwip::Directory
|
||||
{
|
||||
virtual ~Directory() { }
|
||||
|
||||
virtual Read_result readdir(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result readdir(Byte_range_ptr const &dst, size_t &out_count) = 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)
|
||||
: Vfs_handle(fs, fs, alloc, status_flags) { }
|
||||
|
||||
virtual Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
|
||||
|
||||
virtual Write_result write(char const *, file_size,
|
||||
file_size &) {
|
||||
virtual Write_result write(Const_byte_range_ptr const &, size_t &) {
|
||||
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_handle(fs, alloc, 0), dir(&dir) { }
|
||||
|
||||
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
|
||||
{
|
||||
return (dir)
|
||||
? dir->readdir(dst, count, out_count)
|
||||
? dir->readdir(dst, out_count)
|
||||
: 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),
|
||||
Nameserver_registry::Element(registry, *this) { }
|
||||
|
||||
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
|
||||
{
|
||||
memset(dst, 0x00, min(file_size(IPADDR_STRLEN_MAX), count));
|
||||
ipaddr_ntoa_r(dns_getserver(0), dst, count);
|
||||
memset(dst.start, 0x00, min(file_size(IPADDR_STRLEN_MAX), dst.num_bytes));
|
||||
ipaddr_ntoa_r(dns_getserver(0), dst.start, dst.num_bytes);
|
||||
|
||||
auto n = strlen(dst);
|
||||
if (n < count)
|
||||
dst[n] = '\n';
|
||||
auto n = strlen(dst.start);
|
||||
if (n < dst.num_bytes)
|
||||
dst.start[n] = '\n';
|
||||
|
||||
out_count = n+1;
|
||||
return Read_result::READ_OK;
|
||||
@ -208,8 +203,7 @@ struct Lwip::Lwip_address_handle final : Lwip_handle
|
||||
, netif(netif)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -220,8 +214,8 @@ struct Lwip::Lwip_address_handle final : Lwip_handle
|
||||
Genode::String<ADDRESS_FILE_SIZE>
|
||||
line((char const *)address, "\n");
|
||||
|
||||
size_t n = min(line.length(), count);
|
||||
memcpy(dst, line.string(), n);
|
||||
size_t n = min(line.length(), dst.num_bytes);
|
||||
memcpy(dst.start, line.string(), n);
|
||||
out_count = n;
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
@ -238,8 +232,7 @@ struct Lwip::Lwip_netmask_handle final : Lwip_handle
|
||||
, netif(netif)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
@ -250,8 +243,8 @@ struct Lwip::Lwip_netmask_handle final : Lwip_handle
|
||||
Genode::String<ADDRESS_FILE_SIZE>
|
||||
line((char const *)netmask, "\n");
|
||||
|
||||
size_t n = min(line.length(), count);
|
||||
memcpy(dst, line.string(), n);
|
||||
size_t n = min(line.length(), dst.num_bytes);
|
||||
memcpy(dst.start, line.string(), n);
|
||||
out_count = n;
|
||||
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();
|
||||
|
||||
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;
|
||||
|
||||
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 notify_read_ready();
|
||||
};
|
||||
@ -406,7 +397,7 @@ struct Lwip::Socket_dir : Lwip::Directory
|
||||
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");
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
@ -419,12 +410,12 @@ struct Lwip::Socket_dir : Lwip::Directory
|
||||
}
|
||||
|
||||
virtual Read_result read(Lwip_file_handle &,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
Byte_range_ptr const &dst,
|
||||
size_t &out_count) = 0;
|
||||
|
||||
virtual Write_result write(Lwip_file_handle &,
|
||||
char const *src, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
Const_byte_range_ptr const &src,
|
||||
size_t &out_count) = 0;
|
||||
|
||||
virtual bool read_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,
|
||||
int status_flags,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Lwip::Lwip_file_handle::~Lwip_file_handle()
|
||||
{
|
||||
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)
|
||||
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)
|
||||
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()
|
||||
{
|
||||
if (socket) {
|
||||
@ -644,7 +640,7 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
|
||||
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");
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
@ -891,9 +887,8 @@ class Lwip::Udp_socket_dir final :
|
||||
return true;
|
||||
}
|
||||
|
||||
Read_result read(Lwip_file_handle &handle,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result read(Lwip_file_handle &handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Read_result result = Read_result::READ_ERR_INVALID;
|
||||
|
||||
@ -902,7 +897,7 @@ class Lwip::Udp_socket_dir final :
|
||||
case Lwip_file_handle::DATA: {
|
||||
result = Read_result::READ_QUEUED;
|
||||
_packet_queue.head([&] (Packet &pkt) {
|
||||
out_count = pkt.read(dst, count);
|
||||
out_count = pkt.read(dst.start, dst.num_bytes);
|
||||
if (pkt.empty()) {
|
||||
_packet_queue.remove(pkt);
|
||||
destroy(_packet_slab, &pkt);
|
||||
@ -914,18 +909,18 @@ class Lwip::Udp_socket_dir final :
|
||||
|
||||
case Lwip_file_handle::PEEK:
|
||||
_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;
|
||||
});
|
||||
break;
|
||||
|
||||
case Lwip_file_handle::LOCAL:
|
||||
case Lwip_file_handle::BIND: {
|
||||
if (count < ENDPOINT_STRLEN_MAX)
|
||||
if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
char const *ip_str = ipaddr_ntoa(&_pcb->local_ip);
|
||||
/* 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);
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
@ -933,14 +928,14 @@ class Lwip::Udp_socket_dir final :
|
||||
case Lwip_file_handle::CONNECT: {
|
||||
/* check if the PCB was connected */
|
||||
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
|
||||
out_count = Genode::snprintf(dst, count, "not connected");
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "not connected");
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
|
||||
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");
|
||||
result = Read_result::READ_ERR_INVALID;
|
||||
} else
|
||||
@ -948,14 +943,14 @@ class Lwip::Udp_socket_dir final :
|
||||
_packet_queue.head([&] (Packet &pkt) {
|
||||
char const *ip_str = ipaddr_ntoa(&pkt.addr);
|
||||
/* 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);
|
||||
result = Read_result::READ_OK;
|
||||
});
|
||||
} else {
|
||||
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
|
||||
/* 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);
|
||||
result = Read_result::READ_OK;
|
||||
}
|
||||
@ -965,8 +960,8 @@ class Lwip::Udp_socket_dir final :
|
||||
/*
|
||||
* Print the location of this socket directory
|
||||
*/
|
||||
out_count = Genode::snprintf(
|
||||
dst, count, "udp/%s\n", name().string());
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "udp/%s\n",
|
||||
name().string());
|
||||
return Read_result::READ_OK;
|
||||
break;
|
||||
|
||||
@ -982,18 +977,20 @@ class Lwip::Udp_socket_dir final :
|
||||
}
|
||||
|
||||
Write_result write(Lwip_file_handle &handle,
|
||||
char const *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
switch (handle.kind) {
|
||||
|
||||
case Lwip_file_handle::DATA: {
|
||||
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) {
|
||||
pbuf *buf = pbuf_alloc(PBUF_RAW, remain, PBUF_RAM);
|
||||
pbuf_take(buf, src, buf->tot_len);
|
||||
pbuf * const buf = pbuf_alloc(PBUF_RAW, remain, PBUF_RAM);
|
||||
pbuf_take(buf, src_ptr, buf->tot_len);
|
||||
|
||||
err_t err = udp_sendto(_pcb, buf, &_to_addr, _to_port);
|
||||
pbuf_free(buf);
|
||||
@ -1002,9 +999,9 @@ class Lwip::Udp_socket_dir final :
|
||||
else if (err != ERR_OK)
|
||||
return Write_result::WRITE_ERR_IO;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1013,12 +1010,11 @@ class Lwip::Udp_socket_dir final :
|
||||
return Write_result::WRITE_ERR_INVALID;
|
||||
} else {
|
||||
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);
|
||||
out_count = count;
|
||||
if (ipaddr_aton(buf, &_to_addr)) {
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
}
|
||||
@ -1026,19 +1022,19 @@ class Lwip::Udp_socket_dir final :
|
||||
}
|
||||
|
||||
case Lwip_file_handle::BIND: {
|
||||
if (count < ENDPOINT_STRLEN_MAX) {
|
||||
if (src.num_bytes < ENDPOINT_STRLEN_MAX) {
|
||||
char buf[ENDPOINT_STRLEN_MAX];
|
||||
ip_addr_t addr;
|
||||
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);
|
||||
if (!ipaddr_aton(buf, &addr))
|
||||
break;
|
||||
|
||||
err_t err = udp_bind(_pcb, &addr, port);
|
||||
if (err == ERR_OK) {
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
return Write_result::WRITE_ERR_IO;
|
||||
@ -1047,10 +1043,10 @@ class Lwip::Udp_socket_dir final :
|
||||
}
|
||||
|
||||
case Lwip_file_handle::CONNECT: {
|
||||
if (count < ENDPOINT_STRLEN_MAX) {
|
||||
if (src.num_bytes < 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);
|
||||
if (!ipaddr_aton(buf, &_to_addr))
|
||||
@ -1062,7 +1058,7 @@ class Lwip::Udp_socket_dir final :
|
||||
return Write_result::WRITE_ERR_IO;
|
||||
}
|
||||
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
break;
|
||||
@ -1303,9 +1299,8 @@ class Lwip::Tcp_socket_dir final :
|
||||
return false;
|
||||
}
|
||||
|
||||
Read_result read(Lwip_file_handle &handle,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result read(Lwip_file_handle &handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
switch (handle.kind) {
|
||||
|
||||
@ -1328,8 +1323,8 @@ class Lwip::Tcp_socket_dir final :
|
||||
: Read_result::READ_OK;
|
||||
}
|
||||
|
||||
u16_t const ucount = min(count, (file_size)0xffff);
|
||||
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst, ucount, 0);
|
||||
u16_t const ucount = min(dst.num_bytes, (file_size)0xffff);
|
||||
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst.start, ucount, 0);
|
||||
|
||||
_recv_pbuf = pbuf_free_header(_recv_pbuf, n);
|
||||
|
||||
@ -1347,19 +1342,19 @@ class Lwip::Tcp_socket_dir final :
|
||||
|
||||
case Lwip_file_handle::PEEK:
|
||||
if (_recv_pbuf != nullptr) {
|
||||
u16_t const ucount = min(count, (file_size)0xffff);
|
||||
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst, ucount, 0);
|
||||
u16_t const ucount = min(dst.num_bytes, 0xffffUL);
|
||||
u16_t const n = pbuf_copy_partial(_recv_pbuf, dst.start, ucount, 0);
|
||||
out_count = n;
|
||||
}
|
||||
return Read_result::READ_OK;
|
||||
|
||||
case Lwip_file_handle::REMOTE:
|
||||
if (state == READY) {
|
||||
if (count < ENDPOINT_STRLEN_MAX)
|
||||
if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
char const *ip_str = ipaddr_ntoa(&_pcb->remote_ip);
|
||||
/* 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);
|
||||
return Read_result::READ_OK;
|
||||
} else {
|
||||
@ -1385,7 +1380,7 @@ class Lwip::Tcp_socket_dir final :
|
||||
|
||||
handle.kind = Lwip_file_handle::LOCATION;
|
||||
/* 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;
|
||||
}
|
||||
@ -1397,8 +1392,8 @@ class Lwip::Tcp_socket_dir final :
|
||||
/*
|
||||
* Print the location of this socket directory
|
||||
*/
|
||||
out_count = Genode::snprintf(
|
||||
dst, count, "tcp/%s\n", name().string());
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "tcp/%s\n",
|
||||
name().string());
|
||||
return Read_result::READ_OK;
|
||||
break;
|
||||
|
||||
@ -1410,20 +1405,19 @@ class Lwip::Tcp_socket_dir final :
|
||||
for (Pcb_pending *p = _pcb_pending.first(); p; p = p->next())
|
||||
++pending_count;
|
||||
|
||||
out_count = Genode::snprintf(
|
||||
dst, count, "%d\n", pending_count);
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "%d\n", pending_count);
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
|
||||
case Lwip_file_handle::LOCAL:
|
||||
case Lwip_file_handle::BIND:
|
||||
if (state != CLOSED) {
|
||||
if (count < ENDPOINT_STRLEN_MAX)
|
||||
if (dst.num_bytes < ENDPOINT_STRLEN_MAX)
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
char const *ip_str = ipaddr_ntoa(&_pcb->local_ip);
|
||||
/* TODO: [IPv6]:port */
|
||||
out_count = Genode::snprintf(
|
||||
dst, count, "%s:%d\n", ip_str, _pcb->local_port);
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes,
|
||||
"%s:%d\n", ip_str, _pcb->local_port);
|
||||
return Read_result::READ_OK;
|
||||
}
|
||||
break;
|
||||
@ -1431,10 +1425,10 @@ class Lwip::Tcp_socket_dir final :
|
||||
case Lwip_file_handle::CONNECT:
|
||||
switch (state) {
|
||||
case READY:
|
||||
out_count = Genode::snprintf(dst, count, "connected");
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "connected");
|
||||
break;
|
||||
default:
|
||||
out_count = Genode::snprintf(dst, count, "connection refused");
|
||||
out_count = Genode::snprintf(dst.start, dst.num_bytes, "connection refused");
|
||||
break;
|
||||
}
|
||||
return Read_result::READ_OK;
|
||||
@ -1469,9 +1463,8 @@ class Lwip::Tcp_socket_dir final :
|
||||
return false;
|
||||
}
|
||||
|
||||
Write_result write(Lwip_file_handle &handle,
|
||||
char const *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Lwip_file_handle &handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
if (_pcb == NULL) {
|
||||
/* socket is closed */
|
||||
@ -1482,7 +1475,10 @@ class Lwip::Tcp_socket_dir final :
|
||||
case Lwip_file_handle::DATA:
|
||||
if (state == READY) {
|
||||
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
|
||||
* and the availability of send buffer
|
||||
@ -1491,7 +1487,7 @@ class Lwip::Tcp_socket_dir final :
|
||||
u16_t n = min(count, tcp_sndbuf(_pcb));
|
||||
|
||||
/* 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) {
|
||||
Genode::error("lwIP: tcp_write failed, error ", (int)-err);
|
||||
res = Write_result::WRITE_ERR_IO;
|
||||
@ -1499,8 +1495,9 @@ class Lwip::Tcp_socket_dir final :
|
||||
}
|
||||
|
||||
count -= n;
|
||||
src += n;
|
||||
src_ptr += n;
|
||||
out += n;
|
||||
|
||||
/* pending_ack += n; */
|
||||
res = Write_result::WRITE_OK;
|
||||
}
|
||||
@ -1520,12 +1517,12 @@ class Lwip::Tcp_socket_dir final :
|
||||
break;
|
||||
|
||||
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];
|
||||
ip_addr_t addr;
|
||||
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);
|
||||
if (!ipaddr_aton(buf, &addr))
|
||||
@ -1534,19 +1531,19 @@ class Lwip::Tcp_socket_dir final :
|
||||
err_t err = tcp_bind(_pcb, &addr, port);
|
||||
if (err == ERR_OK) {
|
||||
state = BOUND;
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
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];
|
||||
ip_addr_t addr;
|
||||
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);
|
||||
if (!ipaddr_aton(buf, &addr))
|
||||
break;
|
||||
@ -1557,17 +1554,17 @@ class Lwip::Tcp_socket_dir final :
|
||||
return Write_result::WRITE_ERR_IO;
|
||||
}
|
||||
state = CONNECT;
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case Lwip_file_handle::LISTEN:
|
||||
if ((state == BOUND) && (count < 11)) {
|
||||
if ((state == BOUND) && (src.num_bytes < 11)) {
|
||||
unsigned long backlog = TCP_DEFAULT_LISTEN_BACKLOG;
|
||||
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);
|
||||
|
||||
/* this replaces the PCB so set the callbacks again */
|
||||
@ -1575,7 +1572,7 @@ class Lwip::Tcp_socket_dir final :
|
||||
tcp_arg(_pcb, this);
|
||||
tcp_accept(_pcb, tcp_accept_callback);
|
||||
state = LISTEN;
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
return Write_result::WRITE_OK;
|
||||
}
|
||||
break;
|
||||
@ -1849,7 +1846,7 @@ class Lwip::File_system final : public Vfs::File_system, public 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");
|
||||
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 **
|
||||
********************************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle,
|
||||
char const *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
/*
|
||||
* LwIP buffer operations are limited to sizes that
|
||||
* 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;
|
||||
|
||||
@ -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))
|
||||
return handle->read(dst, count, out_count);
|
||||
return handle->read(clipped_dst, out_count);
|
||||
return Read_result::READ_ERR_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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())
|
||||
return true;
|
||||
|
@ -450,7 +450,7 @@ struct Vfs::Oss_file_system::Audio
|
||||
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;
|
||||
|
||||
@ -461,7 +461,7 @@ struct Vfs::Oss_file_system::Audio
|
||||
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);
|
||||
|
||||
@ -497,7 +497,7 @@ struct Vfs::Oss_file_system::Audio
|
||||
|
||||
for (unsigned c = 0; c < CHANNELS; c++) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -517,7 +517,7 @@ struct Vfs::Oss_file_system::Audio
|
||||
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;
|
||||
|
||||
@ -528,6 +528,8 @@ struct Vfs::Oss_file_system::Audio
|
||||
|
||||
bool block_write = false;
|
||||
|
||||
size_t buf_size = src.num_bytes;
|
||||
|
||||
if (buf_size > _info.ofrag_bytes) {
|
||||
buf_size = _info.ofrag_bytes;
|
||||
block_write = true;
|
||||
@ -584,7 +586,7 @@ struct Vfs::Oss_file_system::Audio
|
||||
|
||||
for (unsigned c = 0; c < CHANNELS; c++) {
|
||||
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;
|
||||
out_size += sizeof(int16_t);
|
||||
}
|
||||
@ -648,17 +650,17 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
|
||||
_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;
|
||||
|
||||
if (buf_size == 0) {
|
||||
if (dst.num_bytes == 0) {
|
||||
out_count = 0;
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
bool success = _audio.read(buf, buf_size, out_count);
|
||||
bool success = _audio.read(dst, out_count);
|
||||
|
||||
if (success) {
|
||||
if (out_count == 0) {
|
||||
@ -670,10 +672,9 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
|
||||
return READ_ERR_INVALID;
|
||||
}
|
||||
|
||||
Write_result write(char const *buf, file_size buf_size,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src, size_t &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) {
|
||||
blocked = true;
|
||||
|
@ -197,13 +197,15 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
_io.commit_and_wait();
|
||||
|
||||
Vfs::File_io_service::Read_result read_result;
|
||||
Vfs::file_size out_count = 0;
|
||||
|
||||
size_t out_count = 0;
|
||||
|
||||
for (;;) {
|
||||
|
||||
read_result = _handle->fs().complete_read(_handle,
|
||||
(char*)&entry._dirent,
|
||||
sizeof(entry._dirent),
|
||||
Byte_range_ptr const dst { (char*)&entry._dirent,
|
||||
sizeof(entry._dirent) };
|
||||
|
||||
read_result = _handle->fs().complete_read(_handle, dst,
|
||||
out_count);
|
||||
|
||||
if (read_result != Vfs::File_io_service::READ_QUEUED)
|
||||
@ -297,8 +299,8 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
|
||||
char buf[MAX_PATH_LEN];
|
||||
|
||||
Vfs::file_size count = sizeof(buf)-1;
|
||||
Vfs::file_size out_count = 0;
|
||||
size_t count = sizeof(buf)-1;
|
||||
size_t out_count = 0;
|
||||
|
||||
while (!link_handle->fs().queue_read(link_handle, count)) {
|
||||
_io.commit_and_wait();
|
||||
@ -308,7 +310,7 @@ struct Genode::Directory : Noncopyable, Interface
|
||||
|
||||
for (;;) {
|
||||
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)
|
||||
break;
|
||||
@ -470,12 +472,14 @@ class Genode::Readonly_file : public File
|
||||
|
||||
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 (;;) {
|
||||
result = _handle->fs().complete_read(_handle,
|
||||
range.start + total,
|
||||
range.num_bytes - total,
|
||||
|
||||
Byte_range_ptr const partial_range { range.start + total,
|
||||
range.num_bytes - total };
|
||||
|
||||
result = _handle->fs().complete_read(_handle, partial_range,
|
||||
read_bytes);
|
||||
|
||||
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,
|
||||
char const *src, size_t size)
|
||||
Const_byte_range_ptr const &src)
|
||||
{
|
||||
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) {
|
||||
|
||||
bool stalled = false;
|
||||
|
||||
Vfs::file_size out_count = 0;
|
||||
size_t out_count = 0;
|
||||
|
||||
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:
|
||||
stalled = true;
|
||||
@ -785,9 +793,9 @@ class Genode::Writeable_file : Noncopyable
|
||||
break;
|
||||
|
||||
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;
|
||||
src += out_count;
|
||||
src_ptr += out_count;
|
||||
handle.advance_seek(out_count);
|
||||
break;
|
||||
};
|
||||
@ -834,8 +842,11 @@ class Genode::Append_file : public Writeable_file
|
||||
_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) {
|
||||
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);
|
||||
}
|
||||
|
||||
Append_result append(Const_byte_range_ptr const &src) {
|
||||
return _append(_handle, _io, src); }
|
||||
|
||||
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)); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,28 +42,34 @@ class File_system::Chunk_base : Noncopyable
|
||||
|
||||
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:
|
||||
|
||||
seek_off_t const _base_offset;
|
||||
size_t _num_entries; /* corresponds to last used entry */
|
||||
Seek const _base_offset { ~0UL };
|
||||
|
||||
size_t _num_entries = 0; /* corresponds to last used entry */
|
||||
|
||||
/**
|
||||
* Test if specified range lies within the chunk
|
||||
*/
|
||||
void assert_valid_range(seek_off_t start, size_t len,
|
||||
file_size_t chunk_size) const
|
||||
void assert_valid_range(Seek start, size_t len,
|
||||
size_t chunk_size) const
|
||||
{
|
||||
if (zero()) return;
|
||||
|
||||
if (start < _base_offset)
|
||||
if (start.value < _base_offset.value)
|
||||
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();
|
||||
}
|
||||
|
||||
Chunk_base(seek_off_t base_offset)
|
||||
: _base_offset(base_offset), _num_entries(0) { }
|
||||
Chunk_base(Seek base_offset) : _base_offset(base_offset) { }
|
||||
|
||||
/**
|
||||
* 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
|
||||
* base offset of ~0 as marker to identify zero chunks.
|
||||
*/
|
||||
Chunk_base() : _base_offset(~0L), _num_entries(0) { }
|
||||
Chunk_base() { }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
@ -117,7 +123,7 @@ class File_system::Chunk : public Chunk_base
|
||||
* signature of the constructor compatible to the constructor
|
||||
* of 'Chunk_index'.
|
||||
*/
|
||||
Chunk(Allocator &, seek_off_t base_offset)
|
||||
Chunk(Allocator &, Seek 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
|
||||
* 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 */
|
||||
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
|
||||
* 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)
|
||||
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])
|
||||
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);
|
||||
|
||||
@ -255,17 +261,17 @@ class File_system::Chunk_index : public Chunk_base
|
||||
* The caller of this function must make sure that the offset
|
||||
* 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
|
||||
*/
|
||||
template <typename THIS, typename DATA, typename FUNC>
|
||||
static void _range_op(THIS &obj, DATA *data, size_t len,
|
||||
seek_off_t seek_offset, FUNC const &func)
|
||||
template <typename THIS, typename RANGE_PTR, typename FUNC>
|
||||
static void _range_op(THIS &obj, RANGE_PTR const &range_ptr,
|
||||
Seek at, FUNC const &func)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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) {
|
||||
|
||||
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);
|
||||
|
||||
@ -291,20 +300,20 @@ class File_system::Chunk_index : public Chunk_base
|
||||
* zero chunk, which has no defined base offset. Therefore,
|
||||
* we calculate the base offset via index*ENTRY_SIZE.
|
||||
*/
|
||||
seek_off_t const local_seek_offset =
|
||||
seek_offset - obj.base_offset() - index*ENTRY_SIZE;
|
||||
size_t const local_seek_offset =
|
||||
at.value - obj.base_offset().value - index*ENTRY_SIZE;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 */
|
||||
len -= curr_len;
|
||||
data += curr_len;
|
||||
seek_offset += curr_len;
|
||||
data_ptr += 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) {
|
||||
return chunk._entry_for_writing(i); }
|
||||
|
||||
void operator () (Entry &entry, char const *src, size_t len,
|
||||
seek_off_t seek_offset) const
|
||||
void operator () (Entry &entry, Const_byte_range_ptr const &src, Seek at) 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) {
|
||||
return chunk._entry_for_reading(i); }
|
||||
|
||||
void operator () (Entry &entry, char *dst, size_t len,
|
||||
seek_off_t seek_offset) const
|
||||
void operator () (Entry &entry, Byte_range_ptr const &dst, Seek at) const
|
||||
{
|
||||
if (entry.zero())
|
||||
memset(dst, 0, len);
|
||||
memset(dst.start, 0, dst.num_bytes);
|
||||
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
|
||||
* \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(); }
|
||||
|
||||
/**
|
||||
@ -385,13 +392,13 @@ class File_system::Chunk_index : public Chunk_base
|
||||
* The returned value corresponds to the position after the highest
|
||||
* offset that was written to.
|
||||
*/
|
||||
file_size_t used_size() const
|
||||
size_t used_size() const
|
||||
{
|
||||
if (_num_entries == 0)
|
||||
return 0;
|
||||
|
||||
/* 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];
|
||||
if (!last_entry)
|
||||
@ -403,17 +410,17 @@ class File_system::Chunk_index : public Chunk_base
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* 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)
|
||||
return;
|
||||
@ -436,7 +443,7 @@ class File_system::Chunk_index : public Chunk_base
|
||||
|
||||
/* traverse into sub chunks */
|
||||
if (_entries[trunc_index])
|
||||
_entries[trunc_index]->truncate(size);
|
||||
_entries[trunc_index]->truncate(at);
|
||||
|
||||
_num_entries = trunc_index + 1;
|
||||
|
||||
|
@ -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,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count)
|
||||
Byte_range_ptr const &dst,
|
||||
size_t &out_count)
|
||||
{
|
||||
if (!dir_vfs_handle->queued_read_handle) {
|
||||
|
||||
@ -340,10 +340,10 @@ class Vfs::Dir_file_system : public File_system
|
||||
* fs->opendir() failed
|
||||
*/
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
Dirent &dirent = *(Dirent*)dst;
|
||||
Dirent &dirent = *(Dirent*)dst.start;
|
||||
dirent = 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().
|
||||
complete_read(dir_vfs_handle->queued_read_handle,
|
||||
dst, count, out_count);
|
||||
dst, out_count);
|
||||
|
||||
if (result == READ_QUEUED)
|
||||
return result;
|
||||
@ -893,12 +893,12 @@ class Vfs::Dir_file_system : public File_system
|
||||
** 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;
|
||||
}
|
||||
|
||||
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 =
|
||||
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,
|
||||
char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
Dir_vfs_handle *dir_vfs_handle =
|
||||
static_cast<Dir_vfs_handle*>(vfs_handle);
|
||||
|
||||
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())) {
|
||||
|
||||
Dirent &dirent = *(Dirent*)dst;
|
||||
Dirent &dirent = *(Dirent*)dst.start;
|
||||
|
||||
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 _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
|
||||
|
@ -30,9 +30,8 @@ struct Vfs::File_io_service : Interface
|
||||
enum Write_result { WRITE_ERR_WOULD_BLOCK, WRITE_ERR_INVALID,
|
||||
WRITE_ERR_IO, WRITE_OK };
|
||||
|
||||
virtual Write_result write(Vfs_handle *vfs_handle,
|
||||
char const *buf, file_size buf_size,
|
||||
file_size &out_count) = 0;
|
||||
virtual Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &,
|
||||
size_t &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
|
||||
* request is completed.
|
||||
*/
|
||||
virtual bool queue_read(Vfs_handle *, file_size)
|
||||
virtual bool queue_read(Vfs_handle *, size_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Read_result complete_read(Vfs_handle *, char * /* dst */,
|
||||
file_size /* in count */,
|
||||
file_size & /* out count */) = 0;
|
||||
virtual Read_result complete_read(Vfs_handle *, Byte_range_ptr const &dst,
|
||||
size_t &out_count) = 0;
|
||||
|
||||
/**
|
||||
* Return true if the handle has readable data
|
||||
|
@ -51,8 +51,7 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system
|
||||
Single_vfs_handle(ds, fs, alloc, 0), _buffer(buffer)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
@ -60,14 +59,14 @@ class Vfs::Readonly_value_file_system : public Vfs::Single_file_system
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
char const * const src = _buffer.string() + seek();
|
||||
size_t const len = min((size_t)(_buffer.length() - seek()), (size_t)count);
|
||||
Genode::memcpy(dst, src, len);
|
||||
size_t const len = min(size_t(_buffer.length() - seek()), dst.num_bytes);
|
||||
Genode::memcpy(dst.start, src, len);
|
||||
|
||||
out_count = len;
|
||||
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;
|
||||
}
|
||||
|
@ -37,11 +37,9 @@ class Vfs::Single_file_system : public File_system
|
||||
{
|
||||
using Vfs_handle::Vfs_handle;
|
||||
|
||||
virtual Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &, size_t &out_count) = 0;
|
||||
|
||||
virtual Write_result write(char const *src, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Write_result write(Const_byte_range_ptr const &, size_t &out_count) = 0;
|
||||
|
||||
virtual Sync_result sync()
|
||||
{
|
||||
@ -83,17 +81,16 @@ class Vfs::Single_file_system : public File_system
|
||||
_type(type), _rwx(rwx), _filename(filename)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
file_size index = seek() / sizeof(Dirent);
|
||||
|
||||
Dirent &out = *(Dirent*)dst;
|
||||
Dirent &out = *(Dirent*)dst.start;
|
||||
|
||||
auto dirent_type = [&] ()
|
||||
{
|
||||
@ -127,7 +124,7 @@ class Vfs::Single_file_system : public File_system
|
||||
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;
|
||||
}
|
||||
@ -255,27 +252,26 @@ class Vfs::Single_file_system : public File_system
|
||||
** File I/O service interface **
|
||||
********************************/
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, char *dst,
|
||||
file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Single_vfs_handle *handle =
|
||||
static_cast<Single_vfs_handle*>(vfs_handle);
|
||||
|
||||
if (handle)
|
||||
return handle->read(dst, count, out_count);
|
||||
return handle->read(dst, out_count);
|
||||
|
||||
return READ_ERR_INVALID;
|
||||
}
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle, char const *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
Single_vfs_handle *handle =
|
||||
static_cast<Single_vfs_handle*>(vfs_handle);
|
||||
|
||||
if (handle)
|
||||
return handle->write(src, count, out_count);
|
||||
return handle->write(src, out_count);
|
||||
|
||||
return WRITE_ERR_INVALID;
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ namespace Vfs {
|
||||
using Genode::Interface;
|
||||
using Genode::String;
|
||||
using Genode::size_t;
|
||||
using Genode::Byte_range_ptr;
|
||||
using Genode::Const_byte_range_ptr;
|
||||
|
||||
struct Timestamp
|
||||
{
|
||||
|
@ -52,8 +52,7 @@ class Vfs::Value_file_system : public Vfs::Single_file_system
|
||||
_value_fs(value_fs)
|
||||
{ }
|
||||
|
||||
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 = 0;
|
||||
|
||||
@ -61,21 +60,23 @@ class Vfs::Value_file_system : public Vfs::Single_file_system
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
char const * const src = _buffer.string() + seek();
|
||||
Genode::size_t const len = min((size_t)(_buffer.length() - seek()), (size_t)count);
|
||||
Genode::memcpy(dst, src, len);
|
||||
size_t const len = min((size_t)(_buffer.length() - seek()), dst.num_bytes);
|
||||
|
||||
memcpy(dst.start, src, len);
|
||||
|
||||
out_count = len;
|
||||
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;
|
||||
if (seek() > BUF_SIZE)
|
||||
return WRITE_ERR_INVALID;
|
||||
|
||||
Genode::size_t const len = min((size_t)(BUF_SIZE- seek()), (size_t)count);
|
||||
_buffer = Buffer(Genode::Cstring(src, len));
|
||||
size_t const len = min(size_t(BUF_SIZE- seek()), src.num_bytes);
|
||||
|
||||
_buffer = Buffer(Genode::Cstring(src.start, len));
|
||||
out_count = len;
|
||||
|
||||
/* inform watchers */
|
||||
|
@ -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 &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)
|
||||
{
|
||||
Block::Packet_descriptor::Opcode op;
|
||||
@ -164,22 +164,23 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
||||
_writeable(writeable)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
file_size seek_offset = seek();
|
||||
|
||||
file_size read = 0;
|
||||
size_t count = dst.num_bytes;
|
||||
size_t read = 0;
|
||||
|
||||
while (count > 0) {
|
||||
file_size displ = 0;
|
||||
file_size length = 0;
|
||||
file_size nbytes = 0;
|
||||
file_size blk_nr = seek_offset / _block_size;
|
||||
|
||||
size_t length = 0;
|
||||
|
||||
displ = seek_offset % _block_size;
|
||||
|
||||
if ((displ + count) > _block_size)
|
||||
length = (_block_size - displ);
|
||||
length = size_t(_block_size - displ);
|
||||
else
|
||||
length = count;
|
||||
|
||||
@ -195,7 +196,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
||||
if (displ == 0 && !(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) {
|
||||
Genode::error("error while reading block:", blk_nr, " from block device");
|
||||
return READ_ERR_INVALID;
|
||||
@ -208,13 +209,13 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
||||
continue;
|
||||
}
|
||||
|
||||
nbytes = _block_io(blk_nr, _block_buffer, _block_size, false);
|
||||
if ((unsigned)nbytes != _block_size) {
|
||||
size_t const nbytes = _block_io(blk_nr, _block_buffer, _block_size, false);
|
||||
if (nbytes != _block_size) {
|
||||
Genode::error("error while reading block:", blk_nr, " from block device");
|
||||
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;
|
||||
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,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
|
||||
{
|
||||
if (!_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 written = 0;
|
||||
size_t written = 0;
|
||||
size_t count = src.num_bytes;
|
||||
|
||||
while (count > 0) {
|
||||
file_size displ = 0;
|
||||
file_size length = 0;
|
||||
file_size nbytes = 0;
|
||||
file_size blk_nr = seek_offset / _block_size;
|
||||
|
||||
size_t length = 0;
|
||||
|
||||
displ = seek_offset % _block_size;
|
||||
|
||||
if ((displ + count) > _block_size)
|
||||
length = (_block_size - displ);
|
||||
length = size_t(_block_size - displ);
|
||||
else
|
||||
length = count;
|
||||
|
||||
@ -263,7 +265,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
||||
if (displ == 0 && !(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);
|
||||
if (nbytes == 0) {
|
||||
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)
|
||||
_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);
|
||||
if ((unsigned)nbytes != _block_size) {
|
||||
size_t const nbytes = _block_io(blk_nr, _block_buffer, _block_size, true);
|
||||
if (nbytes != _block_size) {
|
||||
Genode::error("error while writing block:", blk_nr, " to block_device");
|
||||
return WRITE_ERR_INVALID;
|
||||
}
|
||||
|
@ -70,19 +70,20 @@ class Vfs_capture::Data_file_system : public Single_file_system
|
||||
bool read_ready() const override { return true; }
|
||||
bool write_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
|
||||
{
|
||||
_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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
|
||||
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)
|
||||
return false;
|
||||
@ -160,8 +160,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
if (!source.ready_to_submit())
|
||||
return false;
|
||||
|
||||
file_size const max_packet_size = source.bulk_buffer_size() / 2;
|
||||
file_size const clipped_count = min(max_packet_size, count);
|
||||
size_t const max_packet_size = source.bulk_buffer_size() / 2;
|
||||
size_t const clipped_count = min(max_packet_size, count);
|
||||
|
||||
::File_system::Packet_descriptor p;
|
||||
try {
|
||||
@ -184,8 +184,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
return true;
|
||||
}
|
||||
|
||||
Read_result _complete_read(void *dst, file_size count,
|
||||
file_size &out_count)
|
||||
Read_result _complete_read(Byte_range_ptr const &dst, size_t &out_count)
|
||||
{
|
||||
if (queued_read_state != Handle_state::Queued_state::ACK)
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -227,15 +226,14 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
::File_system::File_handle file_handle() const
|
||||
{ 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");
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Read_result complete_read(char *,
|
||||
file_size /* in count */,
|
||||
file_size & /* out count */)
|
||||
virtual Read_result complete_read(Byte_range_ptr const &,
|
||||
size_t & /* out count */)
|
||||
{
|
||||
Genode::error("Fs_vfs_handle::complete_read() called");
|
||||
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;
|
||||
|
||||
bool queue_read(file_size count) override
|
||||
bool queue_read(size_t count) override
|
||||
{
|
||||
return _queue_read(count, seek());
|
||||
}
|
||||
|
||||
Read_result complete_read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Byte_range_ptr const &dst, size_t &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;
|
||||
|
||||
bool queue_read(file_size count) override
|
||||
bool queue_read(size_t count) override
|
||||
{
|
||||
if (count < sizeof(Dirent))
|
||||
return true;
|
||||
@ -347,26 +344,27 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
(seek() / sizeof(Dirent) * DIRENT_SIZE));
|
||||
}
|
||||
|
||||
Read_result complete_read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Byte_range_ptr const &dst, size_t &out_count) override
|
||||
{
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
using ::File_system::Directory_entry;
|
||||
|
||||
Directory_entry entry { };
|
||||
file_size entry_out_count = 0;
|
||||
|
||||
size_t entry_out_count = 0;
|
||||
|
||||
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)
|
||||
return read_result;
|
||||
|
||||
entry.sanitize();
|
||||
|
||||
Dirent &dirent = *(Dirent*)dst;
|
||||
Dirent &dirent = *(Dirent*)dst.start;
|
||||
|
||||
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;
|
||||
|
||||
bool queue_read(file_size count) override
|
||||
bool queue_read(size_t count) override
|
||||
{
|
||||
return _queue_read(count, seek());
|
||||
}
|
||||
|
||||
Read_result complete_read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Byte_range_ptr const &dst,
|
||||
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,
|
||||
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 */
|
||||
_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();
|
||||
using ::File_system::Packet_descriptor;
|
||||
|
||||
file_size const max_packet_size = source.bulk_buffer_size() / 2;
|
||||
count = min(max_packet_size, count);
|
||||
size_t const max_packet_size = source.bulk_buffer_size() / 2;
|
||||
size_t const count = min(max_packet_size, src.num_bytes);
|
||||
|
||||
if (!source.ready_to_submit()) {
|
||||
_write_would_block = true;
|
||||
@ -466,13 +464,13 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
}
|
||||
|
||||
try {
|
||||
Packet_descriptor packet_in(source.alloc_packet((size_t)count),
|
||||
Packet_descriptor packet_in(source.alloc_packet(count),
|
||||
handle.file_handle(),
|
||||
Packet_descriptor::WRITE,
|
||||
(size_t)count,
|
||||
count,
|
||||
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);
|
||||
}
|
||||
@ -889,29 +887,29 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
||||
** File I/O service interface **
|
||||
********************************/
|
||||
|
||||
Write_result write(Vfs_handle *vfs_handle, char const *buf,
|
||||
file_size count, file_size &out_count) override
|
||||
Write_result write(Vfs_handle *vfs_handle, Const_byte_range_ptr const &src,
|
||||
size_t &out_count) override
|
||||
{
|
||||
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);
|
||||
|
||||
return handle->queue_read(count);
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
|
||||
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
|
||||
|
@ -28,62 +28,26 @@ class Vfs::Inline_file_system : public Single_file_system
|
||||
|
||||
Xml_node _node;
|
||||
|
||||
class Inline_vfs_handle : public Single_vfs_handle
|
||||
class Handle : public Single_vfs_handle
|
||||
{
|
||||
private:
|
||||
|
||||
char const * const _base;
|
||||
file_size const _size;
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Inline_vfs_handle(Inline_vfs_handle const &);
|
||||
Inline_vfs_handle &operator = (Inline_vfs_handle const &);
|
||||
Inline_file_system const &_fs;
|
||||
|
||||
public:
|
||||
|
||||
Inline_vfs_handle(Directory_service &ds,
|
||||
Handle(Directory_service &ds,
|
||||
File_io_service &fs,
|
||||
Genode::Allocator &alloc,
|
||||
char const * const base,
|
||||
file_size const size)
|
||||
: Single_vfs_handle(ds, fs, alloc, 0),
|
||||
_base(base), _size(size)
|
||||
Allocator &alloc,
|
||||
Inline_file_system const &inline_fs)
|
||||
:
|
||||
Single_vfs_handle(ds, fs, alloc, 0), _fs(inline_fs)
|
||||
{ }
|
||||
|
||||
Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
{
|
||||
/* file read limit is the size of the dataspace */
|
||||
file_size const max_size = _size;
|
||||
inline Read_result read(Byte_range_ptr const &, size_t &) override;
|
||||
|
||||
/* current read offset */
|
||||
file_size const read_offset = seek();
|
||||
|
||||
/* 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
|
||||
Write_result write(Const_byte_range_ptr const &,
|
||||
size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
return WRITE_ERR_INVALID;
|
||||
@ -123,22 +87,13 @@ class Vfs::Inline_file_system : public Single_file_system
|
||||
if (!_single_file(path))
|
||||
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 {
|
||||
_node.with_raw_content([&] (char const *base, size_t size) {
|
||||
*out_handle = new (alloc)
|
||||
Inline_vfs_handle(*this, *this, alloc, base, size);
|
||||
});
|
||||
return OPEN_OK;
|
||||
*out_handle = new (alloc) Handle(*this, *this, alloc, *this);
|
||||
}
|
||||
catch (Genode::Out_of_ram) { return OPEN_ERR_OUT_OF_RAM; }
|
||||
catch (Genode::Out_of_caps) { return OPEN_ERR_OUT_OF_CAPS; }
|
||||
|
||||
return OPEN_OK;
|
||||
}
|
||||
|
||||
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_ */
|
||||
|
@ -52,7 +52,7 @@ class Vfs::Log_file_system : public Single_file_system
|
||||
|
||||
char _line_buf[Genode::Log_session::MAX_STRING_LEN];
|
||||
|
||||
file_offset _line_pos = 0;
|
||||
size_t _line_pos = 0;
|
||||
|
||||
Genode::Log_session &_log;
|
||||
|
||||
@ -83,37 +83,40 @@ class Vfs::Log_file_system : public Single_file_system
|
||||
File_io_service &fs,
|
||||
Genode::Allocator &alloc,
|
||||
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()
|
||||
{
|
||||
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 */
|
||||
return READ_QUEUED;
|
||||
}
|
||||
|
||||
Write_result write(char const *src, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &buf, size_t &out_count) override
|
||||
{
|
||||
size_t count = buf.num_bytes;
|
||||
char const * src = buf.start;
|
||||
|
||||
out_count = count;
|
||||
|
||||
/* count does not include the trailing '\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') {
|
||||
curr_count = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(_line_buf + _line_pos, src, (size_t)curr_count);
|
||||
memcpy(_line_buf + _line_pos, src, curr_count);
|
||||
_line_pos += curr_count;
|
||||
|
||||
if ((_line_pos == sizeof(_line_buf) - 1) ||
|
||||
|
@ -36,19 +36,20 @@ struct Vfs::Null_file_system : Single_file_system
|
||||
Null_vfs_handle(Directory_service &ds,
|
||||
File_io_service &fs,
|
||||
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;
|
||||
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
|
||||
{
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ namespace Vfs_ram {
|
||||
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; }
|
||||
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(Watch_handle &handle) { _watch_handles.insert(&handle); }
|
||||
@ -172,28 +173,27 @@ class Vfs_ram::Node : private Genode::Avl_node<Node>
|
||||
.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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual Vfs::File_io_service::Read_result complete_read(char *,
|
||||
file_size,
|
||||
file_size,
|
||||
file_size &)
|
||||
virtual Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &,
|
||||
Seek,
|
||||
size_t & /* out count */)
|
||||
{
|
||||
Genode::error("Vfs_ram::Node::complete_read() called");
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void truncate(file_size)
|
||||
virtual void truncate(Seek)
|
||||
{
|
||||
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,
|
||||
* not the most efficient way to do this.
|
||||
*/
|
||||
Node *index(file_offset &i)
|
||||
Node *index(size_t &i)
|
||||
{
|
||||
if (i-- == 0)
|
||||
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;
|
||||
|
||||
Chunk_level_0 _chunk;
|
||||
file_size _length = 0;
|
||||
|
||||
size_t _length = 0;
|
||||
|
||||
public:
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -270,45 +271,46 @@ class Vfs_ram::File : public Vfs_ram::Node
|
||||
* Note that 'chunk_used_size' may be lower than '_length'
|
||||
* 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) {
|
||||
if (chunk_used_size >= seek_offset)
|
||||
read_len = chunk_used_size - seek_offset;
|
||||
size_t read_len = len;
|
||||
|
||||
if (seek.value + read_len > chunk_used_size) {
|
||||
if (chunk_used_size >= seek.value)
|
||||
read_len = chunk_used_size - seek.value;
|
||||
else
|
||||
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 */
|
||||
if (read_len < len)
|
||||
memset(dst + read_len, 0, (size_t)(len - read_len));
|
||||
if (read_len < dst.num_bytes)
|
||||
memset(dst.start + read_len, 0, len - read_len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
Vfs::File_io_service::Read_result complete_read(char *dst,
|
||||
file_size count,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &dst,
|
||||
Seek seek, size_t &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;
|
||||
}
|
||||
|
||||
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))
|
||||
seek_offset = _chunk.used_size();
|
||||
size_t const at = (seek.value == ~0UL) ? _chunk.used_size() : seek.value;
|
||||
|
||||
if (seek_offset + len >= Chunk_level_0::SIZE)
|
||||
len = Chunk_level_0::SIZE - (size_t)(seek_offset + len);
|
||||
size_t len = src.num_bytes;
|
||||
|
||||
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; }
|
||||
|
||||
/*
|
||||
@ -316,19 +318,19 @@ class Vfs_ram::File : public Vfs_ram::Node
|
||||
* as file length because trailing zeros may by represented
|
||||
* by zero chunks, which do not contribute to 'used_size()'.
|
||||
*/
|
||||
_length = max(_length, seek_offset + len);
|
||||
_length = max(_length, at + 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);
|
||||
|
||||
_length = size;
|
||||
_length = size.value;
|
||||
}
|
||||
};
|
||||
|
||||
@ -344,43 +346,34 @@ class Vfs_ram::Symlink : public Vfs_ram::Node
|
||||
|
||||
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) {
|
||||
if (target[i] == '\0') {
|
||||
len = i;
|
||||
if (src.start[i] == '\0') {
|
||||
len = i + 1; /* number of characters + terminating zero */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_len = len;
|
||||
memcpy(_target, target, _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);
|
||||
memcpy(_target, src.start, _len);
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -392,7 +385,8 @@ class Vfs_ram::Directory : public Vfs_ram::Node
|
||||
private:
|
||||
|
||||
Avl_tree<Node> _entries { };
|
||||
file_size _count = 0;
|
||||
|
||||
size_t _count = 0;
|
||||
|
||||
public:
|
||||
|
||||
@ -430,21 +424,20 @@ class Vfs_ram::Directory : public Vfs_ram::Node
|
||||
--_count;
|
||||
}
|
||||
|
||||
file_size length() override { return _count; }
|
||||
size_t length() override { return _count; }
|
||||
|
||||
Vfs::File_io_service::Read_result complete_read(char *dst,
|
||||
file_size count,
|
||||
file_size seek_offset,
|
||||
file_size &out_count) override
|
||||
Vfs::File_io_service::Read_result complete_read(Byte_range_ptr const &dst,
|
||||
Seek const seek,
|
||||
size_t &out_count) override
|
||||
{
|
||||
typedef Vfs::Directory_service::Dirent Dirent;
|
||||
|
||||
if (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
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;
|
||||
|
||||
@ -883,14 +876,14 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if (!file)
|
||||
return ds_cap;
|
||||
|
||||
size_t len = (size_t)file->length();
|
||||
size_t len = file->length();
|
||||
|
||||
char *local_addr = nullptr;
|
||||
try {
|
||||
ds_cap = _env.env().ram().alloc(len);
|
||||
|
||||
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);
|
||||
|
||||
} catch(...) {
|
||||
@ -940,30 +933,34 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
************************/
|
||||
|
||||
Write_result write(Vfs_handle * const vfs_handle,
|
||||
char const * const buf, file_size len,
|
||||
Vfs::file_size &out) override
|
||||
Const_byte_range_ptr const &buf,
|
||||
size_t &out) override
|
||||
{
|
||||
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
||||
return WRITE_ERR_INVALID;
|
||||
|
||||
Vfs_ram::Io_handle * const handle =
|
||||
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
Vfs_ram::Io_handle &handle =
|
||||
*static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
|
||||
out = handle->node.write(buf, (size_t)len, handle->seek());
|
||||
handle->modifying = true;
|
||||
Vfs_ram::Seek const seek { size_t(handle.seek()) };
|
||||
|
||||
out = handle.node.write(buf, seek);
|
||||
handle.modifying = true;
|
||||
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle * const vfs_handle, char *dst,
|
||||
file_size count, file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle * const vfs_handle,
|
||||
Byte_range_ptr const &dst, size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
|
||||
Vfs_ram::Io_handle const * const handle =
|
||||
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
Vfs_ram::Io_handle const &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; }
|
||||
@ -974,10 +971,12 @@ class Vfs::Ram_file_system : public Vfs::File_system
|
||||
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
||||
return FTRUNCATE_ERR_NO_PERM;
|
||||
|
||||
Vfs_ram::Io_handle const * const handle =
|
||||
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
Vfs_ram::Io_handle const &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; }
|
||||
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
|
||||
{
|
||||
Vfs_ram::Io_handle * const handle =
|
||||
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
if (handle->modifying) {
|
||||
handle->modifying = false;
|
||||
handle->node.close(*handle);
|
||||
handle->node.notify();
|
||||
handle->node.open(*handle);
|
||||
Vfs_ram::Io_handle &handle =
|
||||
*static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
|
||||
if (handle.modifying) {
|
||||
handle.modifying = false;
|
||||
handle.node.close(handle);
|
||||
handle.node.notify();
|
||||
handle.node.open(handle);
|
||||
}
|
||||
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)
|
||||
return false;
|
||||
|
||||
Vfs_ram::Io_handle * const handle =
|
||||
static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
handle->modifying = true;
|
||||
Vfs_ram::Io_handle &handle =
|
||||
*static_cast<Vfs_ram::Io_handle *>(vfs_handle);
|
||||
|
||||
return handle->node.update_modification_timestamp(time);
|
||||
handle.modifying = true;
|
||||
|
||||
return handle.node.update_modification_timestamp(time);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,17 +39,17 @@ class Vfs::Rom_file_system : public Single_file_system
|
||||
|
||||
Genode::Attached_rom_dataspace _rom { _env, _label.string() };
|
||||
|
||||
file_size _init_content_size()
|
||||
size_t _init_content_size()
|
||||
{
|
||||
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)
|
||||
return pos;
|
||||
|
||||
return _rom.size();
|
||||
}
|
||||
|
||||
file_size _content_size = _init_content_size();
|
||||
size_t _content_size = _init_content_size();
|
||||
|
||||
void _update()
|
||||
{
|
||||
@ -63,7 +63,7 @@ class Vfs::Rom_file_system : public Single_file_system
|
||||
|
||||
Genode::Attached_rom_dataspace &_rom;
|
||||
|
||||
file_size const &_content_size;
|
||||
size_t const &_content_size;
|
||||
|
||||
public:
|
||||
|
||||
@ -71,23 +71,22 @@ class Vfs::Rom_file_system : public Single_file_system
|
||||
File_io_service &fs,
|
||||
Genode::Allocator &alloc,
|
||||
Genode::Attached_rom_dataspace &rom,
|
||||
file_size const &content_size)
|
||||
size_t const &content_size)
|
||||
:
|
||||
Single_vfs_handle(ds, fs, alloc, 0),
|
||||
_rom(rom), _content_size(content_size)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
/* 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 */
|
||||
file_size const read_offset = seek();
|
||||
size_t const read_offset = size_t(seek());
|
||||
|
||||
/* 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 */
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *, file_size,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &, size_t &out_count) override
|
||||
{
|
||||
out_count = 0;
|
||||
return WRITE_ERR_INVALID;
|
||||
|
@ -51,8 +51,7 @@ class Vfs::Rtc_file_system : public Single_file_system
|
||||
* On each read the current time is queried and afterwards formated
|
||||
* as '%Y-%m-%d %H:%M:%S\n' resp. '%F %T\n'.
|
||||
*/
|
||||
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 (seek() >= TIMESTAMP_LEN) {
|
||||
out_count = 0;
|
||||
@ -63,20 +62,20 @@ class Vfs::Rtc_file_system : public Single_file_system
|
||||
|
||||
char buf[TIMESTAMP_LEN+1];
|
||||
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);
|
||||
n -= (size_t)seek();
|
||||
n -= size_t(seek());
|
||||
b += seek();
|
||||
|
||||
file_size len = count > n ? n : count;
|
||||
Genode::memcpy(dst, b, (size_t)len);
|
||||
size_t const len = min(n, dst.num_bytes);
|
||||
memcpy(dst.start, b, len);
|
||||
out_count = len;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -39,18 +39,15 @@ class Vfs::Symlink_file_system : public Single_file_system
|
||||
: Single_vfs_handle(ds, fs, alloc, 0), _target(target)
|
||||
{ }
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
auto n = min(count, _target.length());
|
||||
copy_cstring(dst, _target.string(), (size_t)n);
|
||||
out_count = n - 1;
|
||||
size_t const n = min(dst.num_bytes, _target.length());
|
||||
copy_cstring(dst.start, _target.string(), n);
|
||||
out_count = (n > 0) ? n - 1 : 0;
|
||||
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; }
|
||||
|
||||
bool read_ready() const override { return true; }
|
||||
|
@ -148,8 +148,7 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
|
||||
return _link_state;
|
||||
}
|
||||
|
||||
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 (!read_ready()) {
|
||||
_blocked = true;
|
||||
@ -167,8 +166,8 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
|
||||
const char *const rx_pkt_base {
|
||||
_nic.rx()->packet_content(rx_pkt) };
|
||||
|
||||
out_count = static_cast<file_size>(min(rx_pkt.size(), static_cast<size_t>(count)));
|
||||
memcpy(dst, rx_pkt_base, static_cast<size_t>(out_count));
|
||||
out_count = min(rx_pkt.size(), dst.num_bytes);
|
||||
memcpy(dst.start, rx_pkt_base, out_count);
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -187,18 +185,16 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
|
||||
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||
}
|
||||
try {
|
||||
size_t tx_pkt_size { static_cast<size_t>(count) };
|
||||
|
||||
Packet_descriptor tx_pkt {
|
||||
_nic.tx()->alloc_packet(tx_pkt_size) };
|
||||
_nic.tx()->alloc_packet(src.num_bytes) };
|
||||
|
||||
void *tx_pkt_base {
|
||||
_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);
|
||||
out_count = tx_pkt_size;
|
||||
out_count = src.num_bytes;
|
||||
|
||||
return Write_result::WRITE_OK;
|
||||
} catch (...) {
|
||||
|
@ -136,8 +136,7 @@ class Vfs::Uplink_file_system::Uplink_vfs_handle : public Single_vfs_handle,
|
||||
return _drv_link_state;
|
||||
}
|
||||
|
||||
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 (!_conn.constructed())
|
||||
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 {
|
||||
_conn->rx()->packet_content(conn_rx_pkt) };
|
||||
|
||||
out_count = static_cast<file_size>(min(conn_rx_pkt.size(), static_cast<size_t>(count)));
|
||||
memcpy(dst, conn_rx_pkt_base, static_cast<size_t>(out_count));
|
||||
out_count = min(conn_rx_pkt.size(), dst.num_bytes);
|
||||
memcpy(dst.start, conn_rx_pkt_base, out_count);
|
||||
|
||||
_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;
|
||||
}
|
||||
|
||||
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 (!_conn.constructed())
|
||||
return Write_result::WRITE_ERR_INVALID;
|
||||
|
||||
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;
|
||||
memcpy(dst, src, dst_size);
|
||||
memcpy(dst, src.start, dst_size);
|
||||
return Uplink_client_base::Write_result::WRITE_SUCCEEDED;
|
||||
});
|
||||
|
||||
if (out_count == count)
|
||||
if (out_count == src.num_bytes)
|
||||
return Write_result::WRITE_OK;
|
||||
else
|
||||
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||
|
@ -165,8 +165,7 @@ class Vfs::Tar_file_system : public File_system
|
||||
: Vfs_handle(fs, fs, alloc, status_flags), _node(node)
|
||||
{ }
|
||||
|
||||
virtual Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) = 0;
|
||||
virtual Read_result read(Byte_range_ptr const &dst, size_t &out_count) = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -174,19 +173,18 @@ class Vfs::Tar_file_system : public File_system
|
||||
{
|
||||
using Tar_vfs_handle::Tar_vfs_handle;
|
||||
|
||||
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
|
||||
{
|
||||
file_size const record_size = _node->record->size();
|
||||
|
||||
file_size const record_bytes_left = record_size >= seek()
|
||||
? 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();
|
||||
|
||||
memcpy(dst, data, (size_t)count);
|
||||
memcpy(dst.start, data, count);
|
||||
|
||||
out_count = count;
|
||||
return READ_OK;
|
||||
@ -197,13 +195,12 @@ class Vfs::Tar_file_system : public File_system
|
||||
{
|
||||
using Tar_vfs_handle::Tar_vfs_handle;
|
||||
|
||||
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 (count < sizeof(Dirent))
|
||||
if (dst.num_bytes < sizeof(Dirent))
|
||||
return READ_ERR_INVALID;
|
||||
|
||||
Dirent &dirent = *(Dirent*)dst;
|
||||
Dirent &dirent = *(Dirent*)dst.start;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
@ -751,23 +747,19 @@ class Vfs::Tar_file_system : public File_system
|
||||
** 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;
|
||||
}
|
||||
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, char *dst,
|
||||
file_size count, file_size &out_count) override
|
||||
Read_result complete_read(Vfs_handle *vfs_handle, Byte_range_ptr const &dst,
|
||||
size_t &out_count) override
|
||||
{
|
||||
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 READ_ERR_INVALID;
|
||||
|
||||
return handle->read(dst, count, out_count);
|
||||
return handle.read(dst, out_count);
|
||||
}
|
||||
|
||||
Ftruncate_result ftruncate(Vfs_handle *, file_size) override
|
||||
|
@ -149,8 +149,7 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
|
||||
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
|
||||
{
|
||||
if (_read_buffer.empty())
|
||||
_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;
|
||||
|
||||
unsigned consumed = 0;
|
||||
for (; consumed < count && !_read_buffer.empty(); consumed++)
|
||||
dst[consumed] = _read_buffer.get();
|
||||
for (; consumed < dst.num_bytes && !_read_buffer.empty(); consumed++)
|
||||
dst.start[consumed] = _read_buffer.get();
|
||||
|
||||
out_count = consumed;
|
||||
|
||||
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 = _terminal.write(src, (size_t)count);
|
||||
out_count = _terminal.write(src.start, src.num_bytes);
|
||||
return WRITE_OK;
|
||||
}
|
||||
};
|
||||
|
@ -48,35 +48,35 @@ struct Vfs::Zero_file_system : Single_file_system
|
||||
_size(size)
|
||||
{ }
|
||||
|
||||
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
|
||||
{
|
||||
size_t count = dst.num_bytes;
|
||||
|
||||
if (_size) {
|
||||
|
||||
/* current read offset */
|
||||
file_size const read_offset = seek();
|
||||
|
||||
/* 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) {
|
||||
out_count = 0;
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
count = end_offset - read_offset;
|
||||
count = size_t(end_offset - read_offset);
|
||||
}
|
||||
|
||||
memset(dst, 0, (size_t)count);
|
||||
memset(dst.start, 0, count);
|
||||
|
||||
out_count = count;
|
||||
|
||||
return READ_OK;
|
||||
}
|
||||
|
||||
Write_result write(char const *, file_size count,
|
||||
file_size &out_count) override
|
||||
Write_result write(Const_byte_range_ptr const &src, size_t &out_count) override
|
||||
{
|
||||
out_count = count;
|
||||
out_count = src.num_bytes;
|
||||
|
||||
return WRITE_OK;
|
||||
}
|
||||
|
@ -153,12 +153,14 @@ class Fs_report::Session_component : public Genode::Rpc_object<Report::Session>
|
||||
|
||||
size_t offset = 0;
|
||||
while (offset < length) {
|
||||
file_size n = 0;
|
||||
size_t n = 0;
|
||||
|
||||
handle->seek(offset);
|
||||
Write_result res = handle->fs().write(
|
||||
handle, _ds.local_addr<char const>() + offset,
|
||||
length - offset, n);
|
||||
|
||||
Const_byte_range_ptr const src(_ds.local_addr<char>() + offset,
|
||||
length - offset);
|
||||
|
||||
Write_result res = handle->fs().write(handle, src, n);
|
||||
|
||||
if (res != Write_result::WRITE_OK) {
|
||||
/* do not spam the log */
|
||||
@ -169,7 +171,7 @@ class Fs_report::Session_component : public Genode::Rpc_object<Report::Session>
|
||||
return;
|
||||
}
|
||||
|
||||
offset += (size_t)n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
_file_size = length;
|
||||
|
@ -378,10 +378,12 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
||||
|
||||
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:
|
||||
_acknowledge_as_success((size_t)out_count);
|
||||
break;
|
||||
@ -402,13 +404,13 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
||||
*
|
||||
* \return number of consumed bytes
|
||||
*/
|
||||
size_t _execute_write(char const *src_ptr, size_t length,
|
||||
seek_off_t write_pos)
|
||||
size_t _execute_write(Const_byte_range_ptr const &src, seek_off_t write_pos)
|
||||
{
|
||||
file_size out_count = 0;
|
||||
size_t out_count = 0;
|
||||
_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:
|
||||
break;
|
||||
|
||||
@ -423,7 +425,7 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
||||
|
||||
_modified = true;
|
||||
|
||||
return (size_t)out_count;
|
||||
return out_count;
|
||||
}
|
||||
|
||||
void _execute_sync()
|
||||
@ -669,10 +671,11 @@ struct Vfs_server::Symlink : Io_node
|
||||
*/
|
||||
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)
|
||||
_acknowledge_as_success(count);
|
||||
if (_execute_write(src, 0) == src.num_bytes)
|
||||
_acknowledge_as_success(src.num_bytes);
|
||||
else
|
||||
_acknowledge_as_failure();
|
||||
break;
|
||||
@ -736,7 +739,7 @@ class Vfs_server::File : public Io_node
|
||||
*
|
||||
* Used for the incremental write to continuous files.
|
||||
*/
|
||||
seek_off_t _write_pos = 0;
|
||||
size_t _write_pos = 0;
|
||||
|
||||
bool _watch_read_ready = false;
|
||||
|
||||
@ -800,13 +803,13 @@ class Vfs_server::File : public Io_node
|
||||
|
||||
case Packet_descriptor::WRITE:
|
||||
{
|
||||
size_t const count = (size_t)(_packet.length() - _write_pos);
|
||||
char const * const src_ptr = _payload_ptr.ptr + _write_pos;
|
||||
size_t const consumed = _execute_write(src_ptr, count,
|
||||
_write_pos);
|
||||
Const_byte_range_ptr const src { _payload_ptr.ptr + _write_pos,
|
||||
_packet.length() - _write_pos };
|
||||
|
||||
if (consumed == count) {
|
||||
_acknowledge_as_success(count);
|
||||
size_t const consumed = _execute_write(src, _write_pos);
|
||||
|
||||
if (consumed == src.num_bytes) {
|
||||
_acknowledge_as_success(src.num_bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ namespace Vfs_block {
|
||||
|
||||
using file_size = Vfs::file_size;
|
||||
using file_offset = Vfs::file_offset;
|
||||
using size_t = Genode::size_t;
|
||||
|
||||
struct Job
|
||||
{
|
||||
@ -57,7 +58,7 @@ namespace Vfs_block {
|
||||
State state;
|
||||
file_offset const base_offset;
|
||||
file_offset current_offset;
|
||||
file_size current_count;
|
||||
size_t current_count;
|
||||
|
||||
bool success;
|
||||
bool complete;
|
||||
@ -82,12 +83,13 @@ namespace Vfs_block {
|
||||
using Result = Vfs::File_io_service::Read_result;
|
||||
|
||||
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
|
||||
|| result == Result::READ_ERR_WOULD_BLOCK) {
|
||||
return progress;
|
||||
@ -142,11 +144,13 @@ namespace Vfs_block {
|
||||
using Result = Vfs::File_io_service::Write_result;
|
||||
|
||||
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) {
|
||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||
return progress;
|
||||
@ -243,7 +247,7 @@ namespace Vfs_block {
|
||||
Block::Request request,
|
||||
file_offset base_offset,
|
||||
char *data,
|
||||
file_size length)
|
||||
size_t length)
|
||||
:
|
||||
_handle { handle },
|
||||
request { request },
|
||||
|
@ -26,7 +26,7 @@ using Chunk_level_1 = Chunk_index<4, Chunk_level_2>;
|
||||
|
||||
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
|
||||
{
|
||||
@ -34,7 +34,7 @@ struct Chunk_level_0 : Chunk_index<5, Chunk_level_1>
|
||||
if (used_size() > Chunk_level_0::SIZE) {
|
||||
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, "\"");
|
||||
for (unsigned i = 0; i < used_size(); i++) {
|
||||
@ -98,6 +98,8 @@ struct Allocator_tracer : Allocator
|
||||
|
||||
struct Main
|
||||
{
|
||||
using Seek = Chunk_base::Seek;
|
||||
|
||||
Env &env;
|
||||
Heap heap { env.ram(), env.rm() };
|
||||
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 3: payload=", (int)Chunk_level_3::SIZE, " sizeof=", sizeof(Chunk_level_3));
|
||||
{
|
||||
Chunk_level_0 chunk(alloc, 0);
|
||||
write(chunk, "five-o-one", 0);
|
||||
Chunk_level_0 chunk(alloc, Seek { 0 });
|
||||
write(chunk, "five-o-one", Seek { 0 });
|
||||
|
||||
/* overwrite part of the file */
|
||||
write(chunk, "five", 7);
|
||||
write(chunk, "five", Seek { 7 });
|
||||
|
||||
/* write to position beyond current file length */
|
||||
write(chunk, "Nuance", 17);
|
||||
write(chunk, "YM-2149", 35);
|
||||
write(chunk, "Nuance", Seek { 17 });
|
||||
write(chunk, "YM-2149", Seek { 35 });
|
||||
|
||||
truncate(chunk, 30);
|
||||
truncate(chunk, Seek { 30 });
|
||||
for (unsigned i = 29; i > 0; i--)
|
||||
truncate(chunk, i);
|
||||
truncate(chunk, Seek { i });
|
||||
}
|
||||
log("allocator: sum=", alloc.sum);
|
||||
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);
|
||||
log("write \"", str, "\" at offset ", seek_offset, " -> ", chunk);
|
||||
chunk.write(Const_byte_range_ptr(str, strlen(str)), seek);
|
||||
|
||||
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);
|
||||
log("trunc(", size, ") -> ", chunk);
|
||||
log("trunc(", size.value, ") -> ", chunk);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -290,9 +290,9 @@ struct Write_test : public Stress_test
|
||||
path.base(), Directory_service::OPEN_MODE_WRONLY, &handle, alloc));
|
||||
Vfs_handle::Guard guard(handle);
|
||||
|
||||
file_size n;
|
||||
size_t n;
|
||||
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);
|
||||
while (handle->fs().complete_sync(handle) ==
|
||||
Vfs::File_io_service::SYNC_QUEUED)
|
||||
@ -366,13 +366,15 @@ struct Read_test : public Stress_test
|
||||
Vfs_handle::Guard guard(handle);
|
||||
|
||||
char tmp[MAX_PATH_LEN];
|
||||
file_size n;
|
||||
size_t n;
|
||||
handle->fs().queue_read(handle, sizeof(tmp));
|
||||
|
||||
Vfs::File_io_service::Read_result read_result;
|
||||
|
||||
Byte_range_ptr const dst { tmp, sizeof(tmp) };
|
||||
|
||||
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)
|
||||
_io.commit_and_wait();
|
||||
|
||||
@ -444,10 +446,11 @@ struct Unlink_test : public Stress_test
|
||||
for (Vfs::file_size i = vfs.num_dirent(path); i;) {
|
||||
dir_handle->seek(--i * 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,
|
||||
sizeof(dirent), out_count) ==
|
||||
Byte_range_ptr const dst { (char*)&dirent, sizeof(dirent) };
|
||||
size_t out_count;
|
||||
|
||||
while (dir_handle->fs().complete_read(dir_handle, dst, out_count) ==
|
||||
Vfs::File_io_service::READ_QUEUED)
|
||||
_io.commit_and_wait();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user