[PATCH v6 02/25] parallels: split inactivation out and add the activation counterpart
"Denis V. Lunev" <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu,gmane.comp.emulators.qemu.block |
|---|---|
| Message-ID | <[email protected]> |
From: Denis V. Lunev <[email protected]> We are going to add parallels image extensions storage and need a separate function for the inactivation code, which parallels_close() carries inline today. Move it into parallels_inactivate() and register it as .bdrv_inactivate, so the image is written out when the node is inactivated and not only when it is closed. The condition guarding the old call moves inside, as the handler is now reached for any node: bdrv_inactivate_recurse() calls it and blockdev-set-active can ask for it at any time. There is nothing to write out for a node we can not write to, and trying turns a request which has nothing to do into "Failed to inactivate node: Operation not permitted". Clearing the in use flag now needs someone to set it again. parallels_open() is the only place doing that, and it does not run when a node is made active again, which would leave an image whose header says it was closed correctly while it is open for writing: a crash then looks like a clean shutdown and the repair on open is skipped. Add parallels_co_invalidate_cache(), the counterpart of the above, which arms the flag again and reports through errp when it can not. The flag may only be cleared once everything which can still fail has succeeded, as a failed inactivation leaves the node writable and the image has to keep saying so. The order is therefore the reverse of the code being moved: truncate first, write the header last and answer with the result of that write instead of ignoring it. The migration blocker stays, though its comment asks for it to go once an activate method exists. An activated node needs more than the in use flag to be correct, as the used cluster bitmap describes the image as it was before the handover. Based on the original work from Alexander Ivanov. Cc: Stefan Hajnoczi <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> --- block/parallels.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/block/parallels.c b/block/parallels.c index 94692275c9..f02ad7a0be 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -1481,6 +1481,41 @@ fail: return ret; } +static int GRAPH_RDLOCK parallels_inactivate(BlockDriverState *bs) +{ + BDRVParallelsState *s = bs->opaque; + int ret; + + if (!(bs->open_flags & BDRV_O_RDWR) || (bs->open_flags & BDRV_O_INACTIVE)) { + return 0; + } + + ret = bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true, + PREALLOC_MODE_OFF, 0, NULL); + if (ret < 0) { + return ret; + } + + s->header->inuse = 0; + return parallels_update_header(bs); +} + +static void coroutine_fn GRAPH_RDLOCK +parallels_co_invalidate_cache(BlockDriverState *bs, Error **errp) +{ + BDRVParallelsState *s = bs->opaque; + int ret; + + if (!(bs->open_flags & BDRV_O_RDWR)) { + return; + } + + s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC); + ret = parallels_update_header(bs); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to mark the image in use"); + } +} static void parallels_close(BlockDriverState *bs) { @@ -1488,14 +1523,7 @@ static void parallels_close(BlockDriverState *bs) GRAPH_RDLOCK_GUARD_MAINLOOP(); - if ((bs->open_flags & BDRV_O_RDWR) && !(bs->open_flags & BDRV_O_INACTIVE)) { - s->header->inuse = 0; - parallels_update_header(bs); - - /* errors are ignored, so we might as well pass exact=true */ - bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, true, - PREALLOC_MODE_OFF, 0, NULL); - } + parallels_inactivate(bs); parallels_free_used_bitmap(bs); @@ -1533,6 +1561,8 @@ static BlockDriver bdrv_parallels = { .bdrv_co_check = parallels_co_check, .bdrv_co_pdiscard = parallels_co_pdiscard, .bdrv_co_pwrite_zeroes = parallels_co_pwrite_zeroes, + .bdrv_co_invalidate_cache = parallels_co_invalidate_cache, + .bdrv_inactivate = parallels_inactivate, }; static void bdrv_parallels_init(void) -- 2.53.0