From 81cf113b48527e4ad2fb4669ad0f80f149ad7a14 Mon Sep 17 00:00:00 2001 From: Benjamin Lamowski Date: Thu, 19 Sep 2024 16:22:44 +0200 Subject: [PATCH] Revert "PROPOSAL libc: implement read and write by async_read and async_write" See https://github.com/genodelabs/genode/issues/5302#issuecomment-2353815371 for a discussion of the proposal. This reverts commit 4ed972c9c7797b1b1b08c447baf96ab6bba65a62. --- repos/libports/src/lib/libc/internal/plugin.h | 22 +++--- repos/libports/src/lib/libc/vfs_plugin.cc | 67 +++++++++++-------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/repos/libports/src/lib/libc/internal/plugin.h b/repos/libports/src/lib/libc/internal/plugin.h index f7956a62c14..08707424437 100644 --- a/repos/libports/src/lib/libc/internal/plugin.h +++ b/repos/libports/src/lib/libc/internal/plugin.h @@ -79,22 +79,18 @@ namespace Libc { virtual bool supports_mmap(); /* - * Asynchronous I/O + * Asynchronous helper methods */ - struct Async_result - { - bool complete; - - /* value that would be returned by the corresponding read() etc. */ - ssize_t return_status; - - /* errno value that would be set by the corresponding read() etc. */ - int error_status; + struct Async_read_state { + bool complete_read { false }; }; + virtual bool async_read(File_descriptor *, void *, ::size_t, ::off_t, ssize_t &, int &, Async_read_state &); - virtual Async_result async_read(File_descriptor *, void *, ::size_t, ::off_t); - - virtual Async_result async_write(File_descriptor *, const void *, ::size_t, ::off_t); + struct Async_write_state { + bool first_run { true }; + size_t bytes_written { 0 }; + }; + virtual bool async_write(File_descriptor *, const void *, ::size_t, ::off_t, ssize_t &, int &, Async_write_state &); /* * Should be overwritten for plugins that require the Genode environment diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 5f01341e3b4..cd8b0d0ed61 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -946,37 +946,38 @@ ssize_t Libc::Vfs_plugin::read(File_descriptor *fd, void *buf, } -Libc::Vfs_plugin::Async_result -Libc::Vfs_plugin::async_write(File_descriptor *fd, - void const *buf, - ::size_t count, - ::off_t offset) +bool Libc::Vfs_plugin::async_write(File_descriptor *fd, + void const *buf, + ::size_t count, + ::off_t offset, + ssize_t &retval, + int &result_errno, + Async_write_state &write_state) { using Result = Vfs::File_io_service::Write_result; - if ((fd->flags & O_ACCMODE) == O_RDONLY) - return { true, -1, EBADF }; + if ((fd->flags & O_ACCMODE) == O_RDONLY) { + result_errno = EBADF; + retval = -1; + return true; + } Vfs::Vfs_handle *handle = vfs_handle(fd); Result out_result = Result::WRITE_OK; - size_t bytes_written = 0; + if (offset && write_state.first_run) + handle->seek(offset); -/* FIXME seek is not relevant for aio - thus implement in ::write only */ -// if (offset && write_state.first_run) -// handle->seek(offset); -// -// write_state.first_run = false; + write_state.first_run = false; if (fd->flags & O_NONBLOCK) { Const_byte_range_ptr const src { (char const *)buf, count }; - out_result = handle->fs().write(handle, src, bytes_written); + out_result = handle->fs().write(handle, src, write_state.bytes_written); -/* FIXME seek is not relevant for aio - thus implement in ::write only */ -// if (out_result == Result::WRITE_OK) -// handle->advance_seek(write_state.bytes_written); + if (out_result == Result::WRITE_OK) + handle->advance_seek(write_state.bytes_written); } else { auto _fd_refers_to_continuous_file = [&] { @@ -1001,9 +1002,9 @@ Libc::Vfs_plugin::async_write(File_descriptor *fd, ::size_t partial_out_count = 0; /* Subtract already written bytes from count */ - ::size_t remaining_count = count - bytes_written; + ::size_t remaining_count = count - write_state.bytes_written; - Const_byte_range_ptr const src { (char const *)buf + bytes_written, + Const_byte_range_ptr const src { (char const *)buf + write_state.bytes_written, remaining_count }; out_result = handle->fs().write(handle, src, partial_out_count); @@ -1021,7 +1022,7 @@ Libc::Vfs_plugin::async_write(File_descriptor *fd, bool const write_complete = (partial_out_count == remaining_count); if (!write_complete) { - bool const continuous_file = (bytes_written || _fd_refers_to_continuous_file()); + bool const continuous_file = (write_state.bytes_written || _fd_refers_to_continuous_file()); if (!continuous_file) { warning("partial write on transactional file"); @@ -1030,7 +1031,7 @@ Libc::Vfs_plugin::async_write(File_descriptor *fd, } } - bytes_written += partial_out_count; + write_state.bytes_written += partial_out_count; handle->advance_seek(partial_out_count); @@ -1041,13 +1042,25 @@ Libc::Vfs_plugin::async_write(File_descriptor *fd, switch (out_result) { /* Not reached */ - case Result::WRITE_ERR_WOULD_BLOCK: return { true, -1, EWOULDBLOCK }; - case Result::WRITE_ERR_INVALID: return { true, -1, EINVAL }; - case Result::WRITE_ERR_IO: return { true, -1, EIO }; - case Result::WRITE_OK: return { true, -1, bytes_written }; + case Result::WRITE_ERR_WOULD_BLOCK: + result_errno = EWOULDBLOCK; + retval = -1; + break; + case Result::WRITE_ERR_INVALID: + result_errno = EINVAL; + retval = -1; + break; + case Result::WRITE_ERR_IO: + result_errno = EIO; + retval = -1; + break; + case Result::WRITE_OK: + retval = write_state.bytes_written; + result_errno = 0; + break; } -// -// return true; + + return true; }