提交 958c717d 编写于 作者: M Max Reitz 提交者: Stefan Hajnoczi

nbd: Drop nbd_can_read()

There is no variant of aio_set_fd_handler() like qemu_set_fd_handler2(),
so we cannot give a can_read() callback function. Instead, unregister
the nbd_read() function whenever we cannot read and re-register it as
soon as we can read again.

All this is hidden behind the functions nbd_set_handlers() (which
registers all handlers for the AIO context and file descriptor belonging
to the given client), nbd_unset_handlers() (which unregisters them) and
nbd_update_can_read() (which checks whether NBD can read for the given
client and acts accordingly).
Signed-off-by: NMax Reitz <mreitz@redhat.com>
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
上级 a780dea0
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "block/nbd.h" #include "block/nbd.h"
#include "block/block.h" #include "block/block.h"
#include "block/block_int.h"
#include "block/coroutine.h" #include "block/coroutine.h"
...@@ -107,6 +108,8 @@ struct NBDExport { ...@@ -107,6 +108,8 @@ struct NBDExport {
uint32_t nbdflags; uint32_t nbdflags;
QTAILQ_HEAD(, NBDClient) clients; QTAILQ_HEAD(, NBDClient) clients;
QTAILQ_ENTRY(NBDExport) next; QTAILQ_ENTRY(NBDExport) next;
AioContext *ctx;
}; };
static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
...@@ -123,6 +126,8 @@ struct NBDClient { ...@@ -123,6 +126,8 @@ struct NBDClient {
CoMutex send_lock; CoMutex send_lock;
Coroutine *send_coroutine; Coroutine *send_coroutine;
bool can_read;
QTAILQ_ENTRY(NBDClient) next; QTAILQ_ENTRY(NBDClient) next;
int nb_requests; int nb_requests;
bool closing; bool closing;
...@@ -130,6 +135,10 @@ struct NBDClient { ...@@ -130,6 +135,10 @@ struct NBDClient {
/* That's all folks */ /* That's all folks */
static void nbd_set_handlers(NBDClient *client);
static void nbd_unset_handlers(NBDClient *client);
static void nbd_update_can_read(NBDClient *client);
ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
{ {
size_t offset = 0; size_t offset = 0;
...@@ -862,7 +871,7 @@ void nbd_client_put(NBDClient *client) ...@@ -862,7 +871,7 @@ void nbd_client_put(NBDClient *client)
*/ */
assert(client->closing); assert(client->closing);
qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL); nbd_unset_handlers(client);
close(client->sock); close(client->sock);
client->sock = -1; client->sock = -1;
if (client->exp) { if (client->exp) {
...@@ -898,6 +907,7 @@ static NBDRequest *nbd_request_get(NBDClient *client) ...@@ -898,6 +907,7 @@ static NBDRequest *nbd_request_get(NBDClient *client)
assert(client->nb_requests <= MAX_NBD_REQUESTS - 1); assert(client->nb_requests <= MAX_NBD_REQUESTS - 1);
client->nb_requests++; client->nb_requests++;
nbd_update_can_read(client);
req = g_slice_new0(NBDRequest); req = g_slice_new0(NBDRequest);
nbd_client_get(client); nbd_client_get(client);
...@@ -914,9 +924,8 @@ static void nbd_request_put(NBDRequest *req) ...@@ -914,9 +924,8 @@ static void nbd_request_put(NBDRequest *req)
} }
g_slice_free(NBDRequest, req); g_slice_free(NBDRequest, req);
if (client->nb_requests-- == MAX_NBD_REQUESTS) { client->nb_requests--;
qemu_notify_event(); nbd_update_can_read(client);
}
nbd_client_put(client); nbd_client_put(client);
} }
...@@ -932,6 +941,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, ...@@ -932,6 +941,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
exp->nbdflags = nbdflags; exp->nbdflags = nbdflags;
exp->size = size == -1 ? bdrv_getlength(bs) : size; exp->size = size == -1 ? bdrv_getlength(bs) : size;
exp->close = close; exp->close = close;
exp->ctx = bdrv_get_aio_context(bs);
bdrv_ref(bs); bdrv_ref(bs);
return exp; return exp;
} }
...@@ -1023,10 +1033,6 @@ void nbd_export_close_all(void) ...@@ -1023,10 +1033,6 @@ void nbd_export_close_all(void)
} }
} }
static int nbd_can_read(void *opaque);
static void nbd_read(void *opaque);
static void nbd_restart_write(void *opaque);
static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply, static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
int len) int len)
{ {
...@@ -1035,9 +1041,8 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply, ...@@ -1035,9 +1041,8 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
ssize_t rc, ret; ssize_t rc, ret;
qemu_co_mutex_lock(&client->send_lock); 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(); client->send_coroutine = qemu_coroutine_self();
nbd_set_handlers(client);
if (!len) { if (!len) {
rc = nbd_send_reply(csock, reply); rc = nbd_send_reply(csock, reply);
...@@ -1054,7 +1059,7 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply, ...@@ -1054,7 +1059,7 @@ static ssize_t nbd_co_send_reply(NBDRequest *req, struct nbd_reply *reply,
} }
client->send_coroutine = NULL; client->send_coroutine = NULL;
qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client); nbd_set_handlers(client);
qemu_co_mutex_unlock(&client->send_lock); qemu_co_mutex_unlock(&client->send_lock);
return rc; return rc;
} }
...@@ -1067,6 +1072,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque ...@@ -1067,6 +1072,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque
ssize_t rc; ssize_t rc;
client->recv_coroutine = qemu_coroutine_self(); client->recv_coroutine = qemu_coroutine_self();
nbd_update_can_read(client);
rc = nbd_receive_request(csock, request); rc = nbd_receive_request(csock, request);
if (rc < 0) { if (rc < 0) {
if (rc != -EAGAIN) { if (rc != -EAGAIN) {
...@@ -1108,6 +1115,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque ...@@ -1108,6 +1115,8 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque
out: out:
client->recv_coroutine = NULL; client->recv_coroutine = NULL;
nbd_update_can_read(client);
return rc; return rc;
} }
...@@ -1259,13 +1268,6 @@ out: ...@@ -1259,13 +1268,6 @@ out:
nbd_client_close(client); nbd_client_close(client);
} }
static int nbd_can_read(void *opaque)
{
NBDClient *client = opaque;
return client->recv_coroutine || client->nb_requests < MAX_NBD_REQUESTS;
}
static void nbd_read(void *opaque) static void nbd_read(void *opaque)
{ {
NBDClient *client = opaque; NBDClient *client = opaque;
...@@ -1284,6 +1286,37 @@ static void nbd_restart_write(void *opaque) ...@@ -1284,6 +1286,37 @@ static void nbd_restart_write(void *opaque)
qemu_coroutine_enter(client->send_coroutine, NULL); qemu_coroutine_enter(client->send_coroutine, NULL);
} }
static void nbd_set_handlers(NBDClient *client)
{
if (client->exp && client->exp->ctx) {
aio_set_fd_handler(client->exp->ctx, client->sock,
client->can_read ? nbd_read : NULL,
client->send_coroutine ? nbd_restart_write : NULL,
client);
}
}
static void nbd_unset_handlers(NBDClient *client)
{
if (client->exp && client->exp->ctx) {
aio_set_fd_handler(client->exp->ctx, client->sock, NULL, NULL, NULL);
}
}
static void nbd_update_can_read(NBDClient *client)
{
bool can_read = client->recv_coroutine ||
client->nb_requests < MAX_NBD_REQUESTS;
if (can_read != client->can_read) {
client->can_read = can_read;
nbd_set_handlers(client);
/* There is no need to invoke aio_notify(), since aio_set_fd_handler()
* in nbd_set_handlers() will have taken care of that */
}
}
NBDClient *nbd_client_new(NBDExport *exp, int csock, NBDClient *nbd_client_new(NBDExport *exp, int csock,
void (*close)(NBDClient *)) void (*close)(NBDClient *))
{ {
...@@ -1292,13 +1325,14 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock, ...@@ -1292,13 +1325,14 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
client->refcount = 1; client->refcount = 1;
client->exp = exp; client->exp = exp;
client->sock = csock; client->sock = csock;
client->can_read = true;
if (nbd_send_negotiate(client)) { if (nbd_send_negotiate(client)) {
g_free(client); g_free(client);
return NULL; return NULL;
} }
client->close = close; client->close = close;
qemu_co_mutex_init(&client->send_lock); qemu_co_mutex_init(&client->send_lock);
qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client); nbd_set_handlers(client);
if (exp) { if (exp) {
QTAILQ_INSERT_TAIL(&exp->clients, client, next); QTAILQ_INSERT_TAIL(&exp->clients, client, next);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册