From cc69758cd6851c60890631fac81be0e0cb72441c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 7 May 2010 15:50:12 -0300 Subject: [PATCH 05/11] block: Split bdrv_open RH-Author: Christoph Hellwig Message-id: <1273247415-28118-5-git-send-email-chellwig@redhat.com> Patchwork-id: 9104 O-Subject: [RHEL6 qemu PATCH 5/8] block: Split bdrv_open Bugzilla: 580363 RH-Acked-by: Gleb Natapov RH-Acked-by: Juan Quintela RH-Acked-by: Kevin Wolf From: Kevin Wolf bdrv_open contains quite some code that is only useful for opening images (as opposed to opening files by a protocol), for example snapshots. This patch splits the code so that we have bdrv_open_file() for files (uses protocols), bdrv_open() for images (uses format drivers) and bdrv_open_common() for the code common for opening both images and files. Signed-off-by: Kevin Wolf Upstream commit: b6ce07aa83bdee3cfd2610f270a0ce304e78df95 Bugzilla: 580363 Signed-off-by: Eduardo Habkost --- block.c | 135 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 86 insertions(+), 49 deletions(-) diff --git a/block.c b/block.c index 0a1215c..f858841 100644 --- a/block.c +++ b/block.c @@ -42,6 +42,9 @@ #include #endif +static int bdrv_open_common(BlockDriverState *bs, const char *filename, + int flags, BlockDriver *drv); + static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque); @@ -353,6 +356,9 @@ static BlockDriver *find_image_format(const char *filename) return drv; } +/* + * Opens a file using a protocol (file, host_device, nbd, ...) + */ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) { BlockDriverState *bs; @@ -365,7 +371,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) } bs = bdrv_new(""); - ret = bdrv_open(bs, filename, flags, drv); + ret = bdrv_open_common(bs, filename, flags, drv); if (ret < 0) { bdrv_delete(bs); return ret; @@ -375,19 +381,13 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) return 0; } +/* + * Opens a disk image (raw, qcow2, vmdk, ...) + */ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv) { - int ret, open_flags; - char tmp_filename[PATH_MAX]; - char backing_filename[PATH_MAX]; - - bs->is_temporary = 0; - bs->encrypted = 0; - bs->valid_key = 0; - bs->open_flags = flags; - /* buffer_alignment defaulted to 512, drivers can change this value */ - bs->buffer_alignment = 512; + int ret; if (flags & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; @@ -395,6 +395,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, int is_protocol = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; + char tmp_filename[PATH_MAX]; + char backing_filename[PATH_MAX]; /* if snapshot, we create a temporary backing file and open it instead of opening 'filename' directly */ @@ -442,8 +444,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, bs->is_temporary = 1; } - pstrcpy(bs->filename, sizeof(bs->filename), filename); - + /* Find the right image format driver */ if (!drv) { drv = find_image_format(filename); } @@ -452,11 +453,81 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, ret = -ENOENT; goto unlink_and_fail; } - if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { - ret = -ENOTSUP; + + /* Open the image */ + ret = bdrv_open_common(bs, filename, flags, drv); + if (ret < 0) { goto unlink_and_fail; } + /* If there is a backing file, use it */ + if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { + char backing_filename[PATH_MAX]; + int back_flags; + BlockDriver *back_drv = NULL; + + bs->backing_hd = bdrv_new(""); + path_combine(backing_filename, sizeof(backing_filename), + filename, bs->backing_file); + if (bs->backing_format[0] != '\0') + back_drv = bdrv_find_format(bs->backing_format); + + /* backing files always opened read-only */ + back_flags = + flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); + + ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv); + if (ret < 0) { + bdrv_close(bs); + return ret; + } + if (bs->is_temporary) { + bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); + } else { + /* base image inherits from "parent" */ + bs->backing_hd->keep_read_only = bs->keep_read_only; + } + } + + if (!bdrv_key_required(bs)) { + /* call the change callback */ + bs->media_changed = 1; + if (bs->change_cb) + bs->change_cb(bs->change_opaque); + } + + return 0; + +unlink_and_fail: + if (bs->is_temporary) { + unlink(filename); + } + return ret; +} + +/* + * Common part for opening disk images and files + */ +static int bdrv_open_common(BlockDriverState *bs, const char *filename, + int flags, BlockDriver *drv) +{ + int ret, open_flags; + + assert(drv != NULL); + + bs->is_temporary = 0; + bs->encrypted = 0; + bs->valid_key = 0; + bs->open_flags = flags; + /* buffer_alignment defaulted to 512, drivers can change this value */ + bs->buffer_alignment = 512; + + pstrcpy(bs->filename, sizeof(bs->filename), filename); + + if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv)) { + return -ENOTSUP; + } + bs->drv = drv; bs->opaque = qemu_mallocz(drv->instance_size); @@ -496,46 +567,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, unlink(filename); } #endif - if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') { - /* if there is a backing file, use it */ - BlockDriver *back_drv = NULL; - bs->backing_hd = bdrv_new(""); - path_combine(backing_filename, sizeof(backing_filename), - filename, bs->backing_file); - if (bs->backing_format[0] != '\0') - back_drv = bdrv_find_format(bs->backing_format); - - /* backing files always opened read-only */ - open_flags &= ~BDRV_O_RDWR; - - ret = bdrv_open(bs->backing_hd, backing_filename, open_flags, back_drv); - if (ret < 0) { - bdrv_close(bs); - return ret; - } - if (bs->is_temporary) { - bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR); - } else { - /* base image inherits from "parent" */ - bs->backing_hd->keep_read_only = bs->keep_read_only; - } - } - - if (!bdrv_key_required(bs)) { - /* call the change callback */ - bs->media_changed = 1; - if (bs->change_cb) - bs->change_cb(bs->change_opaque); - } return 0; free_and_fail: qemu_free(bs->opaque); bs->opaque = NULL; bs->drv = NULL; -unlink_and_fail: - if (bs->is_temporary) - unlink(filename); return ret; } -- 1.7.0.3