From a7d80288808ba34439889fbafef902a5a593d784 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Juan Quintela Date: Wed, 7 Jan 2015 16:45:13 -0600 Subject: [CHANGE 09/10] buffered_flush: return errors To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Juan Quintela Message-id: <1420649114-17435-10-git-send-email-quintela@redhat.com> Patchwork-id: 63166 O-Subject: [PATCH qemu-kvm RHEL6.7 09/10] buffered_flush: return errors Bugzilla: 970103 RH-Acked-by: Laszlo Ersek RH-Acked-by: Paolo Bonzini RH-Acked-by: Dr. David Alan Gilbert (git) If there happened an error in buffered_flush(), it was not propagated right away, we just did a wait_for_unfreeze() first. Move to check for error first. Once there, if we found an error doing buffered_flush() (or had an error sooner given by qemu_file_get_error()), return that error on buffered_close(). Don't exit on buffered_flush() error on rate_tick. We could be waiting for the notification somewhere else, too fragile for changes at this time. Signed-off-by: Juan Quintela --- buffered_file.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) Signed-off-by: Jeff E. Nelson --- buffered_file.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/buffered_file.c b/buffered_file.c index 2fa13cd..92d4fa7 100644 --- a/buffered_file.c +++ b/buffered_file.c @@ -69,7 +69,7 @@ static void buffered_append(QEMUFileBuffered *s, s->buffer_size += size; } -static void buffered_flush(QEMUFileBuffered *s) +static int buffered_flush(QEMUFileBuffered *s) { size_t offset = 0; int error; @@ -77,7 +77,7 @@ static void buffered_flush(QEMUFileBuffered *s) error = qemu_file_get_error(s->file); if (error != 0) { DPRINTF("flush when error, bailing: %s\n", strerror(-error)); - return; + return error; } DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size); @@ -96,6 +96,7 @@ static void buffered_flush(QEMUFileBuffered *s) if (ret <= 0) { DPRINTF("error flushing data, %zd\n", ret); qemu_file_set_error(s->file, ret); + error = ret; break; } else { DPRINTF("flushed %zd byte(s)\n", ret); @@ -108,6 +109,7 @@ static void buffered_flush(QEMUFileBuffered *s) memmove(s->buffer, s->buffer + offset, s->buffer_size - offset); s->buffer_size -= offset; } + return error; } static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) @@ -127,7 +129,11 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in DPRINTF("unfreezing output\n"); s->freeze_output = 0; - buffered_flush(s); + error = buffered_flush(s); + if (error) { + DPRINTF("error while flushing, bailing: %s\n", strerror(-error)); + return error; + } while (!s->freeze_output && offset < size) { if (s->bytes_xfer > s->xfer_limit) { @@ -174,16 +180,19 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in static int buffered_close(void *opaque) { QEMUFileBuffered *s = opaque; - int ret; + int ret, error; DPRINTF("closing\n"); - while (!qemu_file_get_error(s->file) && s->buffer_size) { - buffered_flush(s); + while (!(error = qemu_file_get_error(s->file)) && s->buffer_size) { + error = buffered_flush(s); + if (error != 0) { + DPRINTF("error while flushing, bailing: %s\n", strerror(-error)); + break; + } if (s->freeze_output) s->wait_for_unfreeze(s->opaque); } - ret = s->close(s->opaque); qemu_del_timer(s->timer); @@ -191,6 +200,10 @@ static int buffered_close(void *opaque) qemu_free(s->buffer); qemu_free(s); + if (error) { + return error; + } + return ret; } @@ -256,7 +269,15 @@ static void buffered_rate_tick(void *opaque) s->bytes_xfer = 0; buffered_flush(s); +/* I am not sure this change is safe. We could be waiting for the + put_ready notification in a different IO handler, just leave + things like this for now. + if (buffered_flush(s) < 0) { + DPRINTF("error while flushing, bailing: %s\n", strerror(-error)); + return; + } +*/ /* Add some checks around this */ s->put_ready(s->opaque); } -- 2.1.0