mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
vfs: simplify File_io_service::write return values
This patch removes the 'Insufficient_buffer' exception by returning the WRITE_ERR_WOULD_BLOCK result value instead. It also eliminates the superfluous WRITE_ERR_AGAIN and WRITE_ERR_INTERRUPT codes. Issue #4697
This commit is contained in:
parent
d9f5dda322
commit
cf87b0fadb
@ -159,7 +159,7 @@ class Vfs::Rump_file_system : public File_system
|
|||||||
case EWOULDBLOCK: return WRITE_ERR_WOULD_BLOCK;
|
case EWOULDBLOCK: return WRITE_ERR_WOULD_BLOCK;
|
||||||
case EINVAL: return WRITE_ERR_INVALID;
|
case EINVAL: return WRITE_ERR_INVALID;
|
||||||
case EIO: return WRITE_ERR_IO;
|
case EIO: return WRITE_ERR_IO;
|
||||||
case EINTR: return WRITE_ERR_INTERRUPT;
|
case EINTR: return WRITE_ERR_IO;
|
||||||
default:
|
default:
|
||||||
Genode::error(__func__, ": unhandled rump error ", errno);
|
Genode::error(__func__, ": unhandled rump error ", errno);
|
||||||
return WRITE_ERR_IO;
|
return WRITE_ERR_IO;
|
||||||
|
@ -174,31 +174,25 @@ namespace Util {
|
|||||||
bool completed = false;
|
bool completed = false;
|
||||||
file_size out = 0;
|
file_size out = 0;
|
||||||
|
|
||||||
Result result = Result::WRITE_ERR_INVALID;
|
|
||||||
try {
|
|
||||||
result = _handle.fs().write(&_handle,
|
|
||||||
_data + _current_offset,
|
|
||||||
_current_count, out);
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_AGAIN
|
Result const result =
|
||||||
|| result == Result::WRITE_ERR_INTERRUPT
|
_handle.fs().write(&_handle, _data + _current_offset,
|
||||||
|| result == Result::WRITE_ERR_WOULD_BLOCK) {
|
_current_count, out);
|
||||||
|
switch (result) {
|
||||||
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
return progress;
|
return progress;
|
||||||
} else
|
|
||||||
|
|
||||||
if (result == Result::WRITE_OK) {
|
case Result::WRITE_OK:
|
||||||
_current_offset += out;
|
_current_offset += out;
|
||||||
_current_count -= out;
|
_current_count -= out;
|
||||||
_success = true;
|
_success = true;
|
||||||
} else
|
break;
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_IO
|
case Result::WRITE_ERR_IO:
|
||||||
|| result == Result::WRITE_ERR_INVALID) {
|
case Result::WRITE_ERR_INVALID:
|
||||||
_success = false;
|
_success = false;
|
||||||
completed = true;
|
completed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_current_count == 0 || completed || (out == 0 && _allow_partial)) {
|
if (_current_count == 0 || completed || (out == 0 && _allow_partial)) {
|
||||||
|
@ -70,15 +70,16 @@ Crypto::Result Crypto::add_key(Key const &key)
|
|||||||
|
|
||||||
_add_key_handle.seek(0);
|
_add_key_handle.seek(0);
|
||||||
file_size nr_of_written_bytes { 0 };
|
file_size nr_of_written_bytes { 0 };
|
||||||
try {
|
|
||||||
_add_key_handle.fs().write(
|
|
||||||
&_add_key_handle, buffer, sizeof (buffer),
|
|
||||||
nr_of_written_bytes);
|
|
||||||
|
|
||||||
} catch (File_io_service::Insufficient_buffer) {
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
|
||||||
|
Write_result const result =
|
||||||
|
_add_key_handle.fs().write(&_add_key_handle, buffer, sizeof (buffer),
|
||||||
|
nr_of_written_bytes);
|
||||||
|
|
||||||
|
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||||
return Result::RETRY_LATER;
|
return Result::RETRY_LATER;
|
||||||
}
|
|
||||||
Key_directory &key_dir { _get_unused_key_dir() };
|
Key_directory &key_dir { _get_unused_key_dir() };
|
||||||
|
|
||||||
key_dir.encrypt_handle = &vfs_open_rw(
|
key_dir.encrypt_handle = &vfs_open_rw(
|
||||||
@ -98,17 +99,17 @@ Crypto::Result Crypto::remove_key(Cbe::Key::Id key_id)
|
|||||||
{
|
{
|
||||||
Vfs::file_size written = 0;
|
Vfs::file_size written = 0;
|
||||||
_remove_key_handle.seek(0);
|
_remove_key_handle.seek(0);
|
||||||
try {
|
|
||||||
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
Write_result const result =
|
||||||
_remove_key_handle.fs().write(&_remove_key_handle,
|
_remove_key_handle.fs().write(&_remove_key_handle,
|
||||||
(char const*)&key_id.value,
|
(char const*)&key_id.value,
|
||||||
sizeof (key_id.value),
|
sizeof (key_id.value),
|
||||||
written);
|
written);
|
||||||
(void)written;
|
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
|
|
||||||
|
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||||
return Result::RETRY_LATER;
|
return Result::RETRY_LATER;
|
||||||
}
|
|
||||||
Key_directory &key_dir { _lookup_key_dir(key_id.value) };
|
Key_directory &key_dir { _lookup_key_dir(key_id.value) };
|
||||||
_env.root_dir().close(key_dir.encrypt_handle);
|
_env.root_dir().close(key_dir.encrypt_handle);
|
||||||
key_dir.encrypt_handle = nullptr;
|
key_dir.encrypt_handle = nullptr;
|
||||||
@ -200,22 +201,17 @@ void Crypto::_execute_decrypt_block(Job &job,
|
|||||||
{
|
{
|
||||||
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
||||||
file_size nr_of_written_bytes { 0 };
|
file_size nr_of_written_bytes { 0 };
|
||||||
try {
|
|
||||||
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);
|
|
||||||
|
|
||||||
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
job.handle->fs().write(
|
||||||
progress = true;
|
job.handle,
|
||||||
return;
|
reinterpret_cast<char const*>(
|
||||||
|
&cipher_buf.item(job.cipher_buf_idx)),
|
||||||
|
file_size(sizeof (Cbe::Block_data)),
|
||||||
|
nr_of_written_bytes);
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
||||||
|
progress = true;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case Job_state::OP_WRITTEN_TO_VFS_HANDLE:
|
case Job_state::OP_WRITTEN_TO_VFS_HANDLE:
|
||||||
{
|
{
|
||||||
@ -271,22 +267,17 @@ void Crypto::_execute_encrypt_block(Job &job,
|
|||||||
{
|
{
|
||||||
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
job.handle->seek(job.request.block_number() * Cbe::BLOCK_SIZE);
|
||||||
file_size nr_of_written_bytes { 0 };
|
file_size nr_of_written_bytes { 0 };
|
||||||
try {
|
|
||||||
job.handle->fs().write(
|
|
||||||
job.handle,
|
|
||||||
reinterpret_cast<char const*>(
|
|
||||||
&plain_buf.item(job.plain_buf_idx)),
|
|
||||||
file_size(sizeof (Cbe::Block_data)),
|
|
||||||
nr_of_written_bytes);
|
|
||||||
|
|
||||||
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
job.handle->fs().write(
|
||||||
progress = true;
|
job.handle,
|
||||||
return;
|
reinterpret_cast<char const*>(
|
||||||
|
&plain_buf.item(job.plain_buf_idx)),
|
||||||
|
file_size(sizeof (Cbe::Block_data)),
|
||||||
|
nr_of_written_bytes);
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
job.state = Job_state::OP_WRITTEN_TO_VFS_HANDLE;
|
||||||
|
progress = true;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case Job_state::OP_WRITTEN_TO_VFS_HANDLE:
|
case Job_state::OP_WRITTEN_TO_VFS_HANDLE:
|
||||||
{
|
{
|
||||||
|
@ -393,22 +393,14 @@ class Vfs_block_io_job
|
|||||||
reinterpret_cast<char *>(
|
reinterpret_cast<char *>(
|
||||||
&io_data.item(_cbe_req_io_buf_idx(_cbe_req))) };
|
&io_data.item(_cbe_req_io_buf_idx(_cbe_req))) };
|
||||||
|
|
||||||
Result result;
|
Result const result =
|
||||||
try {
|
_handle.fs().write(&_handle,
|
||||||
result = _handle.fs().write(&_handle,
|
data + _nr_of_processed_bytes,
|
||||||
data + _nr_of_processed_bytes,
|
_nr_of_remaining_bytes,
|
||||||
_nr_of_remaining_bytes,
|
nr_of_written_bytes);
|
||||||
nr_of_written_bytes);
|
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Result::WRITE_ERR_AGAIN:
|
|
||||||
case Result::WRITE_ERR_INTERRUPT:
|
|
||||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Result::WRITE_OK:
|
case Result::WRITE_OK:
|
||||||
|
@ -37,22 +37,12 @@ void Trust_anchor::_execute_write_read_operation(Vfs_handle &file,
|
|||||||
case Job_state::WRITE_IN_PROGRESS:
|
case Job_state::WRITE_IN_PROGRESS:
|
||||||
{
|
{
|
||||||
file_size nr_of_written_bytes { 0 };
|
file_size nr_of_written_bytes { 0 };
|
||||||
Write_result result { Write_result::WRITE_ERR_INVALID };
|
Write_result const result =
|
||||||
try {
|
file.fs().write(&file, write_buf + _job.fl_offset,
|
||||||
result =
|
_job.fl_size, nr_of_written_bytes);
|
||||||
file.fs().write(
|
|
||||||
&file, write_buf + _job.fl_offset,
|
|
||||||
_job.fl_size, nr_of_written_bytes);
|
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Write_result::WRITE_ERR_AGAIN:
|
|
||||||
case Write_result::WRITE_ERR_INTERRUPT:
|
|
||||||
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
|
||||||
|
|
||||||
|
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Write_result::WRITE_OK:
|
case Write_result::WRITE_OK:
|
||||||
@ -155,22 +145,14 @@ void Trust_anchor::_execute_write_operation(Vfs_handle &file,
|
|||||||
case Job_state::WRITE_IN_PROGRESS:
|
case Job_state::WRITE_IN_PROGRESS:
|
||||||
{
|
{
|
||||||
file_size nr_of_written_bytes { 0 };
|
file_size nr_of_written_bytes { 0 };
|
||||||
Write_result result { Write_result::WRITE_ERR_INVALID };
|
Write_result const result =
|
||||||
try {
|
file.fs().write(
|
||||||
result =
|
&file, write_buf + _job.fl_offset,
|
||||||
file.fs().write(
|
_job.fl_size, nr_of_written_bytes);
|
||||||
&file, write_buf + _job.fl_offset,
|
|
||||||
_job.fl_size, nr_of_written_bytes);
|
|
||||||
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Write_result::WRITE_ERR_AGAIN:
|
|
||||||
case Write_result::WRITE_ERR_INTERRUPT:
|
|
||||||
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
|
||||||
|
|
||||||
|
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Write_result::WRITE_OK:
|
case Write_result::WRITE_OK:
|
||||||
|
@ -248,30 +248,27 @@ class Vfs_replay
|
|||||||
bool completed = false;
|
bool completed = false;
|
||||||
file_size out = 0;
|
file_size out = 0;
|
||||||
|
|
||||||
Result result = Result::WRITE_ERR_INVALID;
|
Result const result =
|
||||||
try {
|
_vfs_handle->fs().write(_vfs_handle,
|
||||||
result = _vfs_handle->fs().write(_vfs_handle,
|
_write_buffer.local_addr<char>(),
|
||||||
_write_buffer.local_addr<char>(),
|
request.current_count, out);
|
||||||
request.current_count, out);
|
switch (result) {
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
return progress;
|
return progress;
|
||||||
}
|
|
||||||
if ( result == Result::WRITE_ERR_AGAIN
|
case Result::WRITE_OK:
|
||||||
|| result == Result::WRITE_ERR_INTERRUPT
|
|
||||||
|| result == Result::WRITE_ERR_WOULD_BLOCK) {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
if (result == Result::WRITE_OK) {
|
|
||||||
request.current_offset += out;
|
request.current_offset += out;
|
||||||
request.current_count -= out;
|
request.current_count -= out;
|
||||||
request.success = true;
|
request.success = true;
|
||||||
}
|
break;
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_IO
|
case Result::WRITE_ERR_IO:
|
||||||
|| result == Result::WRITE_ERR_INVALID) {
|
case Result::WRITE_ERR_INVALID:
|
||||||
request.success = false;
|
request.success = false;
|
||||||
completed = true;
|
completed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.current_count == 0 || completed) {
|
if (request.current_count == 0 || completed) {
|
||||||
request.state = Request::State::WRITE_COMPLETE;
|
request.state = Request::State::WRITE_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -233,7 +233,7 @@ class Vfs_audit::File_system : public Vfs::File_system
|
|||||||
|
|
||||||
if (result == WRITE_OK)
|
if (result == WRITE_OK)
|
||||||
_log("wrote to ", h.path, " ", out, " / ", len);
|
_log("wrote to ", h.path, " ", out, " / ", len);
|
||||||
else if (result == WRITE_ERR_WOULD_BLOCK || result == WRITE_ERR_AGAIN)
|
else if (result == WRITE_ERR_WOULD_BLOCK)
|
||||||
_log("write stalled for ", h.path);
|
_log("write stalled for ", h.path);
|
||||||
else
|
else
|
||||||
_log("write failed for ", h.path);
|
_log("write failed for ", h.path);
|
||||||
|
@ -152,33 +152,27 @@ namespace Vfs_cbe {
|
|||||||
bool completed = false;
|
bool completed = false;
|
||||||
file_size out = 0;
|
file_size out = 0;
|
||||||
|
|
||||||
Result result = Result::WRITE_ERR_INVALID;
|
char const * const data =
|
||||||
try {
|
reinterpret_cast<char const * const>(&io_data.item(_index));
|
||||||
char const * const data =
|
|
||||||
reinterpret_cast<char const * const>(&io_data.item(_index));
|
|
||||||
result = _handle.fs().write(&_handle,
|
|
||||||
data + _current_offset,
|
|
||||||
_current_count, out);
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_AGAIN
|
Result const result =
|
||||||
|| result == Result::WRITE_ERR_INTERRUPT
|
_handle.fs().write(&_handle, data + _current_offset,
|
||||||
|| result == Result::WRITE_ERR_WOULD_BLOCK) {
|
_current_count, out);
|
||||||
|
switch (result) {
|
||||||
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
return progress;
|
return progress;
|
||||||
} else
|
|
||||||
|
|
||||||
if (result == Result::WRITE_OK) {
|
case Result::WRITE_OK:
|
||||||
_current_offset += out;
|
_current_offset += out;
|
||||||
_current_count -= out;
|
_current_count -= out;
|
||||||
_success = true;
|
_success = true;
|
||||||
} else
|
break;
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_IO
|
case Result::WRITE_ERR_IO:
|
||||||
|| result == Result::WRITE_ERR_INVALID) {
|
case Result::WRITE_ERR_INVALID:
|
||||||
_success = false;
|
_success = false;
|
||||||
completed = true;
|
completed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_current_count == 0 || completed) {
|
if (_current_count == 0 || completed) {
|
||||||
|
@ -1185,14 +1185,15 @@ class Vfs_cbe::Wrapper
|
|||||||
|
|
||||||
file_size written = 0;
|
file_size written = 0;
|
||||||
_add_key_handle->seek(0);
|
_add_key_handle->seek(0);
|
||||||
try {
|
|
||||||
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
|
||||||
|
Write_result const result =
|
||||||
_add_key_handle->fs().write(_add_key_handle,
|
_add_key_handle->fs().write(_add_key_handle,
|
||||||
buffer, sizeof (buffer), written);
|
buffer, sizeof (buffer), written);
|
||||||
(void)written;
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||||
/* try again later */
|
break; /* try again later */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instead of acknowledge the CBE's request before we write
|
* Instead of acknowledge the CBE's request before we write
|
||||||
@ -1278,16 +1279,17 @@ class Vfs_cbe::Wrapper
|
|||||||
|
|
||||||
file_size written = 0;
|
file_size written = 0;
|
||||||
_remove_key_handle->seek(0);
|
_remove_key_handle->seek(0);
|
||||||
try {
|
|
||||||
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
|
||||||
|
Write_result const result =
|
||||||
_remove_key_handle->fs().write(_remove_key_handle,
|
_remove_key_handle->fs().write(_remove_key_handle,
|
||||||
(char const*)&key_id.value,
|
(char const*)&key_id.value,
|
||||||
sizeof (key_id.value),
|
sizeof (key_id.value),
|
||||||
written);
|
written);
|
||||||
(void)written;
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
if (result == Write_result::WRITE_ERR_WOULD_BLOCK)
|
||||||
/* try again later */
|
break; /* try again later */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Crypto_file *cf = nullptr;
|
Crypto_file *cf = nullptr;
|
||||||
try {
|
try {
|
||||||
@ -1395,14 +1397,13 @@ class Vfs_cbe::Wrapper
|
|||||||
case Crypto_job::State::IDLE:
|
case Crypto_job::State::IDLE:
|
||||||
break;
|
break;
|
||||||
case Crypto_job::State::SUBMITTED:
|
case Crypto_job::State::SUBMITTED:
|
||||||
try {
|
{
|
||||||
char const *data = nullptr;
|
char const *data = nullptr;
|
||||||
|
|
||||||
if (op == Crypto_job::Operation::ENCRYPT) {
|
if (op == Crypto_job::Operation::ENCRYPT) {
|
||||||
data = reinterpret_cast<char const*>(&plain.item(plain_index));
|
data = reinterpret_cast<char const*>(&plain.item(plain_index));
|
||||||
} else
|
}
|
||||||
|
else if (op == Crypto_job::Operation::DECRYPT) {
|
||||||
if (op == Crypto_job::Operation::DECRYPT) {
|
|
||||||
data = reinterpret_cast<char const*>(&cipher.item(cipher_index));
|
data = reinterpret_cast<char const*>(&cipher.item(cipher_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,16 +1414,14 @@ class Vfs_cbe::Wrapper
|
|||||||
|
|
||||||
if (op == Crypto_job::Operation::ENCRYPT) {
|
if (op == Crypto_job::Operation::ENCRYPT) {
|
||||||
cbe.crypto_cipher_data_requested(plain_index);
|
cbe.crypto_cipher_data_requested(plain_index);
|
||||||
} else
|
}
|
||||||
|
else if (op == Crypto_job::Operation::DECRYPT) {
|
||||||
if (op == Crypto_job::Operation::DECRYPT) {
|
|
||||||
cbe.crypto_plain_data_requested(cipher_index);
|
cbe.crypto_plain_data_requested(cipher_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = Crypto_job::State::PENDING;
|
state = Crypto_job::State::PENDING;
|
||||||
result.progress |= true;
|
result.progress |= true;
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) { }
|
}
|
||||||
|
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
case Crypto_job::State::PENDING:
|
case Crypto_job::State::PENDING:
|
||||||
@ -1939,9 +1938,9 @@ class Vfs_cbe::Data_file_system : public Single_file_system
|
|||||||
State state = _w.frontend_request().state;
|
State state = _w.frontend_request().state;
|
||||||
if (state == State::NONE) {
|
if (state == State::NONE) {
|
||||||
|
|
||||||
if (!_w.client_request_acceptable()) {
|
if (!_w.client_request_acceptable())
|
||||||
throw Insufficient_buffer();
|
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||||
}
|
|
||||||
using Op = Cbe::Request::Operation;
|
using Op = Cbe::Request::Operation;
|
||||||
|
|
||||||
bool const accepted =
|
bool const accepted =
|
||||||
@ -1956,7 +1955,7 @@ class Vfs_cbe::Data_file_system : public Single_file_system
|
|||||||
if ( state == State::PENDING
|
if ( state == State::PENDING
|
||||||
|| state == State::IN_PROGRESS) {
|
|| state == State::IN_PROGRESS) {
|
||||||
_w.enqueue_handle(*this);
|
_w.enqueue_handle(*this);
|
||||||
throw Insufficient_buffer();
|
return WRITE_ERR_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State::COMPLETE) {
|
if (state == State::COMPLETE) {
|
||||||
|
@ -98,7 +98,6 @@ class Vfs_import::File_system : public Vfs::File_system
|
|||||||
dst_handle, target.string(), count, out_count);
|
dst_handle, target.string(), count, out_count);
|
||||||
|
|
||||||
switch (wres) {
|
switch (wres) {
|
||||||
case WRITE_ERR_AGAIN:
|
|
||||||
case WRITE_ERR_WOULD_BLOCK:
|
case WRITE_ERR_WOULD_BLOCK:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -151,41 +150,35 @@ class Vfs_import::File_system : public Vfs::File_system
|
|||||||
|
|
||||||
if (!bytes_from_source) break;
|
if (!bytes_from_source) break;
|
||||||
|
|
||||||
bool stalled { false };
|
|
||||||
bool write_error { false };
|
bool write_error { false };
|
||||||
Vfs::file_size remaining_bytes { bytes_from_source };
|
Vfs::file_size remaining_bytes { bytes_from_source };
|
||||||
char const *src { buf };
|
char const *src { buf };
|
||||||
|
|
||||||
while (remaining_bytes > 0 && !write_error) {
|
while (remaining_bytes > 0 && !write_error) {
|
||||||
|
|
||||||
try {
|
Vfs::file_size out_count { 0 };
|
||||||
Vfs::file_size out_count { 0 };
|
|
||||||
switch (dst_handle->fs().write(dst_handle, src,
|
|
||||||
remaining_bytes,
|
|
||||||
out_count)) {
|
|
||||||
case WRITE_ERR_AGAIN:
|
|
||||||
case WRITE_ERR_WOULD_BLOCK:
|
|
||||||
stalled = true;
|
|
||||||
break;
|
|
||||||
case Write_result::WRITE_ERR_INVALID:
|
|
||||||
case Write_result::WRITE_ERR_IO:
|
|
||||||
case Write_result::WRITE_ERR_INTERRUPT:
|
|
||||||
env.root_dir().unlink(path.string());
|
|
||||||
write_error = true;
|
|
||||||
break;
|
|
||||||
case WRITE_OK:
|
|
||||||
out_count = min(remaining_bytes, out_count);
|
|
||||||
remaining_bytes -= out_count;
|
|
||||||
src += out_count;
|
|
||||||
at.value += out_count;
|
|
||||||
dst_handle->advance_seek(out_count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
stalled = true; }
|
|
||||||
|
|
||||||
if (stalled)
|
switch (dst_handle->fs().write(dst_handle, src,
|
||||||
env.env().ep().wait_and_dispatch_one_io_signal();
|
remaining_bytes,
|
||||||
|
out_count)) {
|
||||||
|
case WRITE_ERR_WOULD_BLOCK:
|
||||||
|
env.io().commit_and_wait();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Write_result::WRITE_ERR_INVALID:
|
||||||
|
case Write_result::WRITE_ERR_IO:
|
||||||
|
env.root_dir().unlink(path.string());
|
||||||
|
write_error = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WRITE_OK:
|
||||||
|
out_count = min(remaining_bytes, out_count);
|
||||||
|
remaining_bytes -= out_count;
|
||||||
|
src += out_count;
|
||||||
|
at.value += out_count;
|
||||||
|
dst_handle->advance_seek(out_count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (write_error)
|
if (write_error)
|
||||||
break;
|
break;
|
||||||
|
@ -844,9 +844,7 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
|||||||
if (nonblocking) {
|
if (nonblocking) {
|
||||||
|
|
||||||
monitor().monitor([&] {
|
monitor().monitor([&] {
|
||||||
try {
|
out_result = handle->fs().write(handle, (char const *)buf, count, out_count);
|
||||||
out_result = handle->fs().write(handle, (char const *)buf, count, out_count);
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) { }
|
|
||||||
return Fn::COMPLETE;
|
return Fn::COMPLETE;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -886,23 +884,21 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
|||||||
/* number of bytes written in one iteration */
|
/* number of bytes written in one iteration */
|
||||||
Vfs::file_size partial_out_count = 0;
|
Vfs::file_size partial_out_count = 0;
|
||||||
|
|
||||||
try {
|
char const * const src = (char const *)_buf + _offset;
|
||||||
char const * const src = (char const *)_buf + _offset;
|
_out_result = _handle->fs().write(_handle, src, _count, partial_out_count);
|
||||||
|
|
||||||
_out_result = _handle->fs().write(_handle, src, _count, partial_out_count);
|
if (_out_result == Result::WRITE_ERR_WOULD_BLOCK)
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) { return Fn::INCOMPLETE; }
|
return Fn::INCOMPLETE;
|
||||||
|
|
||||||
if (_out_result != Result::WRITE_OK) {
|
if (_out_result != Result::WRITE_OK)
|
||||||
return Fn::COMPLETE;
|
return Fn::COMPLETE;
|
||||||
}
|
|
||||||
|
|
||||||
/* increment byte count reported to caller */
|
/* increment byte count reported to caller */
|
||||||
_out_count += partial_out_count;
|
_out_count += partial_out_count;
|
||||||
|
|
||||||
bool const write_complete = (partial_out_count == _count);
|
bool const write_complete = (partial_out_count == _count);
|
||||||
if (write_complete) {
|
if (write_complete)
|
||||||
return Fn::COMPLETE;
|
return Fn::COMPLETE;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the write has not consumed all bytes, set up
|
* If the write has not consumed all bytes, set up
|
||||||
@ -941,11 +937,9 @@ ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
|||||||
Plugin::resume_all();
|
Plugin::resume_all();
|
||||||
|
|
||||||
switch (out_result) {
|
switch (out_result) {
|
||||||
case Result::WRITE_ERR_AGAIN: return Errno(EAGAIN);
|
|
||||||
case Result::WRITE_ERR_WOULD_BLOCK: return Errno(EWOULDBLOCK);
|
case Result::WRITE_ERR_WOULD_BLOCK: return Errno(EWOULDBLOCK);
|
||||||
case Result::WRITE_ERR_INVALID: return Errno(EINVAL);
|
case Result::WRITE_ERR_INVALID: return Errno(EINVAL);
|
||||||
case Result::WRITE_ERR_IO: return Errno(EIO);
|
case Result::WRITE_ERR_IO: return Errno(EIO);
|
||||||
case Result::WRITE_ERR_INTERRUPT: return Errno(EINTR);
|
|
||||||
case Result::WRITE_OK: break;
|
case Result::WRITE_OK: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2283,12 +2277,15 @@ int Libc::Vfs_plugin::symlink(const char *target_path, const char *link_path)
|
|||||||
|
|
||||||
case Stage::WRITE:
|
case Stage::WRITE:
|
||||||
{
|
{
|
||||||
try {
|
typedef Vfs::File_io_service::Write_result Result;
|
||||||
handle->fs().write(handle, target_path, count, out_count);
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
Result result = handle->fs().write(handle, target_path,
|
||||||
|
count, out_count);
|
||||||
|
if (result == Result::WRITE_ERR_WOULD_BLOCK)
|
||||||
return Fn::INCOMPLETE;
|
return Fn::INCOMPLETE;
|
||||||
}
|
}
|
||||||
} stage = Stage::SYNC; [[fallthrough]];
|
stage = Stage::SYNC;
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
case Stage::SYNC:
|
case Stage::SYNC:
|
||||||
{
|
{
|
||||||
|
@ -2013,16 +2013,15 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
char const *src, file_size count,
|
char const *src, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
Write_result res = Write_result::WRITE_ERR_INVALID;
|
|
||||||
out_count = 0;
|
out_count = 0;
|
||||||
|
|
||||||
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
||||||
return Write_result::WRITE_ERR_INVALID;
|
return Write_result::WRITE_ERR_INVALID;
|
||||||
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle)) {
|
|
||||||
res = handle->write(src, count, out_count);
|
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle))
|
||||||
if (res == WRITE_ERR_WOULD_BLOCK) throw Insufficient_buffer();
|
return handle->write(src, count, out_count);
|
||||||
}
|
|
||||||
return res;
|
return Write_result::WRITE_ERR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Read_result complete_read(Vfs_handle *vfs_handle,
|
Read_result complete_read(Vfs_handle *vfs_handle,
|
||||||
|
@ -188,6 +188,8 @@ struct Vfs::Oss_file_system::Audio
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Audio(Audio const &);
|
Audio(Audio const &);
|
||||||
@ -509,14 +511,14 @@ struct Vfs::Oss_file_system::Audio
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write(char const *buf, file_size buf_size, file_size &out_size)
|
Write_result write(char const *buf, file_size buf_size, file_size &out_size)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
out_size = 0;
|
out_size = 0;
|
||||||
|
|
||||||
if (_info.ofrag_bytes == 0)
|
if (_info.ofrag_bytes == 0)
|
||||||
throw Vfs::File_io_service::Insufficient_buffer();
|
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||||
|
|
||||||
bool block_write = false;
|
bool block_write = false;
|
||||||
|
|
||||||
@ -527,10 +529,8 @@ struct Vfs::Oss_file_system::Audio
|
|||||||
|
|
||||||
unsigned stream_samples_to_write = buf_size / CHANNELS / sizeof(int16_t);
|
unsigned stream_samples_to_write = buf_size / CHANNELS / sizeof(int16_t);
|
||||||
|
|
||||||
if (stream_samples_to_write == 0) {
|
if (stream_samples_to_write == 0)
|
||||||
/* invalid argument */
|
return Write_result::WRITE_ERR_INVALID;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_start_output();
|
_start_output();
|
||||||
|
|
||||||
@ -554,18 +554,18 @@ struct Vfs::Oss_file_system::Audio
|
|||||||
_out[0]->stream()->reset();
|
_out[0]->stream()->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Look up the previously allocated packet.
|
* Look up the previously allocated packet.
|
||||||
* The tail pointer got incremented after allocation,
|
* The tail pointer got incremented after allocation,
|
||||||
* so we need to decrement by 1.
|
* so we need to decrement by 1.
|
||||||
*/
|
*/
|
||||||
unsigned const tail =
|
unsigned const tail =
|
||||||
(_out[0]->stream()->tail() +
|
(_out[0]->stream()->tail() +
|
||||||
Audio_out::QUEUE_SIZE - 1) %
|
Audio_out::QUEUE_SIZE - 1) %
|
||||||
Audio_out::QUEUE_SIZE;
|
Audio_out::QUEUE_SIZE;
|
||||||
lp = _out[0]->stream()->get(tail);
|
lp = _out[0]->stream()->get(tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned const pos = _out[0]->stream()->packet_position(lp);
|
unsigned const pos = _out[0]->stream()->packet_position(lp);
|
||||||
Audio_out::Packet *rp = _out[1]->stream()->get(pos);
|
Audio_out::Packet *rp = _out[1]->stream()->get(pos);
|
||||||
@ -602,14 +602,15 @@ struct Vfs::Oss_file_system::Audio
|
|||||||
/* update info */
|
/* update info */
|
||||||
update_info_ofrag_avail_from_optr_fifo_samples();
|
update_info_ofrag_avail_from_optr_fifo_samples();
|
||||||
|
|
||||||
if (block_write) { throw Vfs::File_io_service::Insufficient_buffer(); }
|
if (block_write)
|
||||||
|
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||||
|
|
||||||
return true;
|
return Write_result::WRITE_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return Write_result::WRITE_OK;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -665,12 +666,13 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
|
|||||||
Write_result write(char const *buf, file_size buf_size,
|
Write_result write(char const *buf, file_size buf_size,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
try {
|
Write_result const result = _audio.write(buf, buf_size, out_count);
|
||||||
return _audio.write(buf, buf_size, out_count) ? WRITE_OK : WRITE_ERR_INVALID;
|
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
if (result == Write_result::WRITE_ERR_WOULD_BLOCK) {
|
||||||
blocked = true;
|
blocked = true;
|
||||||
return WRITE_OK;
|
return WRITE_OK;
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_ready() override
|
bool read_ready() override
|
||||||
|
@ -755,35 +755,28 @@ class Genode::Writeable_file : Noncopyable
|
|||||||
|
|
||||||
bool stalled = false;
|
bool stalled = false;
|
||||||
|
|
||||||
try {
|
Vfs::file_size out_count = 0;
|
||||||
Vfs::file_size out_count = 0;
|
|
||||||
|
|
||||||
using Write_result = Vfs::File_io_service::Write_result;
|
using Write_result = Vfs::File_io_service::Write_result;
|
||||||
|
|
||||||
switch (handle.fs().write(&handle, src, remaining_bytes,
|
switch (handle.fs().write(&handle, src, remaining_bytes, out_count)) {
|
||||||
out_count)) {
|
|
||||||
|
|
||||||
case Write_result::WRITE_ERR_AGAIN:
|
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
||||||
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
stalled = true;
|
||||||
stalled = true;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Write_result::WRITE_ERR_INVALID:
|
case Write_result::WRITE_ERR_INVALID:
|
||||||
case Write_result::WRITE_ERR_IO:
|
case Write_result::WRITE_ERR_IO:
|
||||||
case Write_result::WRITE_ERR_INTERRUPT:
|
write_error = true;
|
||||||
write_error = true;
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Write_result::WRITE_OK:
|
case Write_result::WRITE_OK:
|
||||||
out_count = min((Vfs::file_size)remaining_bytes, out_count);
|
out_count = min((Vfs::file_size)remaining_bytes, out_count);
|
||||||
remaining_bytes -= (size_t)out_count;
|
remaining_bytes -= (size_t)out_count;
|
||||||
src += out_count;
|
src += out_count;
|
||||||
handle.advance_seek(out_count);
|
handle.advance_seek(out_count);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
stalled = true; }
|
|
||||||
|
|
||||||
if (stalled)
|
if (stalled)
|
||||||
io.commit_and_wait();
|
io.commit_and_wait();
|
||||||
|
@ -30,16 +30,8 @@ struct Vfs::File_io_service : Interface
|
|||||||
** Write **
|
** Write **
|
||||||
***********/
|
***********/
|
||||||
|
|
||||||
/*
|
enum Write_result { WRITE_ERR_WOULD_BLOCK, WRITE_ERR_INVALID,
|
||||||
* Exception, thrown when, for example, 'alloc_packet()' or
|
WRITE_ERR_IO, WRITE_OK };
|
||||||
* 'submit_packet()' failed in the VFS plugin. The caller can try again
|
|
||||||
* after a previous VFS request is completed.
|
|
||||||
*/
|
|
||||||
struct Insufficient_buffer { };
|
|
||||||
|
|
||||||
enum Write_result { WRITE_ERR_AGAIN, WRITE_ERR_WOULD_BLOCK,
|
|
||||||
WRITE_ERR_INVALID, WRITE_ERR_IO,
|
|
||||||
WRITE_ERR_INTERRUPT, WRITE_OK };
|
|
||||||
|
|
||||||
virtual Write_result write(Vfs_handle *vfs_handle,
|
virtual Write_result write(Vfs_handle *vfs_handle,
|
||||||
char const *buf, file_size buf_size,
|
char const *buf, file_size buf_size,
|
||||||
|
@ -133,11 +133,9 @@ static inline void print(Genode::Output &output, Vfs::File_io_service::Write_res
|
|||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
CASE_PRINT(WRITE_OK);
|
CASE_PRINT(WRITE_OK);
|
||||||
CASE_PRINT(WRITE_ERR_AGAIN);
|
|
||||||
CASE_PRINT(WRITE_ERR_WOULD_BLOCK);
|
CASE_PRINT(WRITE_ERR_WOULD_BLOCK);
|
||||||
CASE_PRINT(WRITE_ERR_INVALID);
|
CASE_PRINT(WRITE_ERR_INVALID);
|
||||||
CASE_PRINT(WRITE_ERR_IO);
|
CASE_PRINT(WRITE_ERR_IO);
|
||||||
CASE_PRINT(WRITE_ERR_INTERRUPT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CASE_PRINT
|
#undef CASE_PRINT
|
||||||
|
@ -504,8 +504,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
|||||||
return read_num_bytes;
|
return read_num_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_size _write(Fs_vfs_handle &handle,
|
Write_result _write(Fs_vfs_handle &handle, file_size const seek_offset,
|
||||||
const char *buf, file_size count, file_size seek_offset)
|
const char *buf, file_size count, file_size &out_count)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* TODO
|
* TODO
|
||||||
@ -524,7 +524,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
|||||||
if (!source.ready_to_submit()) {
|
if (!source.ready_to_submit()) {
|
||||||
if (!handle.enqueued())
|
if (!handle.enqueued())
|
||||||
_congested_handles.enqueue(handle);
|
_congested_handles.enqueue(handle);
|
||||||
throw Insufficient_buffer();
|
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -537,15 +537,18 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
|||||||
memcpy(source.packet_content(packet_in), buf, (size_t)count);
|
memcpy(source.packet_content(packet_in), buf, (size_t)count);
|
||||||
|
|
||||||
_submit_packet(packet_in);
|
_submit_packet(packet_in);
|
||||||
} catch (::File_system::Session::Tx::Source::Packet_alloc_failed) {
|
}
|
||||||
|
catch (::File_system::Session::Tx::Source::Packet_alloc_failed) {
|
||||||
if (!handle.enqueued())
|
if (!handle.enqueued())
|
||||||
_congested_handles.enqueue(handle);
|
_congested_handles.enqueue(handle);
|
||||||
throw Insufficient_buffer();
|
return Write_result::WRITE_ERR_WOULD_BLOCK;
|
||||||
} catch (...) {
|
|
||||||
Genode::error("unhandled exception");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return count;
|
catch (...) {
|
||||||
|
Genode::error("unhandled exception");
|
||||||
|
return Write_result::WRITE_ERR_IO;
|
||||||
|
}
|
||||||
|
out_count = count;
|
||||||
|
return Write_result::WRITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handle_ack()
|
void _handle_ack()
|
||||||
@ -967,12 +970,11 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
|
|||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
Write_result write(Vfs_handle *vfs_handle, char const *buf,
|
Write_result write(Vfs_handle *vfs_handle, char const *buf,
|
||||||
file_size buf_size, file_size &out_count) override
|
file_size count, file_size &out_count) override
|
||||||
{
|
{
|
||||||
Fs_vfs_handle &handle = static_cast<Fs_vfs_handle &>(*vfs_handle);
|
Fs_vfs_handle &handle = static_cast<Fs_vfs_handle &>(*vfs_handle);
|
||||||
|
|
||||||
out_count = _write(handle, buf, buf_size, handle.seek());
|
return _write(handle, handle.seek(), buf, count, out_count);
|
||||||
return WRITE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool queue_read(Vfs_handle *vfs_handle, file_size count) override
|
bool queue_read(Vfs_handle *vfs_handle, file_size count) override
|
||||||
|
@ -408,25 +408,20 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
|||||||
seek_off_t write_pos)
|
seek_off_t write_pos)
|
||||||
{
|
{
|
||||||
file_size out_count = 0;
|
file_size out_count = 0;
|
||||||
try {
|
_handle.seek(_initial_write_seek_offset + write_pos);
|
||||||
_handle.seek(_initial_write_seek_offset + write_pos);
|
|
||||||
|
|
||||||
switch (_handle.fs().write(&_handle, src_ptr, length, out_count)) {
|
switch (_handle.fs().write(&_handle, src_ptr, length, out_count)) {
|
||||||
case Write_result::WRITE_ERR_AGAIN:
|
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
||||||
case Write_result::WRITE_ERR_WOULD_BLOCK:
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Write_result::WRITE_ERR_INVALID:
|
case Write_result::WRITE_ERR_INVALID:
|
||||||
case Write_result::WRITE_ERR_IO:
|
case Write_result::WRITE_ERR_IO:
|
||||||
case Write_result::WRITE_ERR_INTERRUPT:
|
_acknowledge_as_failure();
|
||||||
_acknowledge_as_failure();
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case Write_result::WRITE_OK:
|
case Write_result::WRITE_OK:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Vfs::File_io_service::Insufficient_buffer) { /* re-execute */ }
|
|
||||||
|
|
||||||
_modified = true;
|
_modified = true;
|
||||||
|
|
||||||
@ -452,14 +447,11 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
|||||||
|
|
||||||
void _execute_write_timestamp()
|
void _execute_write_timestamp()
|
||||||
{
|
{
|
||||||
try {
|
_packet.with_timestamp([&] (::File_system::Timestamp const time) {
|
||||||
_packet.with_timestamp([&] (::File_system::Timestamp const time) {
|
Vfs::Timestamp ts { .value = time.value };
|
||||||
Vfs::Timestamp ts { .value = time.value };
|
_handle.fs().update_modification_timestamp(&_handle, ts);
|
||||||
_handle.fs().update_modification_timestamp(&_handle, ts);
|
});
|
||||||
});
|
_acknowledge_as_success(0);
|
||||||
_acknowledge_as_success(0);
|
|
||||||
}
|
|
||||||
catch (Vfs::File_io_service::Insufficient_buffer) { }
|
|
||||||
|
|
||||||
_modified = true;
|
_modified = true;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ namespace Vfs_block {
|
|||||||
_handle.seek(base_offset + current_offset);
|
_handle.seek(base_offset + current_offset);
|
||||||
state = State::IN_PROGRESS;
|
state = State::IN_PROGRESS;
|
||||||
progress = true;
|
progress = true;
|
||||||
|
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case State::IN_PROGRESS:
|
case State::IN_PROGRESS:
|
||||||
{
|
{
|
||||||
@ -145,31 +146,24 @@ namespace Vfs_block {
|
|||||||
bool completed = false;
|
bool completed = false;
|
||||||
file_size out = 0;
|
file_size out = 0;
|
||||||
|
|
||||||
Result result = Result::WRITE_ERR_INVALID;
|
Result result = _handle.fs().write(&_handle,
|
||||||
try {
|
data + current_offset,
|
||||||
result = _handle.fs().write(&_handle,
|
current_count, out);
|
||||||
data + current_offset,
|
switch (result) {
|
||||||
current_count, out);
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
|
||||||
return progress;
|
return progress;
|
||||||
}
|
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_AGAIN
|
case Result::WRITE_OK:
|
||||||
|| result == Result::WRITE_ERR_INTERRUPT
|
|
||||||
|| result == Result::WRITE_ERR_WOULD_BLOCK) {
|
|
||||||
return progress;
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (result == Result::WRITE_OK) {
|
|
||||||
current_offset += out;
|
current_offset += out;
|
||||||
current_count -= out;
|
current_count -= out;
|
||||||
success = true;
|
success = true;
|
||||||
} else
|
break;
|
||||||
|
|
||||||
if ( result == Result::WRITE_ERR_IO
|
case Result::WRITE_ERR_IO:
|
||||||
|| result == Result::WRITE_ERR_INVALID) {
|
case Result::WRITE_ERR_INVALID:
|
||||||
success = false;
|
success = false;
|
||||||
completed = true;
|
completed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_count == 0 || completed) {
|
if (current_count == 0 || completed) {
|
||||||
|
@ -95,16 +95,12 @@ inline void assert_write(Vfs::File_io_service::Write_result r)
|
|||||||
typedef Vfs::File_io_service::Write_result Result;
|
typedef Vfs::File_io_service::Write_result Result;
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case Result::WRITE_OK: return;
|
case Result::WRITE_OK: return;
|
||||||
case Result::WRITE_ERR_AGAIN:
|
|
||||||
error("WRITE_ERR_AGAIN"); break;
|
|
||||||
case Result::WRITE_ERR_WOULD_BLOCK:
|
case Result::WRITE_ERR_WOULD_BLOCK:
|
||||||
error("WRITE_ERR_WOULD_BLOCK"); break;
|
error("WRITE_ERR_WOULD_BLOCK"); break;
|
||||||
case Result::WRITE_ERR_INVALID:
|
case Result::WRITE_ERR_INVALID:
|
||||||
error("WRITE_ERR_INVALID"); break;
|
error("WRITE_ERR_INVALID"); break;
|
||||||
case Result::WRITE_ERR_IO:
|
case Result::WRITE_ERR_IO:
|
||||||
error("WRITE_ERR_IO"); break;
|
error("WRITE_ERR_IO"); break;
|
||||||
case Result::WRITE_ERR_INTERRUPT:
|
|
||||||
error("WRITE_ERR_INTERRUPT"); break;
|
|
||||||
}
|
}
|
||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user