提交 d746427a 编写于 作者: P Paolo Bonzini 提交者: Fam Zheng

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: NStefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: NFam Zheng <famz@redhat.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
Message-Id: <1477565348-5458-10-git-send-email-pbonzini@redhat.com>
Signed-off-by: NFam Zheng <famz@redhat.com>
上级 aa92d6c4
...@@ -52,6 +52,7 @@ typedef struct NFSClient { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册