mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches # gpg: Signature made Fri 24 Feb 2017 18:08:26 GMT # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: tests: Use opened block node for block job tests vvfat: Use opened node as backing file block: Add bdrv_new_open_driver() block: Factor out bdrv_open_driver() block: Use BlockBackend for image probing block: Factor out bdrv_open_child_bs() block: Attach bs->file only during .bdrv_open() block: Pass BdrvChild to bdrv_truncate() mirror: Resize active commit base in mirror_run() qcow2: Use BB for resizing in qcow2_amend_options() blockdev: Use BlockBackend to resize in qmp_block_resize() iotests: Fix another race in 030 qemu-img: Improve documentation for PREALLOC_MODE_FALLOC qemu-img: Truncate before full preallocation qemu-img: Add tests for raw image preallocation qemu-img: Do not truncate before preallocation qemu-iotests: redirect nbd server stdout to /dev/null qemu-iotests: add ability to exclude certain protocols from tests qemu-iotests: Test 137 only supports 'file' protocol Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -588,21 +588,20 @@ BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
|
||||
return drv;
|
||||
}
|
||||
|
||||
static int find_image_format(BdrvChild *file, const char *filename,
|
||||
static int find_image_format(BlockBackend *file, const char *filename,
|
||||
BlockDriver **pdrv, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = file->bs;
|
||||
BlockDriver *drv;
|
||||
uint8_t buf[BLOCK_PROBE_BUF_SIZE];
|
||||
int ret = 0;
|
||||
|
||||
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
|
||||
if (bdrv_is_sg(bs) || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
|
||||
if (blk_is_sg(file) || !blk_is_inserted(file) || blk_getlength(file) == 0) {
|
||||
*pdrv = &bdrv_raw;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(file, 0, buf, sizeof(buf));
|
||||
ret = blk_pread(file, 0, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Could not read image for determining its "
|
||||
"format");
|
||||
@@ -926,6 +925,95 @@ 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->read_only = !(bs->open_flags & BDRV_O_RDWR);
|
||||
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 if (drv->bdrv_open) {
|
||||
ret = drv->bdrv_open(bs, options, open_flags, &local_err);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
|
||||
int flags, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
int ret;
|
||||
|
||||
bs = bdrv_new();
|
||||
bs->open_flags = flags;
|
||||
bs->explicit_options = qdict_new();
|
||||
bs->options = qdict_new();
|
||||
bs->opaque = NULL;
|
||||
|
||||
update_options_from_flags(bs->options, flags);
|
||||
|
||||
ret = bdrv_open_driver(bs, drv, node_name, bs->options, flags, errp);
|
||||
if (ret < 0) {
|
||||
QDECREF(bs->explicit_options);
|
||||
QDECREF(bs->options);
|
||||
bdrv_unref(bs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
QemuOptsList bdrv_runtime_opts = {
|
||||
.name = "bdrv_common",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(bdrv_runtime_opts.head),
|
||||
@@ -974,7 +1062,7 @@ QemuOptsList bdrv_runtime_opts = {
|
||||
*
|
||||
* Removes all processed options from *options.
|
||||
*/
|
||||
static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
|
||||
QDict *options, Error **errp)
|
||||
{
|
||||
int ret, open_flags;
|
||||
@@ -1005,7 +1093,7 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
assert(drv != NULL);
|
||||
|
||||
if (file != NULL) {
|
||||
filename = file->bs->filename;
|
||||
filename = blk_bs(file)->filename;
|
||||
} else {
|
||||
filename = qdict_get_try_str(options, "filename");
|
||||
}
|
||||
@@ -1020,14 +1108,6 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *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)) {
|
||||
@@ -1093,62 +1173,19 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *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 {
|
||||
if (file == NULL) {
|
||||
error_setg(errp, "Can't use '%s' as a block driver for the "
|
||||
"protocol level", drv->format_name);
|
||||
ret = -EINVAL;
|
||||
goto free_and_fail;
|
||||
}
|
||||
bs->file = file;
|
||||
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:
|
||||
bs->file = NULL;
|
||||
g_free(bs->opaque);
|
||||
bs->opaque = NULL;
|
||||
bs->drv = NULL;
|
||||
fail_opts:
|
||||
qemu_opts_del(opts);
|
||||
return ret;
|
||||
@@ -1368,7 +1405,18 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
|
||||
}
|
||||
|
||||
if (child->bs->inherits_from == parent) {
|
||||
child->bs->inherits_from = NULL;
|
||||
BdrvChild *c;
|
||||
|
||||
/* Remove inherits_from only when the last reference between parent and
|
||||
* child->bs goes away. */
|
||||
QLIST_FOREACH(c, &parent->children, next) {
|
||||
if (c != child && c->bs == child->bs) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == NULL) {
|
||||
child->bs->inherits_from = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bdrv_root_unref_child(child);
|
||||
@@ -1543,28 +1591,12 @@ free_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a disk image whose options are given as BlockdevRef in another block
|
||||
* device's options.
|
||||
*
|
||||
* If allow_none is true, no image will be opened if filename is false and no
|
||||
* BlockdevRef is given. NULL will be returned, but errp remains unset.
|
||||
*
|
||||
* bdrev_key specifies the key for the image's BlockdevRef in the options QDict.
|
||||
* That QDict has to be flattened; therefore, if the BlockdevRef is a QDict
|
||||
* itself, all options starting with "${bdref_key}." are considered part of the
|
||||
* BlockdevRef.
|
||||
*
|
||||
* The BlockdevRef will be removed from the options QDict.
|
||||
*/
|
||||
BdrvChild *bdrv_open_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState* parent,
|
||||
const BdrvChildRole *child_role,
|
||||
bool allow_none, Error **errp)
|
||||
static BlockDriverState *
|
||||
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent, const BdrvChildRole *child_role,
|
||||
bool allow_none, Error **errp)
|
||||
{
|
||||
BdrvChild *c = NULL;
|
||||
BlockDriverState *bs;
|
||||
BlockDriverState *bs = NULL;
|
||||
QDict *image_options;
|
||||
char *bdref_key_dot;
|
||||
const char *reference;
|
||||
@@ -1591,11 +1623,40 @@ BdrvChild *bdrv_open_child(const char *filename,
|
||||
goto done;
|
||||
}
|
||||
|
||||
c = bdrv_attach_child(parent, bs, bdref_key, child_role);
|
||||
|
||||
done:
|
||||
qdict_del(options, bdref_key);
|
||||
return c;
|
||||
return bs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a disk image whose options are given as BlockdevRef in another block
|
||||
* device's options.
|
||||
*
|
||||
* If allow_none is true, no image will be opened if filename is false and no
|
||||
* BlockdevRef is given. NULL will be returned, but errp remains unset.
|
||||
*
|
||||
* bdrev_key specifies the key for the image's BlockdevRef in the options QDict.
|
||||
* That QDict has to be flattened; therefore, if the BlockdevRef is a QDict
|
||||
* itself, all options starting with "${bdref_key}." are considered part of the
|
||||
* BlockdevRef.
|
||||
*
|
||||
* The BlockdevRef will be removed from the options QDict.
|
||||
*/
|
||||
BdrvChild *bdrv_open_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent,
|
||||
const BdrvChildRole *child_role,
|
||||
bool allow_none, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
|
||||
bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_role,
|
||||
allow_none, errp);
|
||||
if (bs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bdrv_attach_child(parent, bs, bdref_key, child_role);
|
||||
}
|
||||
|
||||
static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs,
|
||||
@@ -1691,7 +1752,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
Error **errp)
|
||||
{
|
||||
int ret;
|
||||
BdrvChild *file = NULL;
|
||||
BlockBackend *file = NULL;
|
||||
BlockDriverState *bs;
|
||||
BlockDriver *drv = NULL;
|
||||
const char *drvname;
|
||||
@@ -1789,13 +1850,25 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
qdict_del(options, "backing");
|
||||
}
|
||||
|
||||
/* Open image file without format layer */
|
||||
/* Open image file without format layer. This BlockBackend is only used for
|
||||
* probing, the block drivers will do their own bdrv_open_child() for the
|
||||
* same BDS, which is why we put the node name back into options. */
|
||||
if ((flags & BDRV_O_PROTOCOL) == 0) {
|
||||
file = bdrv_open_child(filename, options, "file", bs,
|
||||
&child_file, true, &local_err);
|
||||
BlockDriverState *file_bs;
|
||||
|
||||
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
|
||||
&child_file, true, &local_err);
|
||||
if (local_err) {
|
||||
goto fail;
|
||||
}
|
||||
if (file_bs != NULL) {
|
||||
file = blk_new();
|
||||
blk_insert_bs(file, file_bs);
|
||||
bdrv_unref(file_bs);
|
||||
|
||||
qdict_put(options, "file",
|
||||
qstring_from_str(bdrv_get_node_name(file_bs)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Image format probing */
|
||||
@@ -1835,8 +1908,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (file && (bs->file != file)) {
|
||||
bdrv_unref_child(bs, file);
|
||||
if (file) {
|
||||
blk_unref(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
@@ -1898,8 +1971,9 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
return bs;
|
||||
|
||||
fail:
|
||||
if (file != NULL) {
|
||||
bdrv_unref_child(bs, file);
|
||||
blk_unref(file);
|
||||
if (bs->file != NULL) {
|
||||
bdrv_unref_child(bs, bs->file);
|
||||
}
|
||||
QDECREF(snapshot_options);
|
||||
QDECREF(bs->explicit_options);
|
||||
@@ -2626,8 +2700,9 @@ exit:
|
||||
/**
|
||||
* Truncate file to 'offset' bytes (needed only for file protocols)
|
||||
*/
|
||||
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
|
||||
int bdrv_truncate(BdrvChild *child, int64_t offset)
|
||||
{
|
||||
BlockDriverState *bs = child->bs;
|
||||
BlockDriver *drv = bs->drv;
|
||||
int ret;
|
||||
if (!drv)
|
||||
|
||||
+1
-1
@@ -663,7 +663,7 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
|
||||
static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
|
||||
{
|
||||
return bdrv_truncate(bs->file->bs, offset);
|
||||
return bdrv_truncate(bs->file, offset);
|
||||
}
|
||||
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
|
||||
|
||||
@@ -1605,7 +1605,7 @@ int blk_truncate(BlockBackend *blk, int64_t offset)
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
return bdrv_truncate(blk_bs(blk), offset);
|
||||
return bdrv_truncate(blk->root, offset);
|
||||
}
|
||||
|
||||
static void blk_pdiscard_entry(void *opaque)
|
||||
|
||||
@@ -104,6 +104,12 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
struct bochs_header bochs;
|
||||
int ret;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bs->read_only = true; /* no write support yet */
|
||||
|
||||
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
|
||||
|
||||
@@ -66,6 +66,12 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
uint32_t offsets_size, max_compressed_block_size = 1, i;
|
||||
int ret;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bs->read_only = true;
|
||||
|
||||
/* read header */
|
||||
|
||||
+7
-1
@@ -300,6 +300,12 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
|
||||
QCryptoBlockOpenOptions *open_opts = NULL;
|
||||
unsigned int cflags = 0;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (local_err) {
|
||||
@@ -383,7 +389,7 @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset)
|
||||
|
||||
offset += payload_offset;
|
||||
|
||||
return bdrv_truncate(bs->file->bs, offset);
|
||||
return bdrv_truncate(bs->file, offset);
|
||||
}
|
||||
|
||||
static void block_crypto_close(BlockDriverState *bs)
|
||||
|
||||
@@ -413,6 +413,12 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int64_t offset;
|
||||
int ret;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
block_module_load_one("dmg-bz2");
|
||||
bs->read_only = true;
|
||||
|
||||
|
||||
+21
-7
@@ -1591,18 +1591,17 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ftruncate(fd, total_size) != 0) {
|
||||
result = -errno;
|
||||
error_setg_errno(errp, -result, "Could not resize file");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
switch (prealloc) {
|
||||
#ifdef CONFIG_POSIX_FALLOCATE
|
||||
case PREALLOC_MODE_FALLOC:
|
||||
/* posix_fallocate() doesn't set errno. */
|
||||
/*
|
||||
* Truncating before posix_fallocate() makes it about twice slower on
|
||||
* file systems that do not support fallocate(), trying to check if a
|
||||
* block is allocated before allocating it, so don't do that here.
|
||||
*/
|
||||
result = -posix_fallocate(fd, 0, total_size);
|
||||
if (result != 0) {
|
||||
/* posix_fallocate() doesn't set errno. */
|
||||
error_setg_errno(errp, -result,
|
||||
"Could not preallocate data for the new file");
|
||||
}
|
||||
@@ -1610,6 +1609,17 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
#endif
|
||||
case PREALLOC_MODE_FULL:
|
||||
{
|
||||
/*
|
||||
* Knowing the final size from the beginning could allow the file
|
||||
* system driver to do less allocations and possibly avoid
|
||||
* fragmentation of the file.
|
||||
*/
|
||||
if (ftruncate(fd, total_size) != 0) {
|
||||
result = -errno;
|
||||
error_setg_errno(errp, -result, "Could not resize file");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
int64_t num = 0, left = total_size;
|
||||
buf = g_malloc0(65536);
|
||||
|
||||
@@ -1636,6 +1646,10 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
break;
|
||||
}
|
||||
case PREALLOC_MODE_OFF:
|
||||
if (ftruncate(fd, total_size) != 0) {
|
||||
result = -errno;
|
||||
error_setg_errno(errp, -result, "Could not resize file");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
|
||||
+22
-28
@@ -662,7 +662,28 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
if (s->bdev_length < 0) {
|
||||
ret = s->bdev_length;
|
||||
goto immediate_exit;
|
||||
} else if (s->bdev_length == 0) {
|
||||
}
|
||||
|
||||
/* Active commit must resize the base image if its size differs from the
|
||||
* active layer. */
|
||||
if (s->base == blk_bs(s->target)) {
|
||||
int64_t base_length;
|
||||
|
||||
base_length = blk_getlength(s->target);
|
||||
if (base_length < 0) {
|
||||
ret = base_length;
|
||||
goto immediate_exit;
|
||||
}
|
||||
|
||||
if (s->bdev_length > base_length) {
|
||||
ret = blk_truncate(s->target, s->bdev_length);
|
||||
if (ret < 0) {
|
||||
goto immediate_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s->bdev_length == 0) {
|
||||
/* Report BLOCK_JOB_READY and wait for complete. */
|
||||
block_job_event_ready(&s->common);
|
||||
s->synced = true;
|
||||
@@ -1063,9 +1084,7 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockCompletionFunc *cb, void *opaque, Error **errp,
|
||||
bool auto_complete)
|
||||
{
|
||||
int64_t length, base_length;
|
||||
int orig_base_flags;
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
orig_base_flags = bdrv_get_flags(base);
|
||||
@@ -1074,31 +1093,6 @@ void commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
return;
|
||||
}
|
||||
|
||||
length = bdrv_getlength(bs);
|
||||
if (length < 0) {
|
||||
error_setg_errno(errp, -length,
|
||||
"Unable to determine length of %s", bs->filename);
|
||||
goto error_restore_flags;
|
||||
}
|
||||
|
||||
base_length = bdrv_getlength(base);
|
||||
if (base_length < 0) {
|
||||
error_setg_errno(errp, -base_length,
|
||||
"Unable to determine length of %s", base->filename);
|
||||
goto error_restore_flags;
|
||||
}
|
||||
|
||||
if (length > base_length) {
|
||||
ret = bdrv_truncate(base, length);
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret,
|
||||
"Top image %s is larger than base image %s, and "
|
||||
"resize of base image failed",
|
||||
bs->filename, base->filename);
|
||||
goto error_restore_flags;
|
||||
}
|
||||
}
|
||||
|
||||
mirror_start_job(job_id, bs, creation_flags, base, NULL, speed, 0, 0,
|
||||
MIRROR_LEAVE_BACKING_CHAIN,
|
||||
on_error, on_error, true, cb, opaque, &local_err,
|
||||
|
||||
+10
-4
@@ -215,7 +215,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
|
||||
s->data_end << BDRV_SECTOR_BITS,
|
||||
space << BDRV_SECTOR_BITS, 0);
|
||||
} else {
|
||||
ret = bdrv_truncate(bs->file->bs,
|
||||
ret = bdrv_truncate(bs->file,
|
||||
(s->data_end + space) << BDRV_SECTOR_BITS);
|
||||
}
|
||||
if (ret < 0) {
|
||||
@@ -449,7 +449,7 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
size - res->image_end_offset);
|
||||
res->leaks += count;
|
||||
if (fix & BDRV_FIX_LEAKS) {
|
||||
ret = bdrv_truncate(bs->file->bs, res->image_end_offset);
|
||||
ret = bdrv_truncate(bs->file, res->image_end_offset);
|
||||
if (ret < 0) {
|
||||
res->check_errors++;
|
||||
return ret;
|
||||
@@ -581,6 +581,12 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error *local_err = NULL;
|
||||
char *buf;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
@@ -681,7 +687,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
goto fail_options;
|
||||
}
|
||||
if (!bdrv_has_zero_init(bs->file->bs) ||
|
||||
bdrv_truncate(bs->file->bs, bdrv_getlength(bs->file->bs)) != 0) {
|
||||
bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs)) != 0) {
|
||||
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
|
||||
}
|
||||
|
||||
@@ -724,7 +730,7 @@ static void parallels_close(BlockDriverState *bs)
|
||||
}
|
||||
|
||||
if (bs->open_flags & BDRV_O_RDWR) {
|
||||
bdrv_truncate(bs->file->bs, s->data_end << BDRV_SECTOR_BITS);
|
||||
bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
|
||||
}
|
||||
|
||||
g_free(s->bat_dirty_bmap);
|
||||
|
||||
+8
-2
@@ -106,6 +106,12 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
QCowHeader header;
|
||||
Error *local_err = NULL;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
@@ -467,7 +473,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
|
||||
/* round to cluster size */
|
||||
cluster_offset = (cluster_offset + s->cluster_size - 1) &
|
||||
~(s->cluster_size - 1);
|
||||
bdrv_truncate(bs->file->bs, cluster_offset + s->cluster_size);
|
||||
bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
|
||||
/* if encrypted, we must initialize the cluster
|
||||
content which won't be written */
|
||||
if (bs->encrypted &&
|
||||
@@ -909,7 +915,7 @@ static int qcow_make_empty(BlockDriverState *bs)
|
||||
if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
|
||||
l1_length) < 0)
|
||||
return -1;
|
||||
ret = bdrv_truncate(bs->file->bs, s->l1_table_offset + l1_length);
|
||||
ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -1734,7 +1734,7 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
goto resize_fail;
|
||||
}
|
||||
|
||||
ret = bdrv_truncate(bs->file->bs, offset + s->cluster_size);
|
||||
ret = bdrv_truncate(bs->file, offset + s->cluster_size);
|
||||
if (ret < 0) {
|
||||
goto resize_fail;
|
||||
}
|
||||
|
||||
+22
-6
@@ -814,8 +814,8 @@ static int qcow2_update_options(BlockDriverState *bs, QDict *options,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
unsigned int len, i;
|
||||
@@ -1205,6 +1205,18 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return qcow2_do_open(bs, options, flags, errp);
|
||||
}
|
||||
|
||||
static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVQcow2State *s = bs->opaque;
|
||||
@@ -1785,7 +1797,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||
options = qdict_clone_shallow(bs->options);
|
||||
|
||||
flags &= ~BDRV_O_INACTIVE;
|
||||
ret = qcow2_open(bs, options, flags, &local_err);
|
||||
ret = qcow2_do_open(bs, options, flags, &local_err);
|
||||
QDECREF(options);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
@@ -2570,7 +2582,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
|
||||
/* align end of file to a sector boundary to ease reading with
|
||||
sector based I/Os */
|
||||
cluster_offset = bdrv_getlength(bs->file->bs);
|
||||
return bdrv_truncate(bs->file->bs, cluster_offset);
|
||||
return bdrv_truncate(bs->file, cluster_offset);
|
||||
}
|
||||
|
||||
buf = qemu_blockalign(bs, s->cluster_size);
|
||||
@@ -2784,7 +2796,7 @@ static int make_completely_empty(BlockDriverState *bs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = bdrv_truncate(bs->file->bs, (3 + l1_clusters) * s->cluster_size);
|
||||
ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -3250,7 +3262,11 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
||||
}
|
||||
|
||||
if (new_size) {
|
||||
ret = bdrv_truncate(bs, new_size);
|
||||
BlockBackend *blk = blk_new();
|
||||
blk_insert_bs(blk, bs);
|
||||
ret = blk_truncate(blk, new_size);
|
||||
blk_unref(blk);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
+15
-3
@@ -415,8 +415,8 @@ static void bdrv_qed_drain(BlockDriverState *bs)
|
||||
}
|
||||
}
|
||||
|
||||
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
static int bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
QEDHeader le_header;
|
||||
@@ -550,6 +550,18 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return bdrv_qed_do_open(bs, options, flags, errp);
|
||||
}
|
||||
|
||||
static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
@@ -1629,7 +1641,7 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs, Error **errp)
|
||||
bdrv_qed_close(bs);
|
||||
|
||||
memset(s, 0, sizeof(BDRVQEDState));
|
||||
ret = bdrv_qed_open(bs, NULL, bs->open_flags, &local_err);
|
||||
ret = bdrv_qed_do_open(bs, NULL, bs->open_flags, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
error_prepend(errp, "Could not reopen qed layer: ");
|
||||
|
||||
+7
-1
@@ -341,7 +341,7 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset)
|
||||
|
||||
s->size = offset;
|
||||
offset += s->offset;
|
||||
return bdrv_truncate(bs->file->bs, offset);
|
||||
return bdrv_truncate(bs->file, offset);
|
||||
}
|
||||
|
||||
static int raw_media_changed(BlockDriverState *bs)
|
||||
@@ -384,6 +384,12 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bs->sg = bs->file->bs->sg;
|
||||
bs->supported_write_flags = BDRV_REQ_FUA &
|
||||
bs->file->bs->supported_write_flags;
|
||||
|
||||
@@ -86,6 +86,12 @@ static int replication_open(BlockDriverState *bs, QDict *options,
|
||||
const char *mode;
|
||||
const char *top_id;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
|
||||
@@ -363,6 +363,12 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int ret;
|
||||
Error *local_err = NULL;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
logout("\n");
|
||||
|
||||
ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1);
|
||||
|
||||
+1
-1
@@ -548,7 +548,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
if (new_file_size % (1024*1024)) {
|
||||
/* round up to nearest 1MB boundary */
|
||||
new_file_size = ((new_file_size >> 20) + 1) << 20;
|
||||
bdrv_truncate(bs->file->bs, new_file_size);
|
||||
bdrv_truncate(bs->file, new_file_size);
|
||||
}
|
||||
}
|
||||
qemu_vfree(desc_entries);
|
||||
|
||||
+7
-1
@@ -898,6 +898,12 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
uint64_t signature;
|
||||
Error *local_err = NULL;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s->bat = NULL;
|
||||
s->first_visible_write = true;
|
||||
|
||||
@@ -1165,7 +1171,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
|
||||
/* per the spec, the address for a block is in units of 1MB */
|
||||
*new_offset = ROUND_UP(*new_offset, 1024 * 1024);
|
||||
|
||||
return bdrv_truncate(bs->file->bs, *new_offset + s->block_size);
|
||||
return bdrv_truncate(bs->file, *new_offset + s->block_size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -943,6 +943,12 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
uint32_t magic;
|
||||
Error *local_err = NULL;
|
||||
|
||||
bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
||||
false, errp);
|
||||
if (!bs->file) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf = vmdk_read_desc(bs->file, 0, errp);
|
||||
if (!buf) {
|
||||
return -EINVAL;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user