@samitouri / QOSamiQemu / commits / e12cbfb930

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>

Junjie Cao committed Apr 21, 2026 at 04:13 UTC e12cbfb9305f7bd2e2ee703f74fd9a6091a54764
1 file changed +3 -32
migration/qemu-file.c
+3 -32
@@ -535,28 +535,13 @@ void qemu_put_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
535 off_t pos)
536 {
537 Error *err = NULL;
538 - size_t ret;
538
539 if (f->last_error) {
540 return;
541 }
542
543 qemu_fflush(f);
545 - ret = qio_channel_pwrite(f->ioc, (char *)buf, buflen, pos, &err);
546 -
547 - if (err) {
548 - qemu_file_set_error_obj(f, -EIO, err);
549 - return;
550 - }
551 -
552 - if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
553 - qemu_file_set_error_obj(f, -EAGAIN, NULL);
554 - return;
555 - }
556 -
557 - if (ret != buflen) {
558 - error_setg(&err, "Partial write of size %zu, expected %zu", ret,
559 - buflen);
544 + if (qio_channel_pwrite_all(f->ioc, buf, buflen, pos, &err) < 0) {
545 qemu_file_set_error_obj(f, -EIO, err);
546 return;
547 }
@@ -569,31 +554,17 @@ size_t qemu_get_buffer_at(QEMUFile *f, const uint8_t *buf, size_t buflen,
554 off_t pos)
555 {
556 Error *err = NULL;
572 - size_t ret;
557
558 if (f->last_error) {
559 return 0;
560 }
561
578 - ret = qio_channel_pread(f->ioc, (char *)buf, buflen, pos, &err);
579 -
580 - if ((ssize_t)ret == -1 || err) {
562 + if (qio_channel_pread_all(f->ioc, (char *)buf, buflen, pos, &err) < 0) {
563 qemu_file_set_error_obj(f, -EIO, err);
564 return 0;
565 }
566
585 - if ((ssize_t)ret == QIO_CHANNEL_ERR_BLOCK) {
586 - qemu_file_set_error_obj(f, -EAGAIN, NULL);
587 - return 0;
588 - }
589 -
590 - if (ret != buflen) {
591 - error_setg(&err, "Partial read of size %zu, expected %zu", ret, buflen);
592 - qemu_file_set_error_obj(f, -EIO, err);
593 - return 0;
594 - }
595 -
596 - return ret;
567 + return buflen;
568 }
569
570 void qemu_set_offset(QEMUFile *f, off_t off, int whence)