Commit 471799d1 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi
Browse files

nfs: implement .bdrv_detach/attach_aio_context()



Drop the assumption that we're using the main AioContext.  The following
functions need to be converted:
 * qemu_bh_new() -> aio_bh_new()
 * qemu_aio_set_fd_handler() -> aio_set_fd_handler()
 * qemu_aio_wait() -> aio_poll()

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the fd handler from the old to the new AioContext.

Cc: Peter Lieven <pl@kamp.de>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: default avatarPeter Lieven <pl@kamp.de>
parent 69447cd8
Loading
Loading
Loading
Loading
+57 −24
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ typedef struct NFSClient {
    struct nfsfh *fh;
    int events;
    bool has_zero_init;
    AioContext *aio_context;
} NFSClient;

typedef struct NFSRPC {
@@ -49,6 +50,7 @@ typedef struct NFSRPC {
    struct stat *st;
    Coroutine *co;
    QEMUBH *bh;
    NFSClient *client;
} NFSRPC;

static void nfs_process_read(void *arg);
@@ -58,7 +60,8 @@ static void nfs_set_events(NFSClient *client)
{
    int ev = nfs_which_events(client->context);
    if (ev != client->events) {
        qemu_aio_set_fd_handler(nfs_get_fd(client->context),
        aio_set_fd_handler(client->aio_context,
                           nfs_get_fd(client->context),
                           (ev & POLLIN) ? nfs_process_read : NULL,
                           (ev & POLLOUT) ? nfs_process_write : NULL,
                           client);
@@ -85,6 +88,7 @@ static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
{
    *task = (NFSRPC) {
        .co             = qemu_coroutine_self(),
        .client         = client,
    };
}

@@ -116,7 +120,8 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
        error_report("NFS Error: %s", nfs_get_error(nfs));
    }
    if (task->co) {
        task->bh = qemu_bh_new(nfs_co_generic_bh_cb, task);
        task->bh = aio_bh_new(task->client->aio_context,
                              nfs_co_generic_bh_cb, task);
        qemu_bh_schedule(task->bh);
    }
}
@@ -224,13 +229,34 @@ static QemuOptsList runtime_opts = {
    },
};

static void nfs_detach_aio_context(BlockDriverState *bs)
{
    NFSClient *client = bs->opaque;

    aio_set_fd_handler(client->aio_context,
                       nfs_get_fd(client->context),
                       NULL, NULL, NULL);
    client->events = 0;
}

static void nfs_attach_aio_context(BlockDriverState *bs,
                                   AioContext *new_context)
{
    NFSClient *client = bs->opaque;

    client->aio_context = new_context;
    nfs_set_events(client);
}

static void nfs_client_close(NFSClient *client)
{
    if (client->context) {
        if (client->fh) {
            nfs_close(client->context, client->fh);
        }
        qemu_aio_set_fd_handler(nfs_get_fd(client->context), NULL, NULL, NULL);
        aio_set_fd_handler(client->aio_context,
                           nfs_get_fd(client->context),
                           NULL, NULL, NULL);
        nfs_destroy_context(client->context);
    }
    memset(client, 0, sizeof(NFSClient));
@@ -345,6 +371,8 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
    QemuOpts *opts;
    Error *local_err = NULL;

    client->aio_context = bdrv_get_aio_context(bs);

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
@@ -368,6 +396,8 @@ static int nfs_file_create(const char *url, QEMUOptionParameter *options,
    int64_t total_size = 0;
    NFSClient *client = g_malloc0(sizeof(NFSClient));

    client->aio_context = qemu_get_aio_context();

    /* Read out options */
    while (options && options->name) {
        if (!strcmp(options->name, "size")) {
@@ -407,7 +437,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)

    while (!task.complete) {
        nfs_set_events(client);
        qemu_aio_wait();
        aio_poll(client->aio_context, true);
    }

    return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
@@ -436,6 +466,9 @@ static BlockDriver bdrv_nfs = {
    .bdrv_co_readv                  = nfs_co_readv,
    .bdrv_co_writev                 = nfs_co_writev,
    .bdrv_co_flush_to_disk          = nfs_co_flush,

    .bdrv_detach_aio_context        = nfs_detach_aio_context,
    .bdrv_attach_aio_context        = nfs_attach_aio_context,
};

static void nfs_block_init(void)