nfs: do not use aio_context_acquire/release
Now that all bottom halves and callbacks take care of taking the AioContext lock, we can migrate some users away from it and to a specific QemuMutex or CoMutex. Protect libnfs calls with a QemuMutex. Callbacks are invoked using bottom halves, so we don't even have to drop it around callback invocations. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 20170222180725.28611-3-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
ba3186c4e4
commit
37d1e4d9bf
23
block/nfs.c
23
block/nfs.c
|
@ -54,6 +54,7 @@ typedef struct NFSClient {
|
||||||
int events;
|
int events;
|
||||||
bool has_zero_init;
|
bool has_zero_init;
|
||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
|
QemuMutex mutex;
|
||||||
blkcnt_t st_blocks;
|
blkcnt_t st_blocks;
|
||||||
bool cache_used;
|
bool cache_used;
|
||||||
NFSServer *server;
|
NFSServer *server;
|
||||||
|
@ -191,6 +192,7 @@ static void nfs_parse_filename(const char *filename, QDict *options,
|
||||||
static void nfs_process_read(void *arg);
|
static void nfs_process_read(void *arg);
|
||||||
static void nfs_process_write(void *arg);
|
static void nfs_process_write(void *arg);
|
||||||
|
|
||||||
|
/* Called with QemuMutex held. */
|
||||||
static void nfs_set_events(NFSClient *client)
|
static void nfs_set_events(NFSClient *client)
|
||||||
{
|
{
|
||||||
int ev = nfs_which_events(client->context);
|
int ev = nfs_which_events(client->context);
|
||||||
|
@ -209,20 +211,20 @@ static void nfs_process_read(void *arg)
|
||||||
{
|
{
|
||||||
NFSClient *client = arg;
|
NFSClient *client = arg;
|
||||||
|
|
||||||
aio_context_acquire(client->aio_context);
|
qemu_mutex_lock(&client->mutex);
|
||||||
nfs_service(client->context, POLLIN);
|
nfs_service(client->context, POLLIN);
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
aio_context_release(client->aio_context);
|
qemu_mutex_unlock(&client->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_process_write(void *arg)
|
static void nfs_process_write(void *arg)
|
||||||
{
|
{
|
||||||
NFSClient *client = arg;
|
NFSClient *client = arg;
|
||||||
|
|
||||||
aio_context_acquire(client->aio_context);
|
qemu_mutex_lock(&client->mutex);
|
||||||
nfs_service(client->context, POLLOUT);
|
nfs_service(client->context, POLLOUT);
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
aio_context_release(client->aio_context);
|
qemu_mutex_unlock(&client->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
|
static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
|
||||||
|
@ -242,6 +244,7 @@ static void nfs_co_generic_bh_cb(void *opaque)
|
||||||
aio_co_wake(task->co);
|
aio_co_wake(task->co);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called (via nfs_service) with QemuMutex held. */
|
||||||
static void
|
static void
|
||||||
nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
void *private_data)
|
void *private_data)
|
||||||
|
@ -273,12 +276,15 @@ static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
|
||||||
nfs_co_init_task(bs, &task);
|
nfs_co_init_task(bs, &task);
|
||||||
task.iov = iov;
|
task.iov = iov;
|
||||||
|
|
||||||
|
qemu_mutex_lock(&client->mutex);
|
||||||
if (nfs_pread_async(client->context, client->fh,
|
if (nfs_pread_async(client->context, client->fh,
|
||||||
offset, bytes, nfs_co_generic_cb, &task) != 0) {
|
offset, bytes, nfs_co_generic_cb, &task) != 0) {
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
while (!task.complete) {
|
while (!task.complete) {
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
}
|
}
|
||||||
|
@ -317,9 +323,11 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||||
buf = iov->iov[0].iov_base;
|
buf = iov->iov[0].iov_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemu_mutex_lock(&client->mutex);
|
||||||
if (nfs_pwrite_async(client->context, client->fh,
|
if (nfs_pwrite_async(client->context, client->fh,
|
||||||
offset, bytes, buf,
|
offset, bytes, buf,
|
||||||
nfs_co_generic_cb, &task) != 0) {
|
nfs_co_generic_cb, &task) != 0) {
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
if (my_buffer) {
|
if (my_buffer) {
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
}
|
}
|
||||||
|
@ -327,6 +335,7 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
while (!task.complete) {
|
while (!task.complete) {
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
}
|
}
|
||||||
|
@ -349,12 +358,15 @@ static int coroutine_fn nfs_co_flush(BlockDriverState *bs)
|
||||||
|
|
||||||
nfs_co_init_task(bs, &task);
|
nfs_co_init_task(bs, &task);
|
||||||
|
|
||||||
|
qemu_mutex_lock(&client->mutex);
|
||||||
if (nfs_fsync_async(client->context, client->fh, nfs_co_generic_cb,
|
if (nfs_fsync_async(client->context, client->fh, nfs_co_generic_cb,
|
||||||
&task) != 0) {
|
&task) != 0) {
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
|
qemu_mutex_unlock(&client->mutex);
|
||||||
while (!task.complete) {
|
while (!task.complete) {
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
}
|
}
|
||||||
|
@ -440,6 +452,7 @@ static void nfs_file_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
NFSClient *client = bs->opaque;
|
NFSClient *client = bs->opaque;
|
||||||
nfs_client_close(client);
|
nfs_client_close(client);
|
||||||
|
qemu_mutex_destroy(&client->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NFSServer *nfs_config(QDict *options, Error **errp)
|
static NFSServer *nfs_config(QDict *options, Error **errp)
|
||||||
|
@ -647,6 +660,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
qemu_mutex_init(&client->mutex);
|
||||||
bs->total_sectors = ret;
|
bs->total_sectors = ret;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -702,6 +716,7 @@ static int nfs_has_zero_init(BlockDriverState *bs)
|
||||||
return client->has_zero_init;
|
return client->has_zero_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called (via nfs_service) with QemuMutex held. */
|
||||||
static void
|
static void
|
||||||
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
|
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
void *private_data)
|
void *private_data)
|
||||||
|
|
Loading…
Reference in New Issue