static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) { QEMUFileBuffered *s = opaque; int offset = 0, error; ssize_t ret; DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); error = qemu_file_get_error(s->file); if (error) { DPRINTF("flush when error, bailing: %s\n", strerror(-error)); return error; } DPRINTF("unfreezing output\n"); s->freeze_output = 0; buffered_flush(s); while (!s->freeze_output && offset < size) { if (s->bytes_xfer > s->xfer_limit) { DPRINTF("transfer limit exceeded when putting\n"); break; } ret = s->put_buffer(s->opaque, buf + offset, size - offset); if (ret == -EAGAIN) { DPRINTF("backend not ready, freezing\n"); s->freeze_output = 1; break; } if (ret <= 0) { DPRINTF("error putting\n"); qemu_file_set_error(s->file, ret); offset = -EINVAL; break; } DPRINTF("put %zd byte(s)\n", ret); offset += ret; s->bytes_xfer += ret; } if (offset >= 0) { DPRINTF("buffering %d bytes\n", size - offset); buffered_append(s, buf + offset, size - offset); offset = size; } if (pos == 0 && size == 0) { DPRINTF("file is ready\n"); if (s->bytes_xfer <= s->xfer_limit) { DPRINTF("notifying client\n"); s->put_ready(s->opaque); } } return offset; }
static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size) { QEMUFileBuffered *s = opaque; int offset = 0; ssize_t ret; DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos); if (s->has_error) { DPRINTF("flush when error, bailing\n"); return -EINVAL; } DPRINTF("unfreezing output\n"); s->freeze_output = 0; buffered_flush(s); while (!s->freeze_output && offset < size) { if (s->bytes_xfer > s->xfer_limit) { DPRINTF("transfer limit exceeded when putting\n"); break; } ret = s->put_buffer(s->opaque, buf + offset, size - offset); if (ret == -EAGAIN) { DPRINTF("backend not ready, freezing\n"); s->freeze_output = 1; break; } if (ret <= 0) { DPRINTF("error putting\n"); s->has_error = 1; offset = -EINVAL; break; } DPRINTF("put %zd byte(s)\n", ret); offset += ret; s->bytes_xfer += ret; } if (offset >= 0) { DPRINTF("buffering %d bytes\n", size - offset); buffered_append(s, buf + offset, size - offset); offset = size; } return offset; }