@@ -4626,3 +4626,29 @@ out:
bdrv_delete(bs);
}
}
+
+void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp)
+{
+ if (!old_bs || !old_bs->file || !old_bs->file->drv) {
+ error_setg(errp, "Block driver not reachable.");
+ return;
+ }
+
+ if (!old_bs->file->drv->bdrv_ext_snapshot_img_create) {
+ bdrv_img_create(filename, fmt, base_filename, base_fmt, options,
+ img_size, flags, errp);
+ return;
+ }
+
+ old_bs->file->drv->bdrv_ext_snapshot_img_create(old_bs,
+ filename, fmt,
+ base_filename,
+ base_fmt,
+ options, img_size,
+ flags, errp);
+}
@@ -787,10 +787,10 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
/* create new image w/backing file */
if (mode != NEW_IMAGE_MODE_EXISTING) {
- bdrv_img_create(new_image_file, format,
- states->old_bs->filename,
- states->old_bs->drv->format_name,
- NULL, -1, flags, &local_err);
+ bdrv_ext_snapshot_img_create(states->old_bs, new_image_file, format,
+ states->old_bs->filename,
+ states->old_bs->drv->format_name,
+ NULL, -1, flags, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
goto delete_and_fail;
@@ -346,6 +346,12 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
void bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags, Error **errp);
+void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp);
void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
void *qemu_blockalign(BlockDriverState *bs, size_t size);
@@ -202,6 +202,14 @@ struct BlockDriver {
*/
int (*bdrv_has_zero_init)(BlockDriverState *bs);
+ /* optional field */
+ void (*bdrv_ext_snapshot_img_create)(BlockDriverState *bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp);
+
QLIST_ENTRY(BlockDriver) list;
};
This patch will allow protocols to implements snapshots as the image creation can now delegated to the block driver. Signed-off-by: Benoit Canet <benoit@irqsave.net> --- block.c | 26 ++++++++++++++++++++++++++ blockdev.c | 8 ++++---- include/block/block.h | 6 ++++++ include/block/block_int.h | 8 ++++++++ 4 files changed, 44 insertions(+), 4 deletions(-)