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:
Junjie Cao
2026-04-21 04:13:15 +08:00
committed by Fabiano Rosas
parent ac270baaef
commit e12cbfb930

View File

@@ -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)