Revision eeb6b45d

b/block/raw-posix.c
138 138
#endif
139 139
} BDRVRawState;
140 140

  
141
typedef struct BDRVRawReopenState {
142
    int fd;
143
    int open_flags;
144
#ifdef CONFIG_LINUX_AIO
145
    int use_aio;
146
#endif
147
} BDRVRawReopenState;
148

  
141 149
static int fd_open(BlockDriverState *bs);
142 150
static int64_t raw_getlength(BlockDriverState *bs);
143 151

  
......
290 298
    return raw_open_common(bs, filename, flags, 0);
291 299
}
292 300

  
301
static int raw_reopen_prepare(BDRVReopenState *state,
302
                              BlockReopenQueue *queue, Error **errp)
303
{
304
    BDRVRawState *s;
305
    BDRVRawReopenState *raw_s;
306
    int ret = 0;
307

  
308
    assert(state != NULL);
309
    assert(state->bs != NULL);
310

  
311
    s = state->bs->opaque;
312

  
313
    state->opaque = g_malloc0(sizeof(BDRVRawReopenState));
314
    raw_s = state->opaque;
315

  
316
#ifdef CONFIG_LINUX_AIO
317
    raw_s->use_aio = s->use_aio;
318

  
319
    /* we can use s->aio_ctx instead of a copy, because the use_aio flag is
320
     * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio()
321
     * won't override aio_ctx if aio_ctx is non-NULL */
322
    if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) {
323
        return -1;
324
    }
325
#endif
326

  
327
    raw_parse_flags(state->flags, &raw_s->open_flags);
328

  
329
    raw_s->fd = -1;
330

  
331
    int fcntl_flags = O_APPEND | O_ASYNC | O_NONBLOCK;
332
#ifdef O_NOATIME
333
    fcntl_flags |= O_NOATIME;
334
#endif
335

  
336
    if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) {
337
        /* dup the original fd */
338
        /* TODO: use qemu fcntl wrapper */
339
#ifdef F_DUPFD_CLOEXEC
340
        raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0);
341
#else
342
        raw_s->fd = dup(s->fd);
343
        if (raw_s->fd != -1) {
344
            qemu_set_cloexec(raw_s->fd);
345
        }
346
#endif
347
        if (raw_s->fd >= 0) {
348
            ret = fcntl_setfl(raw_s->fd, raw_s->open_flags);
349
            if (ret) {
350
                qemu_close(raw_s->fd);
351
                raw_s->fd = -1;
352
            }
353
        }
354
    }
355

  
356
    /* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */
357
    if (raw_s->fd == -1) {
358
        assert(!(raw_s->open_flags & O_CREAT));
359
        raw_s->fd = qemu_open(state->bs->filename, raw_s->open_flags);
360
        if (raw_s->fd == -1) {
361
            ret = -1;
362
        }
363
    }
364
    return ret;
365
}
366

  
367

  
368
static void raw_reopen_commit(BDRVReopenState *state)
369
{
370
    BDRVRawReopenState *raw_s = state->opaque;
371
    BDRVRawState *s = state->bs->opaque;
372

  
373
    s->open_flags = raw_s->open_flags;
374

  
375
    qemu_close(s->fd);
376
    s->fd = raw_s->fd;
377
#ifdef CONFIG_LINUX_AIO
378
    s->use_aio = raw_s->use_aio;
379
#endif
380

  
381
    g_free(state->opaque);
382
    state->opaque = NULL;
383
}
384

  
385

  
386
static void raw_reopen_abort(BDRVReopenState *state)
387
{
388
    BDRVRawReopenState *raw_s = state->opaque;
389

  
390
     /* nothing to do if NULL, we didn't get far enough */
391
    if (raw_s == NULL) {
392
        return;
393
    }
394

  
395
    if (raw_s->fd >= 0) {
396
        qemu_close(raw_s->fd);
397
        raw_s->fd = -1;
398
    }
399
    g_free(state->opaque);
400
    state->opaque = NULL;
401
}
402

  
403

  
293 404
/* XXX: use host sector size if necessary with:
294 405
#ifdef DIOCGSECTORSIZE
295 406
        {
......
740 851
    .instance_size = sizeof(BDRVRawState),
741 852
    .bdrv_probe = NULL, /* no probe for protocols */
742 853
    .bdrv_file_open = raw_open,
854
    .bdrv_reopen_prepare = raw_reopen_prepare,
855
    .bdrv_reopen_commit = raw_reopen_commit,
856
    .bdrv_reopen_abort = raw_reopen_abort,
743 857
    .bdrv_close = raw_close,
744 858
    .bdrv_create = raw_create,
745 859
    .bdrv_co_discard = raw_co_discard,

Also available in: Unified diff