From e12cbfb9305f7bd2e2ee703f74fd9a6091a54764 Mon Sep 17 00:00:00 2001 From: Junjie Cao Date: Tue, 21 Apr 2026 04:13:15 +0800 Subject: [PATCH] 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 Reviewed-by: Peter Xu Link: https://lore.kernel.org/qemu-devel/20260420201317.30199-2-junjie.cao@intel.com Signed-off-by: Fabiano Rosas --- migration/qemu-file.c | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 9cf7dc3bd5..9dfb202203 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -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)