static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply, int len) { NBDClient *client = req->client; int csock = client->sock; ssize_t rc, ret; qemu_co_mutex_lock(&client->send_lock); qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, nbd_restart_write, client); client->send_coroutine = qemu_coroutine_self(); if (!len) { rc = nbd_send_reply(csock, reply); } else { socket_set_cork(csock, 1); rc = nbd_send_reply(csock, reply); if (rc >= 0) { ret = qemu_co_send(csock, req->data, len); if (ret != len) { rc = -EIO; } } socket_set_cork(csock, 0); } client->send_coroutine = NULL; qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client); qemu_co_mutex_unlock(&client->send_lock); return rc; }
static int nbd_co_send_request(NbdClientSession *s, struct nbd_request *request, QEMUIOVector *qiov, int offset) { int rc, ret; qemu_co_mutex_lock(&s->send_mutex); s->send_coroutine = qemu_coroutine_self(); qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); } rc = nbd_send_request(s->sock, request); if (rc >= 0) { ret = qemu_co_sendv(s->sock, qiov->iov, qiov->niov, offset, request->len); if (ret != request->len) { rc = -EIO; } } if (!s->is_unix) { socket_set_cork(s->sock, 0); } } else { rc = nbd_send_request(s->sock, request); } qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; }
static int nbd_co_send_request(BlockDriverState *bs, struct nbd_request *request, QEMUIOVector *qiov, int offset) { NbdClientSession *s = nbd_get_client_session(bs); AioContext *aio_context; int rc, ret, i; qemu_co_mutex_lock(&s->send_mutex); for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); s->send_coroutine = qemu_coroutine_self(); aio_context = bdrv_get_aio_context(bs); aio_set_fd_handler(aio_context, s->sock, false, nbd_reply_ready, nbd_restart_write, bs); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); } rc = nbd_send_request(s->sock, request); if (rc >= 0) { ret = qemu_co_sendv(s->sock, qiov->iov, qiov->niov, offset, request->len); if (ret != request->len) { rc = -EIO; } } if (!s->is_unix) { socket_set_cork(s->sock, 0); } } else { rc = nbd_send_request(s->sock, request); } aio_set_fd_handler(aio_context, s->sock, false, nbd_reply_ready, NULL, bs); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; }
static void qio_channel_socket_set_cork(QIOChannel *ioc, bool enabled) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); int v = enabled ? 1 : 0; socket_set_cork(sioc->fd, v); }