diff --git i/block/nfs.c w/block/nfs.c index 1d3a34a30c..78d851d77b 100644 --- i/block/nfs.c +++ w/block/nfs.c @@ -69,7 +69,9 @@ typedef struct NFSClient { typedef struct NFSRPC { BlockDriverState *bs; int ret; +#ifndef LIBNFS_API_V2 QEMUIOVector *iov; +#endif struct stat *st; Coroutine *co; NFSClient *client; @@ -237,6 +239,7 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, NFSRPC *task = private_data; task->ret = ret; assert(!task->st); +#ifndef LIBNFS_API_V2 if (task->ret > 0 && task->iov) { if (task->ret <= task->iov->size) { qemu_iovec_from_buf(task->iov, 0, data, task->ret); @@ -244,6 +247,7 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, task->ret = -EIO; } } +#endif if (task->ret < 0) { error_report("NFS Error: %s", nfs_get_error(nfs)); } @@ -265,20 +269,57 @@ static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, int64_t offset, { NFSClient *client = bs->opaque; NFSRPC task; +#ifdef LIBNFS_API_V2 + char *buf = NULL; + bool my_buffer = false; +#endif nfs_co_init_task(bs, &task); + +#ifdef LIBNFS_API_V2 + if (iov->niov != 1) { + buf = g_try_malloc(bytes); + if (bytes && buf == NULL) { + return -ENOMEM; + } + my_buffer = true; + } else { + buf = iov->iov[0].iov_base; + } +#else task.iov = iov; +#endif WITH_QEMU_LOCK_GUARD(&client->mutex) { +#ifdef LIBNFS_API_V2 + if (nfs_pread_async(client->context, client->fh, + buf, bytes, offset, + nfs_co_generic_cb, &task) != 0) { + if (my_buffer) { + g_free(buf); + } + return -ENOMEM; + } +#else if (nfs_pread_async(client->context, client->fh, offset, bytes, nfs_co_generic_cb, &task) != 0) { return -ENOMEM; } +#endif nfs_set_events(client); } qemu_coroutine_yield(); +#ifdef LIBNFS_API_V2 + if (task.ret > 0) { + qemu_iovec_from_buf(iov, 0, buf, task.ret); + } + if (my_buffer) { + g_free(buf); + } +#endif + if (task.ret < 0) { return task.ret; } @@ -315,7 +356,11 @@ static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, int64_t offset, WITH_QEMU_LOCK_GUARD(&client->mutex) { if (nfs_pwrite_async(client->context, client->fh, +#ifdef LIBNFS_API_V2 + buf, bytes, offset, +#else offset, bytes, buf, +#endif nfs_co_generic_cb, &task) != 0) { if (my_buffer) { g_free(buf); diff --git i/meson.build w/meson.build index d9293294d8..ca9d9f67a9 100644 --- i/meson.build +++ w/meson.build @@ -1178,7 +1178,7 @@ endif libnfs = not_found if not get_option('libnfs').auto() or have_block - libnfs = dependency('libnfs', version: ['>=1.9.3', '<6.0.0'], + libnfs = dependency('libnfs', version: '>=1.9.3', required: get_option('libnfs'), method: 'pkg-config') endif