Add write completion loop to VFS server and libc
Loop at the VFS server and libc VFS plugin on partial writes. This implies that the VFS server will not process successive packets for an open node until a write packet has been processed completely. The libc will now supspend and reissue write requests to the VFS until the write has been submitted completely. Ref #2303 Fix #2971
This commit is contained in:
parent
f6d22088f2
commit
efe39ab077
|
@ -445,7 +445,7 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
|||
|
||||
Vfs::Vfs_handle *handle;
|
||||
void const *buf;
|
||||
::size_t count;
|
||||
::size_t const count;
|
||||
Vfs::file_size &out_count;
|
||||
Result &out_result;
|
||||
|
||||
|
@ -458,14 +458,16 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
|||
|
||||
bool suspend() override
|
||||
{
|
||||
Vfs::file_size out = 0;
|
||||
try {
|
||||
out_result = VFS_THREAD_SAFE(handle->fs().write(handle, (char const *)buf,
|
||||
count, out_count));
|
||||
retry = false;
|
||||
out_result = VFS_THREAD_SAFE(handle->fs().write(handle, (char const *)buf+out_count,
|
||||
count - out_count, out));
|
||||
} catch (Vfs::File_io_service::Insufficient_buffer) {
|
||||
retry = true;
|
||||
out_result = Result::WRITE_OK;
|
||||
}
|
||||
|
||||
out_count += out;
|
||||
retry = (out_result == Result::WRITE_OK) && (out_count < count);
|
||||
return retry;
|
||||
}
|
||||
} check(handle, buf, count, out_count, out_result);
|
||||
|
|
|
@ -251,6 +251,8 @@ class Vfs_server::Io_node : public Vfs_server::Node,
|
|||
if (result == Write_result::WRITE_OK) {
|
||||
mark_as_updated();
|
||||
_packet.succeeded(true);
|
||||
} else {
|
||||
_packet.succeeded(false);
|
||||
}
|
||||
}
|
||||
catch (Vfs::File_io_service::Insufficient_buffer)
|
||||
|
@ -609,6 +611,8 @@ class Vfs_server::File : public Io_node
|
|||
|
||||
char const *_leaf_path = nullptr; /* offset pointer to Node::_path */
|
||||
|
||||
file_size _write_offset { 0 };
|
||||
|
||||
inline
|
||||
seek_off_t seek_tail(file_size count)
|
||||
{
|
||||
|
@ -648,9 +652,15 @@ class Vfs_server::File : public Io_node
|
|||
if (seek_offset == (seek_off_t)SEEK_TAIL)
|
||||
seek_offset = seek_tail(count);
|
||||
|
||||
bool result = _vfs_write(_stream.packet_content(_packet),
|
||||
count, seek_offset, out_count);
|
||||
bool result = _vfs_write(_stream.packet_content(_packet)+_write_offset,
|
||||
count-_write_offset, seek_offset, out_count);
|
||||
if (result) {
|
||||
/* loop until the write completes or produces an error */
|
||||
if (_packet.succeeded() && ((out_count+_write_offset) < count)) {
|
||||
_write_offset += out_count;
|
||||
return false;
|
||||
}
|
||||
_write_offset = 0;
|
||||
_ack_packet(out_count);
|
||||
if (out_count > 0) {
|
||||
mark_as_updated();
|
||||
|
|
Loading…
Reference in New Issue
Block a user