From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, berto@igalia.com, qemu-devel@nongnu.org,
jcody@redhat.com, armbru@redhat.com, mreitz@redhat.com,
stefanha@redhat.com
Subject: [Qemu-devel] [PATCH 07/16] block: Convert bs->backing_hd to BdrvChild
Date: Thu, 17 Sep 2015 15:48:11 +0200 [thread overview]
Message-ID: <1442497700-2536-8-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1442497700-2536-1-git-send-email-kwolf@redhat.com>
This is the final step in converting all of the BlockDriverState
pointers that block drivers use to BdrvChild.
After this patch, bs->children contains the full list of child nodes
that are referenced by a given BDS, and these children are only
referenced through BdrvChild, so that updating the pointer in there is
enough for changing edges in the graph.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 116 +++++++++++++++++++++++++---------------------
block/io.c | 24 +++++-----
block/mirror.c | 7 +--
block/qapi.c | 8 ++--
block/qcow.c | 4 +-
block/qcow2-cluster.c | 4 +-
block/qcow2.c | 6 +--
block/qed.c | 12 ++---
block/stream.c | 10 ++--
block/vmdk.c | 21 +++++----
block/vvfat.c | 6 +--
blockdev.c | 6 +--
include/block/block_int.h | 12 +++--
qemu-img.c | 8 ++--
14 files changed, 130 insertions(+), 114 deletions(-)
diff --git a/block.c b/block.c
index 3992241..fb94567 100644
--- a/block.c
+++ b/block.c
@@ -721,7 +721,7 @@ const BdrvChildRole child_format = {
};
/*
- * Returns the flags that bs->backing_hd should get, based on the given flags
+ * Returns the flags that bs->backing should get, based on the given flags
* for the parent BDS
*/
static int bdrv_backing_flags(int flags)
@@ -1115,32 +1115,31 @@ void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child)
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
{
- if (bs->backing_hd) {
+ if (bs->backing) {
assert(bs->backing_blocker);
- bdrv_op_unblock_all(bs->backing_hd, bs->backing_blocker);
- bdrv_detach_child(bs->backing_child);
+ bdrv_op_unblock_all(bs->backing->bs, bs->backing_blocker);
+ bdrv_detach_child(bs->backing);
} else if (backing_hd) {
error_setg(&bs->backing_blocker,
"node is used as backing hd of '%s'",
bdrv_get_device_or_node_name(bs));
}
- bs->backing_hd = backing_hd;
if (!backing_hd) {
error_free(bs->backing_blocker);
bs->backing_blocker = NULL;
- bs->backing_child = NULL;
+ bs->backing = NULL;
goto out;
}
- bs->backing_child = bdrv_attach_child(bs, backing_hd, &child_backing);
+ bs->backing = bdrv_attach_child(bs, backing_hd, &child_backing);
bs->open_flags &= ~BDRV_O_NO_BACKING;
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename);
pstrcpy(bs->backing_format, sizeof(bs->backing_format),
backing_hd->drv ? backing_hd->drv->format_name : "");
- bdrv_op_block_all(bs->backing_hd, bs->backing_blocker);
+ bdrv_op_block_all(backing_hd, bs->backing_blocker);
/* Otherwise we won't be able to commit due to check in bdrv_commit */
- bdrv_op_unblock(bs->backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
+ bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
bs->backing_blocker);
out:
bdrv_refresh_limits(bs, NULL);
@@ -1161,7 +1160,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
BlockDriverState *backing_hd;
Error *local_err = NULL;
- if (bs->backing_hd != NULL) {
+ if (bs->backing != NULL) {
QDECREF(options);
goto free_exit;
}
@@ -1201,7 +1200,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
qdict_put(options, "driver", qstring_from_str(bs->backing_format));
}
- assert(bs->backing_hd == NULL);
+ assert(bs->backing == NULL);
ret = bdrv_open_inherit(&backing_hd,
*backing_filename ? backing_filename : NULL,
NULL, options, 0, bs, &child_backing, &local_err);
@@ -1885,8 +1884,8 @@ void bdrv_close(BlockDriverState *bs)
bs->drv->bdrv_close(bs);
- if (bs->backing_hd) {
- BlockDriverState *backing_hd = bs->backing_hd;
+ if (bs->backing) {
+ BlockDriverState *backing_hd = bs->backing->bs;
bdrv_set_backing_hd(bs, NULL);
bdrv_unref(backing_hd);
}
@@ -2204,20 +2203,20 @@ int bdrv_commit(BlockDriverState *bs)
if (!drv)
return -ENOMEDIUM;
- if (!bs->backing_hd) {
+ if (!bs->backing) {
return -ENOTSUP;
}
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, NULL) ||
- bdrv_op_is_blocked(bs->backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) {
+ bdrv_op_is_blocked(bs->backing->bs, BLOCK_OP_TYPE_COMMIT_TARGET, NULL)) {
return -EBUSY;
}
- ro = bs->backing_hd->read_only;
- open_flags = bs->backing_hd->open_flags;
+ ro = bs->backing->bs->read_only;
+ open_flags = bs->backing->bs->open_flags;
if (ro) {
- if (bdrv_reopen(bs->backing_hd, open_flags | BDRV_O_RDWR, NULL)) {
+ if (bdrv_reopen(bs->backing->bs, open_flags | BDRV_O_RDWR, NULL)) {
return -EACCES;
}
}
@@ -2228,7 +2227,7 @@ int bdrv_commit(BlockDriverState *bs)
goto ro_cleanup;
}
- backing_length = bdrv_getlength(bs->backing_hd);
+ backing_length = bdrv_getlength(bs->backing->bs);
if (backing_length < 0) {
ret = backing_length;
goto ro_cleanup;
@@ -2238,7 +2237,7 @@ int bdrv_commit(BlockDriverState *bs)
* grow the backing file image if possible. If not possible,
* we must return an error */
if (length > backing_length) {
- ret = bdrv_truncate(bs->backing_hd, length);
+ ret = bdrv_truncate(bs->backing->bs, length);
if (ret < 0) {
goto ro_cleanup;
}
@@ -2247,7 +2246,7 @@ int bdrv_commit(BlockDriverState *bs)
total_sectors = length >> BDRV_SECTOR_BITS;
/* qemu_try_blockalign() for bs will choose an alignment that works for
- * bs->backing_hd as well, so no need to compare the alignment manually. */
+ * bs->backing->bs as well, so no need to compare the alignment manually. */
buf = qemu_try_blockalign(bs, COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
if (buf == NULL) {
ret = -ENOMEM;
@@ -2265,7 +2264,7 @@ int bdrv_commit(BlockDriverState *bs)
goto ro_cleanup;
}
- ret = bdrv_write(bs->backing_hd, sector, buf, n);
+ ret = bdrv_write(bs->backing->bs, sector, buf, n);
if (ret < 0) {
goto ro_cleanup;
}
@@ -2284,8 +2283,8 @@ int bdrv_commit(BlockDriverState *bs)
* Make sure all data we wrote to the backing device is actually
* stable on disk.
*/
- if (bs->backing_hd) {
- bdrv_flush(bs->backing_hd);
+ if (bs->backing) {
+ bdrv_flush(bs->backing->bs);
}
ret = 0;
@@ -2294,7 +2293,7 @@ ro_cleanup:
if (ro) {
/* ignoring error return here */
- bdrv_reopen(bs->backing_hd, open_flags & ~BDRV_O_RDWR, NULL);
+ bdrv_reopen(bs->backing->bs, open_flags & ~BDRV_O_RDWR, NULL);
}
return ret;
@@ -2308,7 +2307,7 @@ int bdrv_commit_all(void)
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
- if (bs->drv && bs->backing_hd) {
+ if (bs->drv && bs->backing) {
int ret = bdrv_commit(bs);
if (ret < 0) {
aio_context_release(aio_context);
@@ -2365,11 +2364,20 @@ int bdrv_change_backing_file(BlockDriverState *bs,
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
BlockDriverState *bs)
{
- while (active && bs != active->backing_hd) {
- active = active->backing_hd;
+ while (active) {
+ if (active->backing) {
+ if (bs == active->backing->bs) {
+ return active;
+ }
+ active = active->backing->bs;
+ } else if (bs == NULL) {
+ return active;
+ } else {
+ return NULL;
+ }
}
- return active;
+ return NULL;
}
/* Given a BDS, searches for the base layer. */
@@ -2436,9 +2444,9 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
goto exit;
}
- /* special case of new_top_bs->backing_hd already pointing to base - nothing
+ /* special case of new_top_bs->backing->bs already pointing to base - nothing
* to do, no intermediate images */
- if (new_top_bs->backing_hd == base) {
+ if (backing_bs(new_top_bs) == base) {
ret = 0;
goto exit;
}
@@ -2453,11 +2461,11 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
intermediate_state->bs = intermediate;
QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry);
- if (intermediate->backing_hd == base) {
- base_bs = intermediate->backing_hd;
+ if (backing_bs(intermediate) == base) {
+ base_bs = backing_bs(intermediate);
break;
}
- intermediate = intermediate->backing_hd;
+ intermediate = backing_bs(intermediate);
}
if (base_bs == NULL) {
/* something went wrong, we did not end at the base. safely
@@ -2676,25 +2684,27 @@ void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)
int bdrv_is_encrypted(BlockDriverState *bs)
{
- if (bs->backing_hd && bs->backing_hd->encrypted)
+ if (bs->backing && bs->backing->bs->encrypted) {
return 1;
+ }
return bs->encrypted;
}
int bdrv_key_required(BlockDriverState *bs)
{
- BlockDriverState *backing_hd = bs->backing_hd;
+ BdrvChild *backing = bs->backing;
- if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
+ if (backing && backing->bs->encrypted && !backing->bs->valid_key) {
return 1;
+ }
return (bs->encrypted && !bs->valid_key);
}
int bdrv_set_key(BlockDriverState *bs, const char *key)
{
int ret;
- if (bs->backing_hd && bs->backing_hd->encrypted) {
- ret = bdrv_set_key(bs->backing_hd, key);
+ if (bs->backing && bs->backing->bs->encrypted) {
+ ret = bdrv_set_key(bs->backing->bs, key);
if (ret < 0)
return ret;
if (!bs->encrypted)
@@ -2861,7 +2871,7 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
{
while (top && top != base) {
- top = top->backing_hd;
+ top = backing_bs(top);
}
return top != NULL;
@@ -2919,7 +2929,7 @@ int bdrv_has_zero_init(BlockDriverState *bs)
/* If BS is a copy on write image, it is initialized to
the contents of the base image, which may not be zeroes. */
- if (bs->backing_hd) {
+ if (bs->backing) {
return 0;
}
if (bs->drv->bdrv_has_zero_init) {
@@ -2934,7 +2944,7 @@ bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs)
{
BlockDriverInfo bdi;
- if (bs->backing_hd) {
+ if (bs->backing) {
return false;
}
@@ -2949,7 +2959,7 @@ bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
{
BlockDriverInfo bdi;
- if (bs->backing_hd || !(bs->open_flags & BDRV_O_UNMAP)) {
+ if (bs->backing || !(bs->open_flags & BDRV_O_UNMAP)) {
return false;
}
@@ -2962,7 +2972,7 @@ bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
{
- if (bs->backing_hd && bs->backing_hd->encrypted)
+ if (bs->backing && bs->backing->bs->encrypted)
return bs->backing_file;
else if (bs->encrypted)
return bs->filename;
@@ -3087,13 +3097,13 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
is_protocol = path_has_protocol(backing_file);
- for (curr_bs = bs; curr_bs->backing_hd; curr_bs = curr_bs->backing_hd) {
+ for (curr_bs = bs; curr_bs->backing; curr_bs = curr_bs->backing->bs) {
/* If either of the filename paths is actually a protocol, then
* compare unmodified paths; otherwise make paths relative */
if (is_protocol || path_has_protocol(curr_bs->backing_file)) {
if (strcmp(backing_file, curr_bs->backing_file) == 0) {
- retval = curr_bs->backing_hd;
+ retval = curr_bs->backing->bs;
break;
}
} else {
@@ -3117,7 +3127,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
}
if (strcmp(backing_file_full, filename_full) == 0) {
- retval = curr_bs->backing_hd;
+ retval = curr_bs->backing->bs;
break;
}
}
@@ -3135,11 +3145,11 @@ int bdrv_get_backing_file_depth(BlockDriverState *bs)
return 0;
}
- if (!bs->backing_hd) {
+ if (!bs->backing) {
return 0;
}
- return 1 + bdrv_get_backing_file_depth(bs->backing_hd);
+ return 1 + bdrv_get_backing_file_depth(bs->backing->bs);
}
void bdrv_init(void)
@@ -3902,8 +3912,8 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
if (bs->file) {
bdrv_detach_aio_context(bs->file->bs);
}
- if (bs->backing_hd) {
- bdrv_detach_aio_context(bs->backing_hd);
+ if (bs->backing) {
+ bdrv_detach_aio_context(bs->backing->bs);
}
bs->aio_context = NULL;
@@ -3920,8 +3930,8 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
bs->aio_context = new_context;
- if (bs->backing_hd) {
- bdrv_attach_aio_context(bs->backing_hd, new_context);
+ if (bs->backing) {
+ bdrv_attach_aio_context(bs->backing->bs, new_context);
}
if (bs->file) {
bdrv_attach_aio_context(bs->file->bs, new_context);
diff --git a/block/io.c b/block/io.c
index 8a27efa..d7e742a 100644
--- a/block/io.c
+++ b/block/io.c
@@ -170,24 +170,24 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
bs->bl.opt_mem_alignment = getpagesize();
}
- if (bs->backing_hd) {
- bdrv_refresh_limits(bs->backing_hd, &local_err);
+ if (bs->backing) {
+ bdrv_refresh_limits(bs->backing->bs, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
bs->bl.opt_transfer_length =
MAX(bs->bl.opt_transfer_length,
- bs->backing_hd->bl.opt_transfer_length);
+ bs->backing->bs->bl.opt_transfer_length);
bs->bl.max_transfer_length =
MIN_NON_ZERO(bs->bl.max_transfer_length,
- bs->backing_hd->bl.max_transfer_length);
+ bs->backing->bs->bl.max_transfer_length);
bs->bl.opt_mem_alignment =
MAX(bs->bl.opt_mem_alignment,
- bs->backing_hd->bl.opt_mem_alignment);
+ bs->backing->bs->bl.opt_mem_alignment);
bs->bl.min_mem_alignment =
MAX(bs->bl.min_mem_alignment,
- bs->backing_hd->bl.min_mem_alignment);
+ bs->backing->bs->bl.min_mem_alignment);
}
/* Then let the driver override it */
@@ -227,7 +227,7 @@ static bool bdrv_requests_pending(BlockDriverState *bs)
if (bs->file && bdrv_requests_pending(bs->file->bs)) {
return true;
}
- if (bs->backing_hd && bdrv_requests_pending(bs->backing_hd)) {
+ if (bs->backing && bdrv_requests_pending(bs->backing->bs)) {
return true;
}
return false;
@@ -1495,8 +1495,8 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
} else {
if (bdrv_unallocated_blocks_are_zero(bs)) {
ret |= BDRV_BLOCK_ZERO;
- } else if (bs->backing_hd) {
- BlockDriverState *bs2 = bs->backing_hd;
+ } else if (bs->backing) {
+ BlockDriverState *bs2 = bs->backing->bs;
int64_t nb_sectors2 = bdrv_nb_sectors(bs2);
if (nb_sectors2 >= 0 && sector_num >= nb_sectors2) {
ret |= BDRV_BLOCK_ZERO;
@@ -1541,7 +1541,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,
int64_t ret = 0;
assert(bs != base);
- for (p = bs; p != base; p = p->backing_hd) {
+ for (p = bs; p != base; p = backing_bs(p)) {
ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum);
if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) {
break;
@@ -1604,7 +1604,7 @@ int64_t bdrv_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
{
- return bdrv_get_block_status_above(bs, bs->backing_hd,
+ return bdrv_get_block_status_above(bs, backing_bs(bs),
sector_num, nb_sectors, pnum);
}
@@ -1662,7 +1662,7 @@ int bdrv_is_allocated_above(BlockDriverState *top,
n = pnum_inter;
}
- intermediate = intermediate->backing_hd;
+ intermediate = intermediate->backing ? intermediate->backing->bs : NULL;
}
*pnum = n;
diff --git a/block/mirror.c b/block/mirror.c
index a258926..259e11a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -371,7 +371,8 @@ static void mirror_exit(BlockJob *job, void *opaque)
if (s->common.driver->job_type == BLOCK_JOB_TYPE_COMMIT) {
/* drop the bs loop chain formed by the swap: break the loop then
* trigger the unref from the top one */
- BlockDriverState *p = s->base->backing_hd;
+ BlockDriverState *p = s->base->backing
+ ? s->base->backing->bs : NULL;
bdrv_set_backing_hd(s->base, NULL);
bdrv_unref(p);
}
@@ -431,7 +432,7 @@ static void coroutine_fn mirror_run(void *opaque)
*/
bdrv_get_backing_filename(s->target, backing_filename,
sizeof(backing_filename));
- if (backing_filename[0] && !s->target->backing_hd) {
+ if (backing_filename[0] && !s->target->backing) {
ret = bdrv_get_info(s->target, &bdi);
if (ret < 0) {
goto immediate_exit;
@@ -764,7 +765,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
return;
}
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
- base = mode == MIRROR_SYNC_MODE_TOP ? bs->backing_hd : NULL;
+ base = mode == MIRROR_SYNC_MODE_TOP && bs->backing ? bs->backing->bs : NULL;
mirror_start_job(bs, target, replaces,
speed, granularity, buf_size,
on_source_error, on_target_error, unmap, cb, opaque, errp,
diff --git a/block/qapi.c b/block/qapi.c
index 0c4654e..355ba32 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -110,8 +110,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp)
qapi_free_BlockDeviceInfo(info);
return NULL;
}
- if (bs0->drv && bs0->backing_hd) {
- bs0 = bs0->backing_hd;
+ if (bs0->drv && bs0->backing) {
+ bs0 = bs0->backing->bs;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
@@ -362,9 +362,9 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
s->parent = bdrv_query_stats(bs->file->bs, query_backing);
}
- if (query_backing && bs->backing_hd) {
+ if (query_backing && bs->backing) {
s->has_backing = true;
- s->backing = bdrv_query_stats(bs->backing_hd, query_backing);
+ s->backing = bdrv_query_stats(bs->backing->bs, query_backing);
}
return s;
diff --git a/block/qcow.c b/block/qcow.c
index 4d20cd5..b0f2d96 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -596,13 +596,13 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
}
if (!cluster_offset) {
- if (bs->backing_hd) {
+ if (bs->backing) {
/* read from the base image */
hd_iov.iov_base = (void *)buf;
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->backing_hd, sector_num,
+ ret = bdrv_co_readv(bs->backing->bs, sector_num,
n, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 7844f8e..71a8d13 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1474,7 +1474,7 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
*/
switch (qcow2_get_cluster_type(old_l2_entry)) {
case QCOW2_CLUSTER_UNALLOCATED:
- if (full_discard || !bs->backing_hd) {
+ if (full_discard || !bs->backing) {
continue;
}
break;
@@ -1708,7 +1708,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
}
if (!preallocated) {
- if (!bs->backing_hd) {
+ if (!bs->backing) {
/* not backed; therefore we can simply deallocate the
* cluster */
l2_table[j] = 0;
diff --git a/block/qcow2.c b/block/qcow2.c
index 38b2797..bacc4f2 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1369,9 +1369,9 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
switch (ret) {
case QCOW2_CLUSTER_UNALLOCATED:
- if (bs->backing_hd) {
+ if (bs->backing) {
/* read from the base image */
- n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
+ n1 = qcow2_backing_read1(bs->backing->bs, &hd_qiov,
sector_num, cur_nr_sectors);
if (n1 > 0) {
QEMUIOVector local_qiov;
@@ -1382,7 +1382,7 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
qemu_co_mutex_unlock(&s->lock);
- ret = bdrv_co_readv(bs->backing_hd, sector_num,
+ ret = bdrv_co_readv(bs->backing->bs, sector_num,
n1, &local_qiov);
qemu_co_mutex_lock(&s->lock);
diff --git a/block/qed.c b/block/qed.c
index d953f8c..0af81dc 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -772,8 +772,8 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
/* If there is a backing file, get its length. Treat the absence of a
* backing file like a zero length backing file.
*/
- if (s->bs->backing_hd) {
- int64_t l = bdrv_getlength(s->bs->backing_hd);
+ if (s->bs->backing) {
+ int64_t l = bdrv_getlength(s->bs->backing->bs);
if (l < 0) {
cb(opaque, l);
return;
@@ -802,7 +802,7 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos,
qemu_iovec_concat(*backing_qiov, qiov, 0, size);
BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO);
- bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE,
+ bdrv_aio_readv(s->bs->backing->bs, pos / BDRV_SECTOR_SIZE,
*backing_qiov, size / BDRV_SECTOR_SIZE, cb, opaque);
}
@@ -1081,7 +1081,7 @@ static void qed_aio_write_main(void *opaque, int ret)
if (acb->find_cluster_ret == QED_CLUSTER_FOUND) {
next_fn = qed_aio_next_io;
} else {
- if (s->bs->backing_hd) {
+ if (s->bs->backing) {
next_fn = qed_aio_write_flush_before_l2_update;
} else {
next_fn = qed_aio_write_l2_update_cb;
@@ -1139,7 +1139,7 @@ static void qed_aio_write_prefill(void *opaque, int ret)
static bool qed_should_set_need_check(BDRVQEDState *s)
{
/* The flush before L2 update path ensures consistency */
- if (s->bs->backing_hd) {
+ if (s->bs->backing) {
return false;
}
@@ -1443,7 +1443,7 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs,
struct iovec iov;
/* Refuse if there are untouched backing file sectors */
- if (bs->backing_hd) {
+ if (bs->backing) {
if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) {
return -ENOTSUP;
}
diff --git a/block/stream.c b/block/stream.c
index ab0bd05..ece7b58 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -56,7 +56,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
const char *base_id)
{
BlockDriverState *intermediate;
- intermediate = top->backing_hd;
+ intermediate = top->backing ? top->backing->bs : NULL;
/* Must assign before bdrv_delete() to prevent traversing dangling pointer
* while we delete backing image instances.
@@ -72,7 +72,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
}
unused = intermediate;
- intermediate = intermediate->backing_hd;
+ intermediate = intermediate->backing ? intermediate->backing->bs : NULL;
bdrv_set_backing_hd(unused, NULL);
bdrv_unref(unused);
}
@@ -121,7 +121,7 @@ static void coroutine_fn stream_run(void *opaque)
int n = 0;
void *buf;
- if (!bs->backing_hd) {
+ if (!bs->backing) {
block_job_completed(&s->common, 0);
return;
}
@@ -166,8 +166,8 @@ wait:
} else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [sector_num, sector_num+n). */
- ret = bdrv_is_allocated_above(bs->backing_hd, base,
- sector_num, n, &n);
+ ret = bdrv_is_allocated_above(bs->backing ? bs->backing->bs : NULL,
+ base, sector_num, n, &n);
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
diff --git a/block/vmdk.c b/block/vmdk.c
index 9f7e7db..0effb7d 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -308,10 +308,11 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
static int vmdk_is_cid_valid(BlockDriverState *bs)
{
BDRVVmdkState *s = bs->opaque;
- BlockDriverState *p_bs = bs->backing_hd;
uint32_t cur_pcid;
- if (!s->cid_checked && p_bs) {
+ if (!s->cid_checked && bs->backing) {
+ BlockDriverState *p_bs = bs->backing->bs;
+
cur_pcid = vmdk_read_cid(p_bs, 0);
if (s->parent_cid != cur_pcid) {
/* CID not valid */
@@ -1006,7 +1007,7 @@ static int get_whole_cluster(BlockDriverState *bs,
cluster_bytes = extent->cluster_sectors << BDRV_SECTOR_BITS;
whole_grain = qemu_blockalign(bs, cluster_bytes);
- if (!bs->backing_hd) {
+ if (!bs->backing) {
memset(whole_grain, 0, skip_start_sector << BDRV_SECTOR_BITS);
memset(whole_grain + (skip_end_sector << BDRV_SECTOR_BITS), 0,
cluster_bytes - (skip_end_sector << BDRV_SECTOR_BITS));
@@ -1015,15 +1016,15 @@ static int get_whole_cluster(BlockDriverState *bs,
assert(skip_end_sector <= extent->cluster_sectors);
/* we will be here if it's first write on non-exist grain(cluster).
* try to read from parent image, if exist */
- if (bs->backing_hd && !vmdk_is_cid_valid(bs)) {
+ if (bs->backing && !vmdk_is_cid_valid(bs)) {
ret = VMDK_ERROR;
goto exit;
}
/* Read backing data before skip range */
if (skip_start_sector > 0) {
- if (bs->backing_hd) {
- ret = bdrv_read(bs->backing_hd, sector_num,
+ if (bs->backing) {
+ ret = bdrv_read(bs->backing->bs, sector_num,
whole_grain, skip_start_sector);
if (ret < 0) {
ret = VMDK_ERROR;
@@ -1039,8 +1040,8 @@ static int get_whole_cluster(BlockDriverState *bs,
}
/* Read backing data after skip range */
if (skip_end_sector < extent->cluster_sectors) {
- if (bs->backing_hd) {
- ret = bdrv_read(bs->backing_hd, sector_num + skip_end_sector,
+ if (bs->backing) {
+ ret = bdrv_read(bs->backing->bs, sector_num + skip_end_sector,
whole_grain + (skip_end_sector << BDRV_SECTOR_BITS),
extent->cluster_sectors - skip_end_sector);
if (ret < 0) {
@@ -1433,11 +1434,11 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
}
if (ret != VMDK_OK) {
/* if not allocated, try to read from parent image, if exist */
- if (bs->backing_hd && ret != VMDK_ZEROED) {
+ if (bs->backing && ret != VMDK_ZEROED) {
if (!vmdk_is_cid_valid(bs)) {
return -EINVAL;
}
- ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
+ ret = bdrv_read(bs->backing->bs, sector_num, buf, n);
if (ret < 0) {
return ret;
}
diff --git a/block/vvfat.c b/block/vvfat.c
index 7ddc962..7c4b0f5 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2972,9 +2972,9 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
#endif
bdrv_set_backing_hd(s->bs, bdrv_new());
- s->bs->backing_hd->drv = &vvfat_write_target;
- s->bs->backing_hd->opaque = g_new(void *, 1);
- *(void**)s->bs->backing_hd->opaque = s;
+ s->bs->backing->bs->drv = &vvfat_write_target;
+ s->bs->backing->bs->opaque = g_new(void *, 1);
+ *(void**)s->bs->backing->bs->opaque = s;
return 0;
diff --git a/blockdev.c b/blockdev.c
index 32b04b4..bc158ff 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2508,10 +2508,10 @@ void qmp_drive_backup(const char *device, const char *target,
/* See if we have a backing HD we can use to create our new image
* on top of. */
if (sync == MIRROR_SYNC_MODE_TOP) {
- source = bs->backing_hd;
- if (!source) {
+ if (!bs->backing) {
sync = MIRROR_SYNC_MODE_FULL;
}
+ source = bs->backing->bs;
}
if (sync == MIRROR_SYNC_MODE_NONE) {
source = bs;
@@ -2716,7 +2716,7 @@ void qmp_drive_mirror(const char *device, const char *target,
}
flags = bs->open_flags | BDRV_O_RDWR;
- source = bs->backing_hd;
+ source = bs->backing ? bs->backing->bs : NULL;
if (!source && sync == MIRROR_SYNC_MODE_TOP) {
sync = MIRROR_SYNC_MODE_FULL;
}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 98936c9..90971c0 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -378,8 +378,7 @@ struct BlockDriverState {
QDict *full_open_options;
char exact_filename[PATH_MAX];
- BlockDriverState *backing_hd;
- BdrvChild *backing_child;
+ BdrvChild *backing;
BdrvChild *file;
NotifierList close_notifiers;
@@ -458,6 +457,11 @@ struct BlockDriverState {
NotifierWithReturn write_threshold_notifier;
};
+static inline BlockDriverState *backing_bs(BlockDriverState *bs)
+{
+ return bs->backing ? bs->backing->bs : NULL;
+}
+
/* Essential block drivers which must always be statically linked into qemu, and
* which therefore can be accessed without using bdrv_find_format() */
@@ -496,7 +500,7 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
*
* May be called from .bdrv_detach_aio_context() to detach children from the
* current #AioContext. This is only needed by block drivers that manage their
- * own children. Both ->file and ->backing_hd are automatically handled and
+ * own children. Both ->file and ->backing are automatically handled and
* block drivers should not call this function on them explicitly.
*/
void bdrv_detach_aio_context(BlockDriverState *bs);
@@ -506,7 +510,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs);
*
* May be called from .bdrv_attach_aio_context() to attach children to the new
* #AioContext. This is only needed by block drivers that manage their own
- * children. Both ->file and ->backing_hd are automatically handled and block
+ * children. Both ->file and ->backing are automatically handled and block
* drivers should not call this function on them explicitly.
*/
void bdrv_attach_aio_context(BlockDriverState *bs,
diff --git a/qemu-img.c b/qemu-img.c
index 6ff4e85..c4454da 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -747,11 +747,11 @@ static int img_commit(int argc, char **argv)
/* This is different from QMP, which by default uses the deepest file in
* the backing chain (i.e., the very base); however, the traditional
* behavior of qemu-img commit is using the immediate backing file. */
- base_bs = bs->backing_hd;
- if (!base_bs) {
+ if (!bs->backing) {
error_setg(&local_err, "Image does not have a backing file");
goto done;
}
+ base_bs = bs->backing->bs;
}
cbi = (CommonBlockJobCBInfo){
@@ -2206,11 +2206,11 @@ static int get_block_status(BlockDriverState *bs, int64_t sector_num,
if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) {
break;
}
- bs = bs->backing_hd;
- if (bs == NULL) {
+ if (bs->backing == NULL) {
ret = 0;
break;
}
+ bs = bs->backing->bs;
depth++;
}
--
1.8.3.1
next prev parent reply other threads:[~2015-09-17 13:49 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-17 13:48 [Qemu-devel] [PATCH 00/16] block: Get rid of bdrv_swap() Kevin Wolf
2015-09-17 13:48 ` [Qemu-devel] [PATCH 01/16] block: Introduce BDS.file_child Kevin Wolf
2015-09-22 17:14 ` Max Reitz
2015-09-22 17:17 ` Max Reitz
2015-09-23 14:26 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 02/16] vmdk: Use BdrvChild instead of BDS for references to extents Kevin Wolf
2015-09-22 17:45 ` Max Reitz
2015-09-23 13:23 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 03/16] blkverify: Convert s->test_file to BdrvChild Kevin Wolf
2015-09-22 17:51 ` Max Reitz
2015-09-23 13:01 ` Alberto Garcia
2015-09-23 13:58 ` Kevin Wolf
2015-09-23 14:05 ` Alberto Garcia
2015-09-23 14:11 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 04/16] quorum: Convert " Kevin Wolf
2015-09-22 17:57 ` Max Reitz
2015-09-23 12:48 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 05/16] block: Convert bs->file " Kevin Wolf
2015-09-22 18:36 ` Max Reitz
2015-09-23 13:13 ` Kevin Wolf
2015-09-23 14:54 ` Alberto Garcia
2015-09-25 14:09 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 06/16] block: Remove bdrv_open_image() Kevin Wolf
2015-09-22 18:38 ` Max Reitz
2015-09-23 13:10 ` Alberto Garcia
2015-09-17 13:48 ` Kevin Wolf [this message]
2015-09-22 19:21 ` [Qemu-devel] [PATCH 07/16] block: Convert bs->backing_hd to BdrvChild Max Reitz
2015-09-17 13:48 ` [Qemu-devel] [PATCH 08/16] block: Manage backing file references in bdrv_set_backing_hd() Kevin Wolf
2015-09-23 15:22 ` Max Reitz
2015-09-28 12:29 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 09/16] block: Split bdrv_move_feature_fields() Kevin Wolf
2015-09-23 16:36 ` Max Reitz
2015-09-29 13:37 ` Kevin Wolf
2015-09-30 14:51 ` Max Reitz
2015-09-17 13:48 ` [Qemu-devel] [PATCH 10/16] block/io: Make bdrv_requests_pending() public Kevin Wolf
2015-09-23 15:40 ` Max Reitz
2015-09-29 12:29 ` Kevin Wolf
2015-09-28 12:32 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 11/16] block-backend: Add blk_set_bs() Kevin Wolf
2015-09-23 15:46 ` Max Reitz
2015-09-23 15:51 ` Kevin Wolf
2015-09-17 13:48 ` [Qemu-devel] [PATCH 12/16] block: Introduce parents list Kevin Wolf
2015-09-23 16:39 ` Max Reitz
2015-09-28 13:09 ` Alberto Garcia
2015-09-29 12:21 ` Kevin Wolf
2015-09-29 14:00 ` Alberto Garcia
2015-09-17 13:48 ` [Qemu-devel] [PATCH 13/16] block: Implement bdrv_append() without bdrv_swap() Kevin Wolf
2015-09-18 11:45 ` Alberto Garcia
2015-09-18 12:24 ` Kevin Wolf
2015-09-18 13:31 ` Alberto Garcia
2015-09-18 14:23 ` Kevin Wolf
2015-09-23 16:36 ` Max Reitz
2015-09-29 13:51 ` Kevin Wolf
2015-09-30 14:45 ` Max Reitz
2015-09-30 15:33 ` Kevin Wolf
2015-09-17 13:48 ` [Qemu-devel] [PATCH 14/16] blockjob: Store device name at job creation Kevin Wolf
2015-09-23 16:46 ` Max Reitz
2015-09-17 13:48 ` [Qemu-devel] [PATCH 15/16] block: Add and use bdrv_replace_in_backing_chain() Kevin Wolf
2015-09-23 17:08 ` Max Reitz
2015-09-29 15:22 ` Kevin Wolf
2015-09-30 14:50 ` Max Reitz
2015-09-30 14:50 ` Max Reitz
2015-09-17 13:48 ` [Qemu-devel] [PATCH 16/16] block: Remove bdrv_swap() Kevin Wolf
2015-09-23 17:09 ` Max Reitz
2015-09-28 13:24 ` Alberto Garcia
2015-09-18 11:03 ` [Qemu-devel] [PATCH 00/16] block: Get rid of bdrv_swap() Alberto Garcia
2015-09-22 10:07 ` Kevin Wolf
2015-09-24 18:32 ` Alberto Garcia
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1442497700-2536-8-git-send-email-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=armbru@redhat.com \
--cc=berto@igalia.com \
--cc=jcody@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.