static int nbd_co_send_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *qiov) { NBDClientSession *s = nbd_get_client_session(bs); int rc, ret, 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->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } g_assert(qemu_in_coroutine()); assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); if (!s->ioc) { qemu_co_mutex_unlock(&s->send_mutex); return -EPIPE; } if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); if (rc >= 0) { ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len, false, NULL); if (ret != request->len) { rc = -EIO; } } qio_channel_set_cork(s->ioc, false); } else { rc = nbd_send_request(s->ioc, request); } qemu_co_mutex_unlock(&s->send_mutex); return rc; }