Protocols like quorum will be able to queue multiple reopens. Signed-off-by: Benoit Canet <ben...@irqsave.net> --- block.c | 28 ++++++++++++++++++++++++++++ block/cow.c | 1 + block/qcow.c | 1 + block/qcow2.c | 1 + block/qed.c | 1 + block/sheepdog.c | 1 + block/vmdk.c | 1 + block/vvfat.c | 1 + blockdev.c | 5 +++-- include/block/block.h | 2 ++ include/block/block_int.h | 4 ++++ 11 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c index 3bebc74..9205e2d 100644 --- a/block.c +++ b/block.c @@ -4668,3 +4668,31 @@ void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs, options, img_size, flags, errp); } + +int bdrv_ext_snapshot_reopen(BlockDriverState *bs, int bdrv_flags, + Error **errp) +{ + Error *local_err = NULL; + int ret = -ENOTSUP; + + if (!bs->file || !bs->file->drv) { + error_setg(errp, "Block driver not reachable."); + return ret; + } + + if (!bs->file->drv->bdrv_ext_snapshot_reopen) { + error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, + bdrv_get_format_name(bs->file), + bdrv_get_device_name(bs), + "external snapshots"); + return ret; + } + + ret = bs->file->drv->bdrv_ext_snapshot_reopen(bs, bdrv_flags, &local_err); + + if (error_is_set(&local_err)) { + error_propagate(errp, local_err); + } + + return ret; +} diff --git a/block/cow.c b/block/cow.c index ba69f35..86db134 100644 --- a/block/cow.c +++ b/block/cow.c @@ -348,6 +348,7 @@ static BlockDriver bdrv_cow = { .create_options = cow_create_options, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_cow_init(void) diff --git a/block/qcow.c b/block/qcow.c index 423bf35..d25e7d3 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -892,6 +892,7 @@ static BlockDriver bdrv_qcow = { .create_options = qcow_create_options, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_qcow_init(void) diff --git a/block/qcow2.c b/block/qcow2.c index 0174ae5..6b6c5af 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1719,6 +1719,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_check = qcow2_check, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_qcow2_init(void) diff --git a/block/qed.c b/block/qed.c index 9857179..8fac2b8 100644 --- a/block/qed.c +++ b/block/qed.c @@ -1587,6 +1587,7 @@ static BlockDriver bdrv_qed = { .bdrv_check = bdrv_qed_check, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_qed_init(void) diff --git a/block/sheepdog.c b/block/sheepdog.c index 4f483b2..f74e789 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2087,6 +2087,7 @@ BlockDriver bdrv_sheepdog = { .create_options = sd_create_options, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_sheepdog_init(void) diff --git a/block/vmdk.c b/block/vmdk.c index 2b0acc0..93fe441 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1697,6 +1697,7 @@ static BlockDriver bdrv_vmdk = { .create_options = vmdk_create_options, .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_vmdk_init(void) diff --git a/block/vvfat.c b/block/vvfat.c index 4e5f4fc..a33d08d 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2876,6 +2876,7 @@ static BlockDriver bdrv_vvfat = { .protocol_name = "fat", .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create, + .bdrv_ext_snapshot_reopen = bdrv_reopen, }; static void bdrv_vvfat_init(void) diff --git a/blockdev.c b/blockdev.c index b1f388b..e9d235b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -817,8 +817,9 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp) /* We don't need (or want) to use the transactional * bdrv_reopen_multiple() across all the entries at once, because we * don't want to abort all of them if one of them fails the reopen */ - bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR, - NULL); + bdrv_ext_snapshot_reopen(states->new_bs, + states->new_bs->open_flags & ~BDRV_O_RDWR, + NULL); } /* success */ diff --git a/include/block/block.h b/include/block/block.h index 8bb47c4..1e08592 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -141,6 +141,8 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, BlockDriverState *bs, int flags); int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp); +int bdrv_ext_snapshot_reopen(BlockDriverState *bs, int bdrv_flags, + Error **errp); int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue, Error **errp); void bdrv_reopen_commit(BDRVReopenState *reopen_state); diff --git a/include/block/block_int.h b/include/block/block_int.h index 2b476af..23cbd50 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -209,6 +209,10 @@ struct BlockDriver { const char *base_fmt, char *options, uint64_t img_size, int flags, Error **errp); + /* for generic block driver implementing snapshot in a generic way this + field must point to bdrv_reopen */ + int (*bdrv_ext_snapshot_reopen)(BlockDriverState *bs, int bdrv_flags, + Error **errp); QLIST_ENTRY(BlockDriver) list; }; -- 1.7.10.4