mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
nfs: use BDRV_POLL_WHILE
This will make it possible to use nfs_get_allocated_file_size on a file that is not in the main AioContext. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <1477565348-5458-10-git-send-email-pbonzini@redhat.com> Signed-off-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
parent
aa92d6c460
commit
d746427aaf
1 changed files with 28 additions and 18 deletions
46
block/nfs.c
46
block/nfs.c
|
@ -52,6 +52,7 @@ typedef struct NFSClient {
|
||||||
} NFSClient;
|
} NFSClient;
|
||||||
|
|
||||||
typedef struct NFSRPC {
|
typedef struct NFSRPC {
|
||||||
|
BlockDriverState *bs;
|
||||||
int ret;
|
int ret;
|
||||||
int complete;
|
int complete;
|
||||||
QEMUIOVector *iov;
|
QEMUIOVector *iov;
|
||||||
|
@ -90,11 +91,12 @@ static void nfs_process_write(void *arg)
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
|
static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
|
||||||
{
|
{
|
||||||
*task = (NFSRPC) {
|
*task = (NFSRPC) {
|
||||||
.co = qemu_coroutine_self(),
|
.co = qemu_coroutine_self(),
|
||||||
.client = client,
|
.bs = bs,
|
||||||
|
.client = bs->opaque,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
{
|
{
|
||||||
NFSRPC *task = private_data;
|
NFSRPC *task = private_data;
|
||||||
task->ret = ret;
|
task->ret = ret;
|
||||||
|
assert(!task->st);
|
||||||
if (task->ret > 0 && task->iov) {
|
if (task->ret > 0 && task->iov) {
|
||||||
if (task->ret <= task->iov->size) {
|
if (task->ret <= task->iov->size) {
|
||||||
qemu_iovec_from_buf(task->iov, 0, data, task->ret);
|
qemu_iovec_from_buf(task->iov, 0, data, task->ret);
|
||||||
|
@ -118,18 +121,11 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
task->ret = -EIO;
|
task->ret = -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (task->ret == 0 && task->st) {
|
|
||||||
memcpy(task->st, data, sizeof(struct stat));
|
|
||||||
}
|
|
||||||
if (task->ret < 0) {
|
if (task->ret < 0) {
|
||||||
error_report("NFS Error: %s", nfs_get_error(nfs));
|
error_report("NFS Error: %s", nfs_get_error(nfs));
|
||||||
}
|
}
|
||||||
if (task->co) {
|
aio_bh_schedule_oneshot(task->client->aio_context,
|
||||||
aio_bh_schedule_oneshot(task->client->aio_context,
|
nfs_co_generic_bh_cb, task);
|
||||||
nfs_co_generic_bh_cb, task);
|
|
||||||
} else {
|
|
||||||
task->complete = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
|
static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
|
||||||
|
@ -139,7 +135,7 @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
|
||||||
NFSClient *client = bs->opaque;
|
NFSClient *client = bs->opaque;
|
||||||
NFSRPC task;
|
NFSRPC task;
|
||||||
|
|
||||||
nfs_co_init_task(client, &task);
|
nfs_co_init_task(bs, &task);
|
||||||
task.iov = iov;
|
task.iov = iov;
|
||||||
|
|
||||||
if (nfs_pread_async(client->context, client->fh,
|
if (nfs_pread_async(client->context, client->fh,
|
||||||
|
@ -174,7 +170,7 @@ static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
|
||||||
NFSRPC task;
|
NFSRPC task;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
nfs_co_init_task(client, &task);
|
nfs_co_init_task(bs, &task);
|
||||||
|
|
||||||
buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE);
|
buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE);
|
||||||
if (nb_sectors && buf == NULL) {
|
if (nb_sectors && buf == NULL) {
|
||||||
|
@ -210,7 +206,7 @@ static int coroutine_fn nfs_co_flush(BlockDriverState *bs)
|
||||||
NFSClient *client = bs->opaque;
|
NFSClient *client = bs->opaque;
|
||||||
NFSRPC task;
|
NFSRPC task;
|
||||||
|
|
||||||
nfs_co_init_task(client, &task);
|
nfs_co_init_task(bs, &task);
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -496,6 +492,21 @@ static int nfs_has_zero_init(BlockDriverState *bs)
|
||||||
return client->has_zero_init;
|
return client->has_zero_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
|
||||||
|
void *private_data)
|
||||||
|
{
|
||||||
|
NFSRPC *task = private_data;
|
||||||
|
task->ret = ret;
|
||||||
|
if (task->ret == 0) {
|
||||||
|
memcpy(task->st, data, sizeof(struct stat));
|
||||||
|
}
|
||||||
|
if (task->ret < 0) {
|
||||||
|
error_report("NFS Error: %s", nfs_get_error(nfs));
|
||||||
|
}
|
||||||
|
task->complete = 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
NFSClient *client = bs->opaque;
|
NFSClient *client = bs->opaque;
|
||||||
|
@ -507,16 +518,15 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
||||||
return client->st_blocks * 512;
|
return client->st_blocks * 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task.bs = bs;
|
||||||
task.st = &st;
|
task.st = &st;
|
||||||
if (nfs_fstat_async(client->context, client->fh, nfs_co_generic_cb,
|
if (nfs_fstat_async(client->context, client->fh, nfs_get_allocated_file_size_cb,
|
||||||
&task) != 0) {
|
&task) != 0) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
while (!task.complete) {
|
BDRV_POLL_WHILE(bs, !task.complete);
|
||||||
aio_poll(client->aio_context, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
|
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue