#include "qemu/osdep.h"
+#if !defined(_WIN32)
#include <poll.h>
+#endif
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
+#include "block/block-io.h"
#include "block/block_int.h"
#include "block/qdict.h"
#include "trace.h"
#include "qemu/option.h"
#include "qemu/uri.h"
#include "qemu/cutils.h"
-#include "sysemu/sysemu.h"
#include "sysemu/replay.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qdict.h"
bool has_zero_init;
AioContext *aio_context;
QemuMutex mutex;
- blkcnt_t st_blocks;
+ uint64_t st_blocks;
bool cache_used;
NFSServer *server;
char *path;
qdict_put_str(options, "path", uri->path);
for (i = 0; i < qp->n; i++) {
- unsigned long long val;
+ uint64_t val;
if (!qp->p[i].value) {
error_setg(errp, "Value for NFS parameter expected: %s",
qp->p[i].name);
goto out;
}
- if (parse_uint_full(qp->p[i].value, &val, 0)) {
+ if (parse_uint_full(qp->p[i].value, 0, &val)) {
error_setg(errp, "Illegal value for NFS parameter: %s",
qp->p[i].name);
goto out;
if (qp) {
query_params_free(qp);
}
- if (uri) {
- uri_free(uri);
- }
+ uri_free(uri);
return ret;
}
int ev = nfs_which_events(client->context);
if (ev != client->events) {
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
- false,
(ev & POLLIN) ? nfs_process_read : NULL,
(ev & POLLOUT) ? nfs_process_write : NULL,
- NULL, client);
+ NULL, NULL, client);
}
client->events = ev;
qemu_mutex_unlock(&client->mutex);
}
-static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
+static void coroutine_fn nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
{
*task = (NFSRPC) {
.co = qemu_coroutine_self(),
nfs_co_generic_bh_cb, task);
}
-static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
- uint64_t bytes, QEMUIOVector *iov,
- int flags)
+static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset,
+ int64_t bytes, QEMUIOVector *iov,
+ BdrvRequestFlags flags)
{
NFSClient *client = bs->opaque;
NFSRPC task;
return 0;
}
-static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
- uint64_t bytes, QEMUIOVector *iov,
- int flags)
+static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, int64_t offset,
+ int64_t bytes, QEMUIOVector *iov,
+ BdrvRequestFlags flags)
{
NFSClient *client = bs->opaque;
NFSRPC task;
NFSClient *client = bs->opaque;
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
- false, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
client->events = 0;
}
if (client->context) {
qemu_mutex_lock(&client->mutex);
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
- false, NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
qemu_mutex_unlock(&client->mutex);
if (client->fh) {
nfs_close(client->context, client->fh);
int flags, int open_flags, Error **errp)
{
int64_t ret = -EINVAL;
+#ifdef _WIN32
+ struct __stat64 st;
+#else
struct stat st;
+#endif
char *file = NULL, *strp = NULL;
qemu_mutex_init(&client->mutex);
}
ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);
+#if !defined(_WIN32)
client->st_blocks = st.st_blocks;
+#endif
client->has_zero_init = S_ISREG(st.st_mode);
*strp = '/';
goto out;
int flags, int open_flags, Error **errp)
{
BlockdevOptionsNfs *opts;
- int ret;
+ int64_t ret;
opts = nfs_options_qdict_to_qapi(options, errp);
if (opts == NULL) {
return client->has_zero_init;
}
+#if !defined(_WIN32)
/* Called (via nfs_service) with QemuMutex held. */
static void
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
if (task->ret < 0) {
error_report("NFS Error: %s", nfs_get_error(nfs));
}
-
- /* Set task->complete before reading bs->wakeup. */
- atomic_mb_set(&task->complete, 1);
- bdrv_wakeup(task->bs);
+ replay_bh_schedule_oneshot_event(task->client->aio_context,
+ nfs_co_generic_bh_cb, task);
}
-static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
+static int64_t coroutine_fn nfs_co_get_allocated_file_size(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
NFSRPC task = {0};
return client->st_blocks * 512;
}
- task.bs = bs;
+ nfs_co_init_task(bs, &task);
task.st = &st;
- if (nfs_fstat_async(client->context, client->fh, nfs_get_allocated_file_size_cb,
- &task) != 0) {
- return -ENOMEM;
- }
+ WITH_QEMU_LOCK_GUARD(&client->mutex) {
+ if (nfs_fstat_async(client->context, client->fh, nfs_get_allocated_file_size_cb,
+ &task) != 0) {
+ return -ENOMEM;
+ }
- nfs_set_events(client);
- BDRV_POLL_WHILE(bs, !task.complete);
+ nfs_set_events(client);
+ }
+ while (!task.complete) {
+ qemu_coroutine_yield();
+ }
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
+#endif
static int coroutine_fn
nfs_file_co_truncate(BlockDriverState *bs, int64_t offset, bool exact,
BlockReopenQueue *queue, Error **errp)
{
NFSClient *client = state->bs->opaque;
+#ifdef _WIN32
+ struct __stat64 st;
+#else
struct stat st;
+#endif
int ret = 0;
if (state->flags & BDRV_O_RDWR && bdrv_is_read_only(state->bs)) {
nfs_get_error(client->context));
return ret;
}
+#if !defined(_WIN32)
client->st_blocks = st.st_blocks;
+#endif
}
return 0;
}
}
-static char *nfs_dirname(BlockDriverState *bs, Error **errp)
+static char * GRAPH_RDLOCK nfs_dirname(BlockDriverState *bs, Error **errp)
{
NFSClient *client = bs->opaque;
.create_opts = &nfs_create_opts,
.bdrv_has_zero_init = nfs_has_zero_init,
- .bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
+/* libnfs does not provide the allocated filesize of a file on win32. */
+#if !defined(_WIN32)
+ .bdrv_co_get_allocated_file_size = nfs_co_get_allocated_file_size,
+#endif
.bdrv_co_truncate = nfs_file_co_truncate,
.bdrv_file_open = nfs_file_open,