diff options
Diffstat (limited to 'block/nfs.c')
| -rw-r--r-- | block/nfs.c | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/block/nfs.c b/block/nfs.c index a564340d15..ffb54be065 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -108,12 +108,13 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp) qdict_put(options, "path", qstring_from_str(uri->path)); for (i = 0; i < qp->n; i++) { + unsigned long long 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, NULL, 0)) { + if (parse_uint_full(qp->p[i].value, &val, 0)) { error_setg(errp, "Illegal value for NFS parameter: %s", qp->p[i].name); goto out; @@ -207,15 +208,21 @@ static void nfs_set_events(NFSClient *client) static void nfs_process_read(void *arg) { NFSClient *client = arg; + + aio_context_acquire(client->aio_context); nfs_service(client->context, POLLIN); nfs_set_events(client); + aio_context_release(client->aio_context); } static void nfs_process_write(void *arg) { NFSClient *client = arg; + + aio_context_acquire(client->aio_context); nfs_service(client->context, POLLOUT); nfs_set_events(client); + aio_context_release(client->aio_context); } static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task) @@ -230,8 +237,9 @@ static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task) static void nfs_co_generic_bh_cb(void *opaque) { NFSRPC *task = opaque; + task->complete = 1; - qemu_coroutine_enter(task->co); + aio_co_wake(task->co); } static void @@ -255,9 +263,9 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, nfs_co_generic_bh_cb, task); } -static int coroutine_fn nfs_co_readv(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) +static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *iov, + int flags) { NFSClient *client = bs->opaque; NFSRPC task; @@ -266,9 +274,7 @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs, task.iov = iov; if (nfs_pread_async(client->context, client->fh, - sector_num * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE, - nfs_co_generic_cb, &task) != 0) { + offset, bytes, nfs_co_generic_cb, &task) != 0) { return -ENOMEM; } @@ -289,28 +295,34 @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs, return 0; } -static int coroutine_fn nfs_co_writev(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) +static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *iov, + int flags) { NFSClient *client = bs->opaque; NFSRPC task; char *buf = NULL; + bool my_buffer = false; nfs_co_init_task(bs, &task); - buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE); - if (nb_sectors && buf == NULL) { - return -ENOMEM; + if (iov->niov != 1) { + buf = g_try_malloc(bytes); + if (bytes && buf == NULL) { + return -ENOMEM; + } + qemu_iovec_to_buf(iov, 0, buf, bytes); + my_buffer = true; + } else { + buf = iov->iov[0].iov_base; } - qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE); - if (nfs_pwrite_async(client->context, client->fh, - sector_num * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE, - buf, nfs_co_generic_cb, &task) != 0) { - g_free(buf); + offset, bytes, buf, + nfs_co_generic_cb, &task) != 0) { + if (my_buffer) { + g_free(buf); + } return -ENOMEM; } @@ -319,9 +331,11 @@ static int coroutine_fn nfs_co_writev(BlockDriverState *bs, qemu_coroutine_yield(); } - g_free(buf); + if (my_buffer) { + g_free(buf); + } - if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) { + if (task.ret != bytes) { return task.ret < 0 ? task.ret : -EIO; } @@ -358,27 +372,27 @@ static QemuOptsList runtime_opts = { .help = "Path of the image on the host", }, { - .name = "uid", + .name = "user", .type = QEMU_OPT_NUMBER, .help = "UID value to use when talking to the server", }, { - .name = "gid", + .name = "group", .type = QEMU_OPT_NUMBER, .help = "GID value to use when talking to the server", }, { - .name = "tcp-syncnt", + .name = "tcp-syn-count", .type = QEMU_OPT_NUMBER, .help = "Number of SYNs to send during the session establish", }, { - .name = "readahead", + .name = "readahead-size", .type = QEMU_OPT_NUMBER, .help = "Set the readahead size in bytes", }, { - .name = "pagecache", + .name = "page-cache-size", .type = QEMU_OPT_NUMBER, .help = "Set the pagecache size in bytes", }, @@ -507,29 +521,29 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, goto fail; } - if (qemu_opt_get(opts, "uid")) { - client->uid = qemu_opt_get_number(opts, "uid", 0); + if (qemu_opt_get(opts, "user")) { + client->uid = qemu_opt_get_number(opts, "user", 0); nfs_set_uid(client->context, client->uid); } - if (qemu_opt_get(opts, "gid")) { - client->gid = qemu_opt_get_number(opts, "gid", 0); + if (qemu_opt_get(opts, "group")) { + client->gid = qemu_opt_get_number(opts, "group", 0); nfs_set_gid(client->context, client->gid); } - if (qemu_opt_get(opts, "tcp-syncnt")) { - client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syncnt", 0); + if (qemu_opt_get(opts, "tcp-syn-count")) { + client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syn-count", 0); nfs_set_tcp_syncnt(client->context, client->tcp_syncnt); } #ifdef LIBNFS_FEATURE_READAHEAD - if (qemu_opt_get(opts, "readahead")) { + if (qemu_opt_get(opts, "readahead-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS readahead " "if cache.direct = on"); goto fail; } - client->readahead = qemu_opt_get_number(opts, "readahead", 0); + client->readahead = qemu_opt_get_number(opts, "readahead-size", 0); if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) { error_report("NFS Warning: Truncating NFS readahead " "size to %d", QEMU_NFS_MAX_READAHEAD_SIZE); @@ -544,13 +558,13 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options, #endif #ifdef LIBNFS_FEATURE_PAGECACHE - if (qemu_opt_get(opts, "pagecache")) { + if (qemu_opt_get(opts, "page-cache-size")) { if (open_flags & BDRV_O_NOCACHE) { error_setg(errp, "Cannot enable NFS pagecache " "if cache.direct = on"); goto fail; } - client->pagecache = qemu_opt_get_number(opts, "pagecache", 0); + client->pagecache = qemu_opt_get_number(opts, "page-cache-size", 0); if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) { error_report("NFS Warning: Truncating NFS pagecache " "size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE); @@ -797,28 +811,26 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options) ov = qobject_output_visitor_new(&server_qdict); visit_type_NFSServer(ov, NULL, &client->server, &error_abort); visit_complete(ov, &server_qdict); - assert(qobject_type(server_qdict) == QTYPE_QDICT); - qdict_put_obj(opts, "server", server_qdict); qdict_put(opts, "path", qstring_from_str(client->path)); if (client->uid) { - qdict_put(opts, "uid", qint_from_int(client->uid)); + qdict_put(opts, "user", qint_from_int(client->uid)); } if (client->gid) { - qdict_put(opts, "gid", qint_from_int(client->gid)); + qdict_put(opts, "group", qint_from_int(client->gid)); } if (client->tcp_syncnt) { - qdict_put(opts, "tcp-syncnt", - qint_from_int(client->tcp_syncnt)); + qdict_put(opts, "tcp-syn-cnt", + qint_from_int(client->tcp_syncnt)); } if (client->readahead) { - qdict_put(opts, "readahead", - qint_from_int(client->readahead)); + qdict_put(opts, "readahead-size", + qint_from_int(client->readahead)); } if (client->pagecache) { - qdict_put(opts, "pagecache", - qint_from_int(client->pagecache)); + qdict_put(opts, "page-cache-size", + qint_from_int(client->pagecache)); } if (client->debug) { qdict_put(opts, "debug", qint_from_int(client->debug)); @@ -855,8 +867,8 @@ static BlockDriver bdrv_nfs = { .bdrv_create = nfs_file_create, .bdrv_reopen_prepare = nfs_reopen_prepare, - .bdrv_co_readv = nfs_co_readv, - .bdrv_co_writev = nfs_co_writev, + .bdrv_co_preadv = nfs_co_preadv, + .bdrv_co_pwritev = nfs_co_pwritev, .bdrv_co_flush_to_disk = nfs_co_flush, .bdrv_detach_aio_context = nfs_detach_aio_context, |