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