~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to block/nfs.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
    int events;
55
55
    bool has_zero_init;
56
56
    AioContext *aio_context;
 
57
    QemuMutex mutex;
57
58
    blkcnt_t st_blocks;
58
59
    bool cache_used;
59
60
    NFSServer *server;
191
192
static void nfs_process_read(void *arg);
192
193
static void nfs_process_write(void *arg);
193
194
 
 
195
/* Called with QemuMutex held.  */
194
196
static void nfs_set_events(NFSClient *client)
195
197
{
196
198
    int ev = nfs_which_events(client->context);
198
200
        aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
199
201
                           false,
200
202
                           (ev & POLLIN) ? nfs_process_read : NULL,
201
 
                           (ev & POLLOUT) ? nfs_process_write : NULL, client);
 
203
                           (ev & POLLOUT) ? nfs_process_write : NULL,
 
204
                           NULL, client);
202
205
 
203
206
    }
204
207
    client->events = ev;
207
210
static void nfs_process_read(void *arg)
208
211
{
209
212
    NFSClient *client = arg;
 
213
 
 
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);
212
218
}
213
219
 
214
220
static void nfs_process_write(void *arg)
215
221
{
216
222
    NFSClient *client = arg;
 
223
 
 
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);
219
228
}
220
229
 
221
230
static void nfs_co_init_task(BlockDriverState *bs, NFSRPC *task)
230
239
static void nfs_co_generic_bh_cb(void *opaque)
231
240
{
232
241
    NFSRPC *task = opaque;
 
242
 
233
243
    task->complete = 1;
234
 
    qemu_coroutine_enter(task->co);
 
244
    aio_co_wake(task->co);
235
245
}
236
246
 
 
247
/* Called (via nfs_service) with QemuMutex held.  */
237
248
static void
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);
256
267
}
257
268
 
258
 
static int coroutine_fn nfs_co_readv(BlockDriverState *bs,
259
 
                                     int64_t sector_num, int nb_sectors,
260
 
                                     QEMUIOVector *iov)
 
269
static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset,
 
270
                                      uint64_t bytes, QEMUIOVector *iov,
 
271
                                      int flags)
261
272
{
262
273
    NFSClient *client = bs->opaque;
263
274
    NFSRPC task;
265
276
    nfs_co_init_task(bs, &task);
266
277
    task.iov = iov;
267
278
 
 
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);
272
283
        return -ENOMEM;
273
284
    }
274
285
 
275
286
    nfs_set_events(client);
 
287
    qemu_mutex_unlock(&client->mutex);
276
288
    while (!task.complete) {
277
289
        qemu_coroutine_yield();
278
290
    }
289
301
    return 0;
290
302
}
291
303
 
292
 
static int coroutine_fn nfs_co_writev(BlockDriverState *bs,
293
 
                                        int64_t sector_num, int nb_sectors,
294
 
                                        QEMUIOVector *iov)
 
304
static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset,
 
305
                                       uint64_t bytes, QEMUIOVector *iov,
 
306
                                       int flags)
295
307
{
296
308
    NFSClient *client = bs->opaque;
297
309
    NFSRPC task;
298
310
    char *buf = NULL;
 
311
    bool my_buffer = false;
299
312
 
300
313
    nfs_co_init_task(bs, &task);
301
314
 
302
 
    buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE);
303
 
    if (nb_sectors && buf == NULL) {
304
 
        return -ENOMEM;
 
315
    if (iov->niov != 1) {
 
316
        buf = g_try_malloc(bytes);
 
317
        if (bytes && buf == NULL) {
 
318
            return -ENOMEM;
 
319
        }
 
320
        qemu_iovec_to_buf(iov, 0, buf, bytes);
 
321
        my_buffer = true;
 
322
    } else {
 
323
        buf = iov->iov[0].iov_base;
305
324
    }
306
325
 
307
 
    qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE);
308
 
 
 
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) {
 
328
                         offset, bytes, buf,
 
329
                         nfs_co_generic_cb, &task) != 0) {
 
330
        qemu_mutex_unlock(&client->mutex);
 
331
        if (my_buffer) {
 
332
            g_free(buf);
 
333
        }
 
334
        return -ENOMEM;
 
335
    }
 
336
 
 
337
    nfs_set_events(client);
 
338
    qemu_mutex_unlock(&client->mutex);
 
339
    while (!task.complete) {
 
340
        qemu_coroutine_yield();
 
341
    }
 
342
 
 
343
    if (my_buffer) {
313
344
        g_free(buf);
314
 
        return -ENOMEM;
315
 
    }
316
 
 
317
 
    nfs_set_events(client);
318
 
    while (!task.complete) {
319
 
        qemu_coroutine_yield();
320
 
    }
321
 
 
322
 
    g_free(buf);
323
 
 
324
 
    if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) {
 
345
    }
 
346
 
 
347
    if (task.ret != bytes) {
325
348
        return task.ret < 0 ? task.ret : -EIO;
326
349
    }
327
350
 
335
358
 
336
359
    nfs_co_init_task(bs, &task);
337
360
 
 
361
    qemu_mutex_lock(&client->mutex);
338
362
    if (nfs_fsync_async(client->context, client->fh, nfs_co_generic_cb,
339
363
                        &task) != 0) {
 
364
        qemu_mutex_unlock(&client->mutex);
340
365
        return -ENOMEM;
341
366
    }
342
367
 
343
368
    nfs_set_events(client);
 
369
    qemu_mutex_unlock(&client->mutex);
344
370
    while (!task.complete) {
345
371
        qemu_coroutine_yield();
346
372
    }
396
422
    NFSClient *client = bs->opaque;
397
423
 
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;
401
427
}
402
428
 
416
442
            nfs_close(client->context, client->fh);
417
443
        }
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);
421
447
    }
422
448
    memset(client, 0, sizeof(NFSClient));
426
452
{
427
453
    NFSClient *client = bs->opaque;
428
454
    nfs_client_close(client);
 
455
    qemu_mutex_destroy(&client->mutex);
429
456
}
430
457
 
431
458
static NFSServer *nfs_config(QDict *options, Error **errp)
447
474
        goto out;
448
475
    }
449
476
 
450
 
    iv = qobject_input_visitor_new(crumpled_addr, true);
 
477
    /*
 
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.
 
483
     */
 
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);
633
667
    if (ret < 0) {
634
668
        return ret;
635
669
    }
 
670
    qemu_mutex_init(&client->mutex);
636
671
    bs->total_sectors = ret;
637
672
    ret = 0;
638
673
    return ret;
688
723
    return client->has_zero_init;
689
724
}
690
725
 
 
726
/* Called (via nfs_service) with QemuMutex held.  */
691
727
static void
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);
801
 
 
802
836
    qdict_put_obj(opts, "server", server_qdict);
803
837
    qdict_put(opts, "path", qstring_from_str(client->path));
804
838
 
855
889
    .bdrv_create                    = nfs_file_create,
856
890
    .bdrv_reopen_prepare            = nfs_reopen_prepare,
857
891
 
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,
861
895
 
862
896
    .bdrv_detach_aio_context        = nfs_detach_aio_context,