ssize_t qio_channel_write(QIOChannel *ioc, const char *buf, size_t buflen, Error **errp) { struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; return qio_channel_writev_full(ioc, &iov, 1, NULL, 0, errp); } int qio_channel_read_all_eof(QIOChannel *ioc, char *buf, size_t buflen, Error **errp) { struct iovec iov = { .iov_base = buf, .iov_len = buflen }; return qio_channel_readv_all_eof(ioc, &iov, 1, errp); } int qio_channel_read_all(QIOChannel *ioc, char *buf, size_t buflen, Error **errp) { struct iovec iov = { .iov_base = buf, .iov_len = buflen }; return qio_channel_readv_all(ioc, &iov, 1, errp); } int qio_channel_write_all(QIOChannel *ioc, const char *buf, size_t buflen, Error **errp) { struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; return qio_channel_writev_all(ioc, &iov, 1, errp); } int qio_channel_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) { QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); return klass->io_set_blocking(ioc, enabled, errp); } int qio_channel_close(QIOChannel *ioc, Error **errp) { QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); return klass->io_close(ioc, errp); }
/* This thread sends all data using iovecs */ static gpointer test_io_thread_writer(gpointer opaque) { QIOChannelTest *data = opaque; qio_channel_set_blocking(data->src, data->blocking, NULL); qio_channel_writev_all(data->src, data->inputv, data->niov, &data->writeerr); return NULL; }
static int nbd_co_send_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *qiov) { NBDClientSession *s = nbd_get_client_session(bs); int rc, i; qemu_co_mutex_lock(&s->send_mutex); while (s->in_flight == MAX_NBD_REQUESTS) { qemu_co_queue_wait(&s->free_sema, &s->send_mutex); } s->in_flight++; for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->requests[i].coroutine == NULL) { break; } } g_assert(qemu_in_coroutine()); assert(i < MAX_NBD_REQUESTS); s->requests[i].coroutine = qemu_coroutine_self(); s->requests[i].receiving = false; request->handle = INDEX_TO_HANDLE(s, i); if (s->quit) { rc = -EIO; goto err; } if (!s->ioc) { rc = -EPIPE; goto err; } if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); if (rc >= 0 && !s->quit) { assert(request->len == iov_size(qiov->iov, qiov->niov)); if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { rc = -EIO; } } qio_channel_set_cork(s->ioc, false); } else { rc = nbd_send_request(s->ioc, request); } err: if (rc < 0) { s->quit = true; s->requests[i].coroutine = NULL; s->in_flight--; qemu_co_queue_next(&s->free_sema); } qemu_co_mutex_unlock(&s->send_mutex); return rc; }