191
192
static void nfs_process_read(void *arg);
192
193
static void nfs_process_write(void *arg);
195
/* Called with QemuMutex held. */
194
196
static void nfs_set_events(NFSClient *client)
196
198
int ev = nfs_which_events(client->context);
198
200
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
200
202
(ev & POLLIN) ? nfs_process_read : NULL,
201
(ev & POLLOUT) ? nfs_process_write : NULL, client);
203
(ev & POLLOUT) ? nfs_process_write : NULL,
204
207
client->events = ev;
207
210
static void nfs_process_read(void *arg)
209
212
NFSClient *client = arg;
214
qemu_mutex_lock(&client->mutex);
210
215
nfs_service(client->context, POLLIN);
211
216
nfs_set_events(client);
217
qemu_mutex_unlock(&client->mutex);
214
220
static void nfs_process_write(void *arg)
216
222
NFSClient *client = arg;
224
qemu_mutex_lock(&client->mutex);
217
225
nfs_service(client->context, POLLOUT);
218
226
nfs_set_events(client);
227
qemu_mutex_unlock(&client->mutex);
221
230
static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
230
239
static void nfs_co_generic_bh_cb(void *opaque)
232
241
NFSRPC *task = opaque;
233
243
task->complete = 1;
234
qemu_coroutine_enter(task->co);
244
aio_co_wake(task->co);
247
/* Called (via nfs_service) with QemuMutex held. */
238
249
nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
239
250
void *private_data)
255
266
nfs_co_generic_bh_cb, task);
258
static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
259
int64_t sector_num, int nb_sectors,
269
static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
270
uint64_t bytes, QEMUIOVector *iov,
262
273
NFSClient *client = bs->opaque;
265
276
nfs_co_init_task(bs, &task);
279
qemu_mutex_lock(&client->mutex);
268
280
if (nfs_pread_async(client->context, client->fh,
269
sector_num * BDRV_SECTOR_SIZE,
270
nb_sectors * BDRV_SECTOR_SIZE,
271
nfs_co_generic_cb, &task) != 0) {
281
offset, bytes, nfs_co_generic_cb, &task) != 0) {
282
qemu_mutex_unlock(&client->mutex);
275
286
nfs_set_events(client);
287
qemu_mutex_unlock(&client->mutex);
276
288
while (!task.complete) {
277
289
qemu_coroutine_yield();
292
static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
293
int64_t sector_num, int nb_sectors,
304
static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
305
uint64_t bytes, QEMUIOVector *iov,
296
308
NFSClient *client = bs->opaque;
298
310
char *buf = NULL;
311
bool my_buffer = false;
300
313
nfs_co_init_task(bs, &task);
302
buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE);
303
if (nb_sectors && buf == NULL) {
315
if (iov->niov != 1) {
316
buf = g_try_malloc(bytes);
317
if (bytes && buf == NULL) {
320
qemu_iovec_to_buf(iov, 0, buf, bytes);
323
buf = iov->iov[0].iov_base;
307
qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE);
326
qemu_mutex_lock(&client->mutex);
309
327
if (nfs_pwrite_async(client->context, client->fh,
310
sector_num * BDRV_SECTOR_SIZE,
311
nb_sectors * BDRV_SECTOR_SIZE,
312
buf, nfs_co_generic_cb, &task) != 0) {
329
nfs_co_generic_cb, &task) != 0) {
330
qemu_mutex_unlock(&client->mutex);
337
nfs_set_events(client);
338
qemu_mutex_unlock(&client->mutex);
339
while (!task.complete) {
340
qemu_coroutine_yield();
317
nfs_set_events(client);
318
while (!task.complete) {
319
qemu_coroutine_yield();
324
if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) {
347
if (task.ret != bytes) {
325
348
return task.ret < 0 ? task.ret : -EIO;
336
359
nfs_co_init_task(bs, &task);
361
qemu_mutex_lock(&client->mutex);
338
362
if (nfs_fsync_async(client->context, client->fh, nfs_co_generic_cb,
364
qemu_mutex_unlock(&client->mutex);
343
368
nfs_set_events(client);
369
qemu_mutex_unlock(&client->mutex);
344
370
while (!task.complete) {
345
371
qemu_coroutine_yield();
396
422
NFSClient *client = bs->opaque;
398
424
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
399
false, NULL, NULL, NULL);
425
false, NULL, NULL, NULL, NULL);
400
426
client->events = 0;
416
442
nfs_close(client->context, client->fh);
418
444
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
419
false, NULL, NULL, NULL);
445
false, NULL, NULL, NULL, NULL);
420
446
nfs_destroy_context(client->context);
422
448
memset(client, 0, sizeof(NFSClient));
427
453
NFSClient *client = bs->opaque;
428
454
nfs_client_close(client);
455
qemu_mutex_destroy(&client->mutex);
431
458
static NFSServer *nfs_config(QDict *options, Error **errp)
450
iv = qobject_input_visitor_new(crumpled_addr, true);
478
* Caution: this works only because all scalar members of
479
* NFSServer are QString in @crumpled_addr. The visitor expects
480
* @crumpled_addr to be typed according to the QAPI schema. It
481
* is when @options come from -blockdev or blockdev_add. But when
482
* they come from -drive, they're all QString.
484
iv = qobject_input_visitor_new(crumpled_addr);
451
485
visit_type_NFSServer(iv, NULL, &server, &local_error);
452
486
if (local_error) {
453
487
error_propagate(errp, local_error);
688
723
return client->has_zero_init;
726
/* Called (via nfs_service) with QemuMutex held. */
692
728
nfs_get_allocated_file_size_cb(int ret, struct nfs_context *nfs, void *data,
693
729
void *private_data)
797
833
ov = qobject_output_visitor_new(&server_qdict);
798
834
visit_type_NFSServer(ov, NULL, &client->server, &error_abort);
799
835
visit_complete(ov, &server_qdict);
800
assert(qobject_type(server_qdict) == QTYPE_QDICT);
802
836
qdict_put_obj(opts, "server", server_qdict);
803
837
qdict_put(opts, "path", qstring_from_str(client->path));
855
889
.bdrv_create = nfs_file_create,
856
890
.bdrv_reopen_prepare = nfs_reopen_prepare,
858
.bdrv_co_readv = nfs_co_readv,
859
.bdrv_co_writev = nfs_co_writev,
892
.bdrv_co_preadv = nfs_co_preadv,
893
.bdrv_co_pwritev = nfs_co_pwritev,
860
894
.bdrv_co_flush_to_disk = nfs_co_flush,
862
896
.bdrv_detach_aio_context = nfs_detach_aio_context,