diff --git a/block.c b/block.c index 5f1e8aafd7..f96d26b795 100644 --- a/block.c +++ b/block.c @@ -925,6 +925,67 @@ out: g_free(gen_node_name); } +static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv, + const char *node_name, QDict *options, + int open_flags, Error **errp) +{ + Error *local_err = NULL; + int ret; + + bdrv_assign_node_name(bs, node_name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return -EINVAL; + } + + bs->drv = drv; + bs->opaque = g_malloc0(drv->instance_size); + + if (drv->bdrv_file_open) { + assert(!drv->bdrv_needs_filename || bs->filename[0]); + ret = drv->bdrv_file_open(bs, options, open_flags, &local_err); + } else { + ret = drv->bdrv_open(bs, options, open_flags, &local_err); + } + + if (ret < 0) { + if (local_err) { + error_propagate(errp, local_err); + } else if (bs->filename[0]) { + error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename); + } else { + error_setg_errno(errp, -ret, "Could not open image"); + } + goto free_and_fail; + } + + ret = refresh_total_sectors(bs, bs->total_sectors); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not refresh total sector count"); + goto free_and_fail; + } + + bdrv_refresh_limits(bs, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret = -EINVAL; + goto free_and_fail; + } + + assert(bdrv_opt_mem_align(bs) != 0); + assert(bdrv_min_mem_align(bs) != 0); + assert(is_power_of_2(bs->bl.request_alignment)); + + return 0; + +free_and_fail: + /* FIXME Close bs first if already opened*/ + g_free(bs->opaque); + bs->opaque = NULL; + bs->drv = NULL; + return ret; +} + QemuOptsList bdrv_runtime_opts = { .name = "bdrv_common", .head = QTAILQ_HEAD_INITIALIZER(bdrv_runtime_opts.head), @@ -1019,14 +1080,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, trace_bdrv_open_common(bs, filename ?: "", bs->open_flags, drv->format_name); - node_name = qemu_opt_get(opts, "node-name"); - bdrv_assign_node_name(bs, node_name, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret = -EINVAL; - goto fail_opts; - } - bs->read_only = !(bs->open_flags & BDRV_O_RDWR); if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) { @@ -1092,54 +1145,19 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file, } pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), bs->filename); - bs->drv = drv; - bs->opaque = g_malloc0(drv->instance_size); - /* Open the image, either directly or using a protocol */ open_flags = bdrv_open_flags(bs, bs->open_flags); - if (drv->bdrv_file_open) { - assert(file == NULL); - assert(!drv->bdrv_needs_filename || filename != NULL); - ret = drv->bdrv_file_open(bs, options, open_flags, &local_err); - } else { - ret = drv->bdrv_open(bs, options, open_flags, &local_err); - } + node_name = qemu_opt_get(opts, "node-name"); + assert(!drv->bdrv_file_open || file == NULL); + ret = bdrv_open_driver(bs, drv, node_name, options, open_flags, errp); if (ret < 0) { - if (local_err) { - error_propagate(errp, local_err); - } else if (bs->filename[0]) { - error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename); - } else { - error_setg_errno(errp, -ret, "Could not open image"); - } - goto free_and_fail; + goto fail_opts; } - ret = refresh_total_sectors(bs, bs->total_sectors); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not refresh total sector count"); - goto free_and_fail; - } - - bdrv_refresh_limits(bs, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret = -EINVAL; - goto free_and_fail; - } - - assert(bdrv_opt_mem_align(bs) != 0); - assert(bdrv_min_mem_align(bs) != 0); - assert(is_power_of_2(bs->bl.request_alignment)); - qemu_opts_del(opts); return 0; -free_and_fail: - g_free(bs->opaque); - bs->opaque = NULL; - bs->drv = NULL; fail_opts: qemu_opts_del(opts); return ret;