From: Stefan Hajnoczi Date: Thu, 8 May 2014 14:34:43 +0000 (+0200) Subject: nbd: implement .bdrv_detach/attach_aio_context() X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=69447cd8f361dbb6c752bd18b15322d27493ca91;p=qmiga%2Fqemu.git nbd: implement .bdrv_detach/attach_aio_context() Drop the assumption that we're using the main AioContext. Convert qemu_aio_set_fd_handler() calls to aio_set_fd_handler(). The .bdrv_detach/attach_aio_context() interfaces also need to be implemented to move the socket fd handler from the old to the new AioContext. Acked-by: Paolo Bonzini Signed-off-by: Stefan Hajnoczi --- diff --git a/block/nbd-client.c b/block/nbd-client.c index 7d698cb619..6e1c97cad0 100644 --- a/block/nbd-client.c +++ b/block/nbd-client.c @@ -49,7 +49,7 @@ static void nbd_teardown_connection(NbdClientSession *client) shutdown(client->sock, 2); nbd_recv_coroutines_enter_all(client); - qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL); + nbd_client_session_detach_aio_context(client); closesocket(client->sock); client->sock = -1; } @@ -103,11 +103,14 @@ static int nbd_co_send_request(NbdClientSession *s, struct nbd_request *request, QEMUIOVector *qiov, int offset) { + AioContext *aio_context; 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); + aio_context = bdrv_get_aio_context(s->bs); + aio_set_fd_handler(aio_context, s->sock, + nbd_reply_ready, nbd_restart_write, s); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); @@ -126,7 +129,7 @@ static int nbd_co_send_request(NbdClientSession *s, } else { rc = nbd_send_request(s->sock, request); } - qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s); + aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, s); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; @@ -335,6 +338,19 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num, } +void nbd_client_session_detach_aio_context(NbdClientSession *client) +{ + aio_set_fd_handler(bdrv_get_aio_context(client->bs), client->sock, + NULL, NULL, NULL); +} + +void nbd_client_session_attach_aio_context(NbdClientSession *client, + AioContext *new_context) +{ + aio_set_fd_handler(new_context, client->sock, + nbd_reply_ready, NULL, client); +} + void nbd_client_session_close(NbdClientSession *client) { struct nbd_request request = { @@ -381,7 +397,7 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); - qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, client); + nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; diff --git a/block/nbd-client.h b/block/nbd-client.h index f2a63378bb..cd478f3a98 100644 --- a/block/nbd-client.h +++ b/block/nbd-client.h @@ -47,4 +47,8 @@ int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num, int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); +void nbd_client_session_detach_aio_context(NbdClientSession *client); +void nbd_client_session_attach_aio_context(NbdClientSession *client, + AioContext *new_context); + #endif /* NBD_CLIENT_H */ diff --git a/block/nbd.c b/block/nbd.c index 613f2581ae..4eda0958d7 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -323,46 +323,67 @@ static int64_t nbd_getlength(BlockDriverState *bs) return s->client.size; } +static void nbd_detach_aio_context(BlockDriverState *bs) +{ + BDRVNBDState *s = bs->opaque; + + nbd_client_session_detach_aio_context(&s->client); +} + +static void nbd_attach_aio_context(BlockDriverState *bs, + AioContext *new_context) +{ + BDRVNBDState *s = bs->opaque; + + nbd_client_session_attach_aio_context(&s->client, new_context); +} + static BlockDriver bdrv_nbd = { - .format_name = "nbd", - .protocol_name = "nbd", - .instance_size = sizeof(BDRVNBDState), - .bdrv_parse_filename = nbd_parse_filename, - .bdrv_file_open = nbd_open, - .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_close = nbd_close, - .bdrv_co_flush_to_os = nbd_co_flush, - .bdrv_co_discard = nbd_co_discard, - .bdrv_getlength = nbd_getlength, + .format_name = "nbd", + .protocol_name = "nbd", + .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, + .bdrv_file_open = nbd_open, + .bdrv_co_readv = nbd_co_readv, + .bdrv_co_writev = nbd_co_writev, + .bdrv_close = nbd_close, + .bdrv_co_flush_to_os = nbd_co_flush, + .bdrv_co_discard = nbd_co_discard, + .bdrv_getlength = nbd_getlength, + .bdrv_detach_aio_context = nbd_detach_aio_context, + .bdrv_attach_aio_context = nbd_attach_aio_context, }; static BlockDriver bdrv_nbd_tcp = { - .format_name = "nbd", - .protocol_name = "nbd+tcp", - .instance_size = sizeof(BDRVNBDState), - .bdrv_parse_filename = nbd_parse_filename, - .bdrv_file_open = nbd_open, - .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_close = nbd_close, - .bdrv_co_flush_to_os = nbd_co_flush, - .bdrv_co_discard = nbd_co_discard, - .bdrv_getlength = nbd_getlength, + .format_name = "nbd", + .protocol_name = "nbd+tcp", + .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, + .bdrv_file_open = nbd_open, + .bdrv_co_readv = nbd_co_readv, + .bdrv_co_writev = nbd_co_writev, + .bdrv_close = nbd_close, + .bdrv_co_flush_to_os = nbd_co_flush, + .bdrv_co_discard = nbd_co_discard, + .bdrv_getlength = nbd_getlength, + .bdrv_detach_aio_context = nbd_detach_aio_context, + .bdrv_attach_aio_context = nbd_attach_aio_context, }; static BlockDriver bdrv_nbd_unix = { - .format_name = "nbd", - .protocol_name = "nbd+unix", - .instance_size = sizeof(BDRVNBDState), - .bdrv_parse_filename = nbd_parse_filename, - .bdrv_file_open = nbd_open, - .bdrv_co_readv = nbd_co_readv, - .bdrv_co_writev = nbd_co_writev, - .bdrv_close = nbd_close, - .bdrv_co_flush_to_os = nbd_co_flush, - .bdrv_co_discard = nbd_co_discard, - .bdrv_getlength = nbd_getlength, + .format_name = "nbd", + .protocol_name = "nbd+unix", + .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, + .bdrv_file_open = nbd_open, + .bdrv_co_readv = nbd_co_readv, + .bdrv_co_writev = nbd_co_writev, + .bdrv_close = nbd_close, + .bdrv_co_flush_to_os = nbd_co_flush, + .bdrv_co_discard = nbd_co_discard, + .bdrv_getlength = nbd_getlength, + .bdrv_detach_aio_context = nbd_detach_aio_context, + .bdrv_attach_aio_context = nbd_attach_aio_context, }; static void bdrv_nbd_init(void)