mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
migration/qemu-file: switch buffer_at functions to positioned I/O _all helpers
qemu_put_buffer_at() and qemu_get_buffer_at() have the same pattern as
the bug fixed in multifd_file_recv_data(): the ssize_t return value from
the channel layer is stored in a size_t variable, and a short transfer
would be mishandled rather than retried.
Switch to qio_channel_pwrite_all() / qio_channel_pread_all() which
handle short transfers internally and make the code more robust and
consistent with the rest of the positioned I/O call sites.
Fixes: 7f5b50a401 ("migration/qemu-file: add utility methods for working with seekable channels")
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20260420201317.30199-2-junjie.cao@intel.com
Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
committed by
Fabiano Rosas
parent
ac270baaef
commit
e12cbfb930
@@ -535,28 +535,13 @@ void qemu_put_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
|
||||
off_t pos)
|
||||
{
|
||||
Error *err = NULL;
|
||||
size_t ret;
|
||||
|
||||
if (f->last_error) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_fflush(f);
|
||||
ret = qio_channel_pwrite(f->ioc, (char *)buf, buflen, pos, &err);
|
||||
|
||||
if (err) {
|
||||
qemu_file_set_error_obj(f, -EIO, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
|
||||
qemu_file_set_error_obj(f, -EAGAIN, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret != buflen) {
|
||||
error_setg(&err, "Partial write of size %zu, expected %zu", ret,
|
||||
buflen);
|
||||
if (qio_channel_pwrite_all(f->ioc, buf, buflen, pos, &err) < 0) {
|
||||
qemu_file_set_error_obj(f, -EIO, err);
|
||||
return;
|
||||
}
|
||||
@@ -569,31 +554,17 @@ size_t qemu_get_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
|
||||
off_t pos)
|
||||
{
|
||||
Error *err = NULL;
|
||||
size_t ret;
|
||||
|
||||
if (f->last_error) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = qio_channel_pread(f->ioc, (char *)buf, buflen, pos, &err);
|
||||
|
||||
if ((ssize_t)ret == -1 || err) {
|
||||
if (qio_channel_pread_all(f->ioc, (char *)buf, buflen, pos, &err) < 0) {
|
||||
qemu_file_set_error_obj(f, -EIO, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
|
||||
qemu_file_set_error_obj(f, -EAGAIN, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret != buflen) {
|
||||
error_setg(&err, "Partial read of size %zu, expected %zu", ret, buflen);
|
||||
qemu_file_set_error_obj(f, -EIO, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return buflen;
|
||||
}
|
||||
|
||||
void qemu_set_offset(QEMUFile *f, off_t off, int whence)
|
||||
|
||||
Reference in New Issue
Block a user