#define HANDLE_TO_INDEX(bs, handle) ((handle) ^ ((uint64_t)(intptr_t)bs))
#define INDEX_TO_HANDLE(bs, index) ((index) ^ ((uint64_t)(intptr_t)bs))
+static void nbd_recv_coroutines_enter_all(NbdClientSession *s)
+{
+ int i;
+
+ for (i = 0; i < MAX_NBD_REQUESTS; i++) {
+ if (s->recv_coroutine[i]) {
+ qemu_coroutine_enter(s->recv_coroutine[i], NULL);
+ }
+ }
+}
+
+static void nbd_teardown_connection(NbdClientSession *client)
+{
+ /* finish any pending coroutines */
+ shutdown(client->sock, 2);
+ nbd_recv_coroutines_enter_all(client);
+
+ qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
+ closesocket(client->sock);
+ client->sock = -1;
+}
+
static void nbd_reply_ready(void *opaque)
{
NbdClientSession *s = opaque;
}
fail:
- for (i = 0; i < MAX_NBD_REQUESTS; i++) {
- if (s->recv_coroutine[i]) {
- qemu_coroutine_enter(s->recv_coroutine[i], NULL);
- }
- }
+ nbd_teardown_connection(s);
}
static void nbd_restart_write(void *opaque)
int nb_sectors, QEMUIOVector *qiov,
int offset)
{
- struct nbd_request request;
+ struct nbd_request request = { .type = NBD_CMD_READ };
struct nbd_reply reply;
ssize_t ret;
- request.type = NBD_CMD_READ;
request.from = sector_num * 512;
request.len = nb_sectors * 512;
int nb_sectors, QEMUIOVector *qiov,
int offset)
{
- struct nbd_request request;
+ struct nbd_request request = { .type = NBD_CMD_WRITE };
struct nbd_reply reply;
ssize_t ret;
- request.type = NBD_CMD_WRITE;
if (!bdrv_enable_write_cache(client->bs) &&
(client->nbdflags & NBD_FLAG_SEND_FUA)) {
request.type |= NBD_CMD_FLAG_FUA;
int nbd_client_session_co_flush(NbdClientSession *client)
{
- struct nbd_request request;
+ struct nbd_request request = { .type = NBD_CMD_FLUSH };
struct nbd_reply reply;
ssize_t ret;
return 0;
}
- request.type = NBD_CMD_FLUSH;
if (client->nbdflags & NBD_FLAG_SEND_FUA) {
request.type |= NBD_CMD_FLAG_FUA;
}
int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
int nb_sectors)
{
- struct nbd_request request;
+ struct nbd_request request = { .type = NBD_CMD_TRIM };
struct nbd_reply reply;
ssize_t ret;
if (!(client->nbdflags & NBD_FLAG_SEND_TRIM)) {
return 0;
}
- request.type = NBD_CMD_TRIM;
request.from = sector_num * 512;
request.len = nb_sectors * 512;
}
-static void nbd_teardown_connection(NbdClientSession *client)
+void nbd_client_session_close(NbdClientSession *client)
{
- struct nbd_request request;
+ struct nbd_request request = {
+ .type = NBD_CMD_DISC,
+ .from = 0,
+ .len = 0
+ };
- request.type = NBD_CMD_DISC;
- request.from = 0;
- request.len = 0;
- nbd_send_request(client->sock, &request);
+ if (!client->bs) {
+ return;
+ }
+ if (client->sock == -1) {
+ return;
+ }
- qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
- closesocket(client->sock);
- client->sock = -1;
-}
+ nbd_send_request(client->sock, &request);
-void nbd_client_session_close(NbdClientSession *client)
-{
nbd_teardown_connection(client);
- g_free(client->export_name);
- client->export_name = NULL;
+ client->bs = NULL;
}
-int nbd_client_session_init(NbdClientSession *client,
- BlockDriverState *bs, int sock)
+int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
+ int sock, const char *export)
{
int ret;
/* NBD handshake */
+ logout("session init %s\n", export);
qemu_set_block(sock);
- ret = nbd_receive_negotiate(sock, client->export_name,
+ ret = nbd_receive_negotiate(sock, export,
&client->nbdflags, &client->size,
&client->blocksize);
if (ret < 0) {