From: Fam Zheng <famz@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: berto@igalia.com, qemu-block@nongnu.org, armbru@redhat.com,
jcody@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com,
stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH v2 05/16] block: Convert bs->file to BdrvChild
Date: Thu, 8 Oct 2015 18:23:01 +0800 [thread overview]
Message-ID: <20151008102301.GA10388@ad.nay.redhat.com> (raw)
In-Reply-To: <1443705214-9304-6-git-send-email-kwolf@redhat.com>
On Thu, 10/01 15:13, Kevin Wolf wrote:
> @@ -1935,6 +1932,11 @@ void bdrv_close(BlockDriverState *bs)
> bdrv_unref(backing_hd);
> }
>
> + if (bs->file != NULL) {
> + bdrv_unref_child(bs, bs->file);
> + bs->file = NULL;
> + }
> +
> QLIST_FOREACH_SAFE(child, &bs->children, next, next) {
> /* TODO Remove bdrv_unref() from drivers' close function and use
> * bdrv_unref_child() here */
> @@ -1946,7 +1948,6 @@ void bdrv_close(BlockDriverState *bs)
>
> g_free(bs->opaque);
> bs->opaque = NULL;
> - bs->drv = NULL;
> bs->copy_on_read = 0;
> bs->backing_file[0] = '\0';
> bs->backing_format[0] = '\0';
> @@ -1959,11 +1960,6 @@ void bdrv_close(BlockDriverState *bs)
> bs->options = NULL;
> QDECREF(bs->full_open_options);
> bs->full_open_options = NULL;
> -
> - if (bs->file != NULL) {
> - bdrv_unref(bs->file);
> - bs->file = NULL;
> - }
Why do you need to move them up? Changing bdrv_unref to bdrv_unref_child is not
enough?
> }
>
> if (bs->blk) {
> @@ -2566,7 +2562,7 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
> return drv->bdrv_get_allocated_file_size(bs);
> }
> if (bs->file) {
> - return bdrv_get_allocated_file_size(bs->file);
> + return bdrv_get_allocated_file_size(bs->file->bs);
> }
> return -ENOTSUP;
> }
> @@ -3048,7 +3044,7 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
> const char *tag)
> {
> while (bs && bs->drv && !bs->drv->bdrv_debug_breakpoint) {
> - bs = bs->file;
> + bs = bs->file ? bs->file->bs : NULL;
> }
>
> if (bs && bs->drv && bs->drv->bdrv_debug_breakpoint) {
> @@ -3061,7 +3057,7 @@ int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
> int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
> {
> while (bs && bs->drv && !bs->drv->bdrv_debug_remove_breakpoint) {
> - bs = bs->file;
> + bs = bs->file ? bs->file->bs : NULL;
> }
>
> if (bs && bs->drv && bs->drv->bdrv_debug_remove_breakpoint) {
> @@ -3074,7 +3070,7 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
> int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
> {
> while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) {
> - bs = bs->file;
> + bs = bs->file ? bs->file->bs : NULL;
> }
>
> if (bs && bs->drv && bs->drv->bdrv_debug_resume) {
> @@ -3087,7 +3083,7 @@ int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
> bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
> {
> while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {
> - bs = bs->file;
> + bs = bs->file ? bs->file->bs : NULL;
> }
>
> if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) {
> @@ -3209,7 +3205,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
> if (bs->drv->bdrv_invalidate_cache) {
> bs->drv->bdrv_invalidate_cache(bs, &local_err);
> } else if (bs->file) {
> - bdrv_invalidate_cache(bs->file, &local_err);
> + bdrv_invalidate_cache(bs->file->bs, &local_err);
> }
> if (local_err) {
> error_propagate(errp, local_err);
> @@ -3939,7 +3935,7 @@ void bdrv_detach_aio_context(BlockDriverState *bs)
> bs->drv->bdrv_detach_aio_context(bs);
> }
> if (bs->file) {
> - bdrv_detach_aio_context(bs->file);
> + bdrv_detach_aio_context(bs->file->bs);
> }
> if (bs->backing_hd) {
> bdrv_detach_aio_context(bs->backing_hd);
> @@ -3963,7 +3959,7 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
> bdrv_attach_aio_context(bs->backing_hd, new_context);
> }
> if (bs->file) {
> - bdrv_attach_aio_context(bs->file, new_context);
> + bdrv_attach_aio_context(bs->file->bs, new_context);
> }
> if (bs->drv->bdrv_attach_aio_context) {
> bs->drv->bdrv_attach_aio_context(bs, new_context);
> @@ -4175,7 +4171,7 @@ void bdrv_refresh_filename(BlockDriverState *bs)
> /* This BDS's file name will most probably depend on its file's name, so
> * refresh that first */
> if (bs->file) {
> - bdrv_refresh_filename(bs->file);
> + bdrv_refresh_filename(bs->file->bs);
> }
>
> if (drv->bdrv_refresh_filename) {
> @@ -4203,19 +4199,20 @@ void bdrv_refresh_filename(BlockDriverState *bs)
>
> /* If no specific options have been given for this BDS, the filename of
> * the underlying file should suffice for this one as well */
> - if (bs->file->exact_filename[0] && !has_open_options) {
> - strcpy(bs->exact_filename, bs->file->exact_filename);
> + if (bs->file->bs->exact_filename[0] && !has_open_options) {
> + strcpy(bs->exact_filename, bs->file->bs->exact_filename);
> }
> /* Reconstructing the full options QDict is simple for most format block
> * drivers, as long as the full options are known for the underlying
> * file BDS. The full options QDict of that file BDS should somehow
> * contain a representation of the filename, therefore the following
> * suffices without querying the (exact_)filename of this BDS. */
> - if (bs->file->full_open_options) {
> + if (bs->file->bs->full_open_options) {
> qdict_put_obj(opts, "driver",
> QOBJECT(qstring_from_str(drv->format_name)));
> - QINCREF(bs->file->full_open_options);
> - qdict_put_obj(opts, "file", QOBJECT(bs->file->full_open_options));
> + QINCREF(bs->file->bs->full_open_options);
> + qdict_put_obj(opts, "file",
> + QOBJECT(bs->file->bs->full_open_options));
>
> bs->full_open_options = opts;
> } else {
> diff --git a/block/blkdebug.c b/block/blkdebug.c
> index bc247f4..117fce6 100644
> --- a/block/blkdebug.c
> +++ b/block/blkdebug.c
> @@ -427,10 +427,10 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
> s->state = 1;
>
> /* Open the backing file */
Isn't "backing file" a confusing term for bs->file given that we have
bs->backing_hd? :)
> - assert(bs->file == NULL);
> - ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-image"), options, "image",
> - bs, &child_file, false, &local_err);
> - if (ret < 0) {
Should we keep the assertion?
> + bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
> + bs, &child_file, false, &local_err);
> + if (local_err) {
> + ret = -EINVAL;
> error_propagate(errp, local_err);
> goto out;
> }
> @@ -449,7 +449,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
> goto out;
>
> fail_unref:
> - bdrv_unref(bs->file);
> + bdrv_unref(bs->file->bs);
> out:
> qemu_opts_del(opts);
> return ret;
> @@ -510,7 +510,8 @@ static BlockAIOCB *blkdebug_aio_readv(BlockDriverState *bs,
> return inject_error(bs, cb, opaque, rule);
> }
>
> - return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
> + return bdrv_aio_readv(bs->file->bs, sector_num, qiov, nb_sectors,
> + cb, opaque);
> }
>
> static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
> @@ -532,7 +533,8 @@ static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs,
> return inject_error(bs, cb, opaque, rule);
> }
>
> - return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
> + return bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors,
> + cb, opaque);
> }
>
> static BlockAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
> @@ -551,7 +553,7 @@ static BlockAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
> return inject_error(bs, cb, opaque, rule);
> }
>
> - return bdrv_aio_flush(bs->file, cb, opaque);
> + return bdrv_aio_flush(bs->file->bs, cb, opaque);
> }
>
>
> @@ -716,12 +718,12 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag)
>
> static int64_t blkdebug_getlength(BlockDriverState *bs)
> {
> - return bdrv_getlength(bs->file);
> + return bdrv_getlength(bs->file->bs);
> }
>
> static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
> {
> - return bdrv_truncate(bs->file, offset);
> + return bdrv_truncate(bs->file->bs, offset);
> }
>
> static void blkdebug_refresh_filename(BlockDriverState *bs)
> @@ -741,24 +743,24 @@ static void blkdebug_refresh_filename(BlockDriverState *bs)
> }
> }
>
> - if (force_json && !bs->file->full_open_options) {
> + if (force_json && !bs->file->bs->full_open_options) {
> /* The config file cannot be recreated, so creating a plain filename
> * is impossible */
> return;
> }
>
> - if (!force_json && bs->file->exact_filename[0]) {
> + if (!force_json && bs->file->bs->exact_filename[0]) {
> snprintf(bs->exact_filename, sizeof(bs->exact_filename),
> "blkdebug:%s:%s",
> qdict_get_try_str(bs->options, "config") ?: "",
> - bs->file->exact_filename);
> + bs->file->bs->exact_filename);
> }
>
> opts = qdict_new();
> qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
>
> - QINCREF(bs->file->full_open_options);
> - qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options));
> + QINCREF(bs->file->bs->full_open_options);
> + qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options));
>
> for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
> if (strcmp(qdict_entry_key(e), "x-image") &&
> diff --git a/block/blkverify.c b/block/blkverify.c
> index 6b71622..f8655ad 100644
> --- a/block/blkverify.c
> +++ b/block/blkverify.c
> @@ -123,10 +123,10 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* Open the raw file */
> - assert(bs->file == NULL);
> - ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-raw"), options,
> - "raw", bs, &child_file, false, &local_err);
> - if (ret < 0) {
Same as above, should we keep the assert?
> + bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
> + bs, &child_file, false, &local_err);
> + if (local_err) {
> + ret = -EINVAL;
> error_propagate(errp, local_err);
> goto fail;
> }
> @@ -238,13 +238,13 @@ static BlockAIOCB *blkverify_aio_readv(BlockDriverState *bs,
> nb_sectors, cb, opaque);
>
> acb->verify = blkverify_verify_readv;
> - acb->buf = qemu_blockalign(bs->file, qiov->size);
> + acb->buf = qemu_blockalign(bs->file->bs, qiov->size);
> qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);
> qemu_iovec_clone(&acb->raw_qiov, qiov, acb->buf);
>
> bdrv_aio_readv(s->test_file->bs, sector_num, qiov, nb_sectors,
> blkverify_aio_cb, acb);
> - bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,
> + bdrv_aio_readv(bs->file->bs, sector_num, &acb->raw_qiov, nb_sectors,
> blkverify_aio_cb, acb);
> return &acb->common;
> }
> @@ -259,7 +259,7 @@ static BlockAIOCB *blkverify_aio_writev(BlockDriverState *bs,
>
> bdrv_aio_writev(s->test_file->bs, sector_num, qiov, nb_sectors,
> blkverify_aio_cb, acb);
> - bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
> + bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors,
> blkverify_aio_cb, acb);
> return &acb->common;
> }
> @@ -279,7 +279,7 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
> {
> BDRVBlkverifyState *s = bs->opaque;
>
> - bool perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
> + bool perm = bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
>
> if (perm) {
> return true;
> @@ -308,15 +308,17 @@ static void blkverify_refresh_filename(BlockDriverState *bs)
> {
> BDRVBlkverifyState *s = bs->opaque;
>
> - /* bs->file has already been refreshed */
> + /* bs->file->bs has already been refreshed */
> bdrv_refresh_filename(s->test_file->bs);
>
> - if (bs->file->full_open_options && s->test_file->bs->full_open_options) {
> + if (bs->file->bs->full_open_options
> + && s->test_file->bs->full_open_options)
> + {
> QDict *opts = qdict_new();
> qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkverify")));
>
> - QINCREF(bs->file->full_open_options);
> - qdict_put_obj(opts, "raw", QOBJECT(bs->file->full_open_options));
> + QINCREF(bs->file->bs->full_open_options);
> + qdict_put_obj(opts, "raw", QOBJECT(bs->file->bs->full_open_options));
> QINCREF(s->test_file->bs->full_open_options);
> qdict_put_obj(opts, "test",
> QOBJECT(s->test_file->bs->full_open_options));
> @@ -324,10 +326,13 @@ static void blkverify_refresh_filename(BlockDriverState *bs)
> bs->full_open_options = opts;
> }
>
> - if (bs->file->exact_filename[0] && s->test_file->bs->exact_filename[0]) {
> + if (bs->file->bs->exact_filename[0]
> + && s->test_file->bs->exact_filename[0])
> + {
> snprintf(bs->exact_filename, sizeof(bs->exact_filename),
> "blkverify:%s:%s",
> - bs->file->exact_filename, s->test_file->bs->exact_filename);
> + bs->file->bs->exact_filename,
> + s->test_file->bs->exact_filename);
> }
> }
>
> diff --git a/block/bochs.c b/block/bochs.c
> index 199ac2b..18949b9 100644
> --- a/block/bochs.c
> +++ b/block/bochs.c
> @@ -103,7 +103,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
>
> bs->read_only = 1; // no write support yet
>
> - ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
> + ret = bdrv_pread(bs->file->bs, 0, &bochs, sizeof(bochs));
> if (ret < 0) {
> return ret;
> }
> @@ -137,7 +137,7 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
> return -ENOMEM;
> }
>
> - ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
> + ret = bdrv_pread(bs->file->bs, le32_to_cpu(bochs.header), s->catalog_bitmap,
> s->catalog_size * 4);
> if (ret < 0) {
> goto fail;
> @@ -206,7 +206,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
> (s->extent_blocks + s->bitmap_blocks));
>
> /* read in bitmap for current extent */
> - ret = bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),
> + ret = bdrv_pread(bs->file->bs, bitmap_offset + (extent_offset / 8),
> &bitmap_entry, 1);
> if (ret < 0) {
> return ret;
> @@ -229,7 +229,7 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num,
> if (block_offset < 0) {
> return block_offset;
> } else if (block_offset > 0) {
> - ret = bdrv_pread(bs->file, block_offset, buf, 512);
> + ret = bdrv_pread(bs->file->bs, block_offset, buf, 512);
> if (ret < 0) {
> return ret;
> }
> diff --git a/block/cloop.c b/block/cloop.c
> index f328be0..4190ae0 100644
> --- a/block/cloop.c
> +++ b/block/cloop.c
> @@ -66,7 +66,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
> bs->read_only = 1;
>
> /* read header */
> - ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
> + ret = bdrv_pread(bs->file->bs, 128, &s->block_size, 4);
> if (ret < 0) {
> return ret;
> }
> @@ -92,7 +92,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
> return -EINVAL;
> }
>
> - ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);
> + ret = bdrv_pread(bs->file->bs, 128 + 4, &s->n_blocks, 4);
> if (ret < 0) {
> return ret;
> }
> @@ -123,7 +123,7 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
> return -ENOMEM;
> }
>
> - ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);
> + ret = bdrv_pread(bs->file->bs, 128 + 4 + 4, s->offsets, offsets_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -203,8 +203,8 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
> int ret;
> uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];
>
> - ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block,
> - bytes);
> + ret = bdrv_pread(bs->file->bs, s->offsets[block_num],
> + s->compressed_block, bytes);
> if (ret != bytes) {
> return -1;
> }
> diff --git a/block/dmg.c b/block/dmg.c
> index 9f25281..546a6f5 100644
> --- a/block/dmg.c
> +++ b/block/dmg.c
> @@ -85,7 +85,7 @@ static int read_uint64(BlockDriverState *bs, int64_t offset, uint64_t *result)
> uint64_t buffer;
> int ret;
>
> - ret = bdrv_pread(bs->file, offset, &buffer, 8);
> + ret = bdrv_pread(bs->file->bs, offset, &buffer, 8);
> if (ret < 0) {
> return ret;
> }
> @@ -99,7 +99,7 @@ static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
> uint32_t buffer;
> int ret;
>
> - ret = bdrv_pread(bs->file, offset, &buffer, 4);
> + ret = bdrv_pread(bs->file->bs, offset, &buffer, 4);
> if (ret < 0) {
> return ret;
> }
> @@ -354,7 +354,7 @@ static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
> offset += 4;
>
> buffer = g_realloc(buffer, count);
> - ret = bdrv_pread(bs->file, offset, buffer, count);
> + ret = bdrv_pread(bs->file->bs, offset, buffer, count);
> if (ret < 0) {
> goto fail;
> }
> @@ -391,7 +391,7 @@ static int dmg_read_plist_xml(BlockDriverState *bs, DmgHeaderState *ds,
>
> buffer = g_malloc(info_length + 1);
> buffer[info_length] = '\0';
> - ret = bdrv_pread(bs->file, info_begin, buffer, info_length);
> + ret = bdrv_pread(bs->file->bs, info_begin, buffer, info_length);
> if (ret != info_length) {
> ret = -EINVAL;
> goto fail;
> @@ -446,7 +446,7 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> ds.max_sectors_per_chunk = 1;
>
> /* locate the UDIF trailer */
> - offset = dmg_find_koly_offset(bs->file, errp);
> + offset = dmg_find_koly_offset(bs->file->bs, errp);
> if (offset < 0) {
> ret = offset;
> goto fail;
> @@ -514,9 +514,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* initialize zlib engine */
> - s->compressed_chunk = qemu_try_blockalign(bs->file,
> + s->compressed_chunk = qemu_try_blockalign(bs->file->bs,
> ds.max_compressed_size + 1);
> - s->uncompressed_chunk = qemu_try_blockalign(bs->file,
> + s->uncompressed_chunk = qemu_try_blockalign(bs->file->bs,
> 512 * ds.max_sectors_per_chunk);
> if (s->compressed_chunk == NULL || s->uncompressed_chunk == NULL) {
> ret = -ENOMEM;
> @@ -592,7 +592,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
> case 0x80000005: { /* zlib compressed */
> /* we need to buffer, because only the chunk as whole can be
> * inflated. */
> - ret = bdrv_pread(bs->file, s->offsets[chunk],
> + ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
> s->compressed_chunk, s->lengths[chunk]);
> if (ret != s->lengths[chunk]) {
> return -1;
> @@ -616,7 +616,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
> case 0x80000006: /* bzip2 compressed */
> /* we need to buffer, because only the chunk as whole can be
> * inflated. */
> - ret = bdrv_pread(bs->file, s->offsets[chunk],
> + ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
> s->compressed_chunk, s->lengths[chunk]);
> if (ret != s->lengths[chunk]) {
> return -1;
> @@ -641,7 +641,7 @@ static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
> break;
> #endif /* CONFIG_BZIP2 */
> case 1: /* copy */
> - ret = bdrv_pread(bs->file, s->offsets[chunk],
> + ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
> s->uncompressed_chunk, s->lengths[chunk]);
> if (ret != s->lengths[chunk]) {
> return -1;
> diff --git a/block/io.c b/block/io.c
> index 94e18e6..15c676a 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -156,15 +156,15 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp)
>
> /* Take some limits from the children as a default */
> if (bs->file) {
> - bdrv_refresh_limits(bs->file, &local_err);
> + bdrv_refresh_limits(bs->file->bs, &local_err);
> if (local_err) {
> error_propagate(errp, local_err);
> return;
> }
> - bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length;
> - bs->bl.max_transfer_length = bs->file->bl.max_transfer_length;
> - bs->bl.min_mem_alignment = bs->file->bl.min_mem_alignment;
> - bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment;
> + bs->bl.opt_transfer_length = bs->file->bs->bl.opt_transfer_length;
> + bs->bl.max_transfer_length = bs->file->bs->bl.max_transfer_length;
> + bs->bl.min_mem_alignment = bs->file->bs->bl.min_mem_alignment;
> + bs->bl.opt_mem_alignment = bs->file->bs->bl.opt_mem_alignment;
> } else {
> bs->bl.min_mem_alignment = 512;
> bs->bl.opt_mem_alignment = getpagesize();
> @@ -224,7 +224,7 @@ static bool bdrv_requests_pending(BlockDriverState *bs)
> if (!qemu_co_queue_empty(&bs->throttled_reqs[1])) {
> return true;
> }
> - if (bs->file && bdrv_requests_pending(bs->file)) {
> + if (bs->file && bdrv_requests_pending(bs->file->bs)) {
> return true;
> }
> if (bs->backing_hd && bdrv_requests_pending(bs->backing_hd)) {
> @@ -1137,13 +1137,13 @@ static int coroutine_fn bdrv_aligned_pwritev(BlockDriverState *bs,
> if (ret < 0) {
> /* Do nothing, write notifier decided to fail this request */
> } else if (flags & BDRV_REQ_ZERO_WRITE) {
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_ZERO);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO);
> ret = bdrv_co_do_write_zeroes(bs, sector_num, nb_sectors, flags);
> } else {
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV);
> ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
> }
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_DONE);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_DONE);
>
> if (ret == 0 && !bs->enable_write_cache) {
> ret = bdrv_co_flush(bs);
> @@ -1192,13 +1192,13 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
> /* RMW the unaligned part before head. */
> mark_request_serialising(req, align);
> wait_serialising_requests(req);
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_HEAD);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
> ret = bdrv_aligned_preadv(bs, req, offset & ~(align - 1), align,
> align, &local_qiov, 0);
> if (ret < 0) {
> goto fail;
> }
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
>
> memset(buf + head_padding_bytes, 0, zero_bytes);
> ret = bdrv_aligned_pwritev(bs, req, offset & ~(align - 1), align,
> @@ -1230,13 +1230,13 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BlockDriverState *bs,
> /* RMW the unaligned part after tail. */
> mark_request_serialising(req, align);
> wait_serialising_requests(req);
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_TAIL);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
> ret = bdrv_aligned_preadv(bs, req, offset, align,
> align, &local_qiov, 0);
> if (ret < 0) {
> goto fail;
> }
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
>
> memset(buf, 0, bytes);
> ret = bdrv_aligned_pwritev(bs, req, offset, align,
> @@ -1307,13 +1307,13 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
> };
> qemu_iovec_init_external(&head_qiov, &head_iov, 1);
>
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_HEAD);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);
> ret = bdrv_aligned_preadv(bs, &req, offset & ~(align - 1), align,
> align, &head_qiov, 0);
> if (ret < 0) {
> goto fail;
> }
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);
>
> qemu_iovec_init(&local_qiov, qiov->niov + 2);
> qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1));
> @@ -1341,13 +1341,13 @@ static int coroutine_fn bdrv_co_do_pwritev(BlockDriverState *bs,
> };
> qemu_iovec_init_external(&tail_qiov, &tail_iov, 1);
>
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_TAIL);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
> ret = bdrv_aligned_preadv(bs, &req, (offset + bytes) & ~(align - 1), align,
> align, &tail_qiov, 0);
> if (ret < 0) {
> goto fail;
> }
> - BLKDBG_EVENT(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
> + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);
>
> if (!use_local_qiov) {
> qemu_iovec_init(&local_qiov, qiov->niov + 1);
> @@ -1496,7 +1496,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
>
> if (ret & BDRV_BLOCK_RAW) {
> assert(ret & BDRV_BLOCK_OFFSET_VALID);
> - return bdrv_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
> + return bdrv_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS,
> *pnum, pnum);
> }
>
> @@ -1519,7 +1519,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
> (ret & BDRV_BLOCK_OFFSET_VALID)) {
> int file_pnum;
>
> - ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
> + ret2 = bdrv_co_get_block_status(bs->file->bs, ret >> BDRV_SECTOR_BITS,
> *pnum, &file_pnum);
> if (ret2 >= 0) {
> /* Ignore errors. This is just providing extra information, it
> @@ -1723,7 +1723,7 @@ int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos)
> } else if (drv->bdrv_save_vmstate) {
> return drv->bdrv_save_vmstate(bs, qiov, pos);
> } else if (bs->file) {
> - return bdrv_writev_vmstate(bs->file, qiov, pos);
> + return bdrv_writev_vmstate(bs->file->bs, qiov, pos);
> }
>
> return -ENOTSUP;
> @@ -1738,7 +1738,7 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
> if (drv->bdrv_load_vmstate)
> return drv->bdrv_load_vmstate(bs, buf, pos, size);
> if (bs->file)
> - return bdrv_load_vmstate(bs->file, buf, pos, size);
> + return bdrv_load_vmstate(bs->file->bs, buf, pos, size);
> return -ENOTSUP;
> }
>
> @@ -2366,7 +2366,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
> * in the case of cache=unsafe, so there are no useless flushes.
> */
> flush_parent:
> - return bdrv_co_flush(bs->file);
> + return bs->file ? bdrv_co_flush(bs->file->bs) : 0;
> }
>
> int bdrv_flush(BlockDriverState *bs)
> @@ -2594,7 +2594,7 @@ void bdrv_io_plug(BlockDriverState *bs)
> if (drv && drv->bdrv_io_plug) {
> drv->bdrv_io_plug(bs);
> } else if (bs->file) {
> - bdrv_io_plug(bs->file);
> + bdrv_io_plug(bs->file->bs);
> }
> }
>
> @@ -2604,7 +2604,7 @@ void bdrv_io_unplug(BlockDriverState *bs)
> if (drv && drv->bdrv_io_unplug) {
> drv->bdrv_io_unplug(bs);
> } else if (bs->file) {
> - bdrv_io_unplug(bs->file);
> + bdrv_io_unplug(bs->file->bs);
> }
> }
>
> @@ -2614,7 +2614,7 @@ void bdrv_flush_io_queue(BlockDriverState *bs)
> if (drv && drv->bdrv_flush_io_queue) {
> drv->bdrv_flush_io_queue(bs);
> } else if (bs->file) {
> - bdrv_flush_io_queue(bs->file);
> + bdrv_flush_io_queue(bs->file->bs);
> }
> bdrv_start_throttled_reqs(bs);
> }
> diff --git a/block/parallels.c b/block/parallels.c
> index 5cd6ec3..4f79293 100644
> --- a/block/parallels.c
> +++ b/block/parallels.c
> @@ -202,13 +202,13 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
>
> to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx;
> space = to_allocate * s->tracks;
> - if (s->data_end + space > bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS) {
> + if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) {
> int ret;
> space += s->prealloc_size;
> if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
> - ret = bdrv_write_zeroes(bs->file, s->data_end, space, 0);
> + ret = bdrv_write_zeroes(bs->file->bs, s->data_end, space, 0);
> } else {
> - ret = bdrv_truncate(bs->file,
> + ret = bdrv_truncate(bs->file->bs,
> (s->data_end + space) << BDRV_SECTOR_BITS);
> }
> if (ret < 0) {
> @@ -244,7 +244,8 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
> if (off + to_write > s->header_size) {
> to_write = s->header_size - off;
> }
> - ret = bdrv_pwrite(bs->file, off, (uint8_t *)s->header + off, to_write);
> + ret = bdrv_pwrite(bs->file->bs, off, (uint8_t *)s->header + off,
> + to_write);
> if (ret < 0) {
> qemu_co_mutex_unlock(&s->lock);
> return ret;
> @@ -303,7 +304,7 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
> qemu_iovec_reset(&hd_qiov);
> qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
>
> - ret = bdrv_co_writev(bs->file, position, n, &hd_qiov);
> + ret = bdrv_co_writev(bs->file->bs, position, n, &hd_qiov);
> if (ret < 0) {
> break;
> }
> @@ -343,7 +344,7 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
> qemu_iovec_reset(&hd_qiov);
> qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes);
>
> - ret = bdrv_co_readv(bs->file, position, n, &hd_qiov);
> + ret = bdrv_co_readv(bs->file->bs, position, n, &hd_qiov);
> if (ret < 0) {
> break;
> }
> @@ -369,7 +370,7 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
> bool flush_bat = false;
> int cluster_size = s->tracks << BDRV_SECTOR_BITS;
>
> - size = bdrv_getlength(bs->file);
> + size = bdrv_getlength(bs->file->bs);
> if (size < 0) {
> res->check_errors++;
> return size;
> @@ -424,7 +425,7 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
> }
>
> if (flush_bat) {
> - ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size);
> + ret = bdrv_pwrite_sync(bs->file->bs, 0, s->header, s->header_size);
> if (ret < 0) {
> res->check_errors++;
> return ret;
> @@ -440,7 +441,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, res->image_end_offset);
> + ret = bdrv_truncate(bs->file->bs, res->image_end_offset);
> if (ret < 0) {
> res->check_errors++;
> return ret;
> @@ -546,12 +547,13 @@ static int parallels_probe(const uint8_t *buf, int buf_size,
> static int parallels_update_header(BlockDriverState *bs)
> {
> BDRVParallelsState *s = bs->opaque;
> - unsigned size = MAX(bdrv_opt_mem_align(bs->file), sizeof(ParallelsHeader));
> + unsigned size = MAX(bdrv_opt_mem_align(bs->file->bs),
> + sizeof(ParallelsHeader));
>
> if (size > s->header_size) {
> size = s->header_size;
> }
> - return bdrv_pwrite_sync(bs->file, 0, s->header, size);
> + return bdrv_pwrite_sync(bs->file->bs, 0, s->header, size);
> }
>
> static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> @@ -564,7 +566,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> Error *local_err = NULL;
> char *buf;
>
> - ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
> + ret = bdrv_pread(bs->file->bs, 0, &ph, sizeof(ph));
> if (ret < 0) {
> goto fail;
> }
> @@ -603,8 +605,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> size = bat_entry_off(s->bat_size);
> - s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file));
> - s->header = qemu_try_blockalign(bs->file, s->header_size);
> + s->header_size = ROUND_UP(size, bdrv_opt_mem_align(bs->file->bs));
> + s->header = qemu_try_blockalign(bs->file->bs, s->header_size);
> if (s->header == NULL) {
> ret = -ENOMEM;
> goto fail;
> @@ -619,7 +621,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> s->header_size = size;
> }
>
> - ret = bdrv_pread(bs->file, 0, s->header, s->header_size);
> + ret = bdrv_pread(bs->file->bs, 0, s->header, s->header_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -663,8 +665,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> if (local_err != NULL) {
> goto fail_options;
> }
> - if (!bdrv_has_zero_init(bs->file) ||
> - bdrv_truncate(bs->file, bdrv_getlength(bs->file)) != 0) {
> + if (!bdrv_has_zero_init(bs->file->bs) ||
> + bdrv_truncate(bs->file->bs, bdrv_getlength(bs->file->bs)) != 0) {
> s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
> }
>
> @@ -707,7 +709,7 @@ static void parallels_close(BlockDriverState *bs)
> }
>
> if (bs->open_flags & BDRV_O_RDWR) {
> - bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
> + bdrv_truncate(bs->file->bs, s->data_end << BDRV_SECTOR_BITS);
> }
>
> g_free(s->bat_dirty_bmap);
> diff --git a/block/qapi.c b/block/qapi.c
> index 2ce5097..0c4654e 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -359,7 +359,7 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
>
> if (bs->file) {
> s->has_parent = true;
> - s->parent = bdrv_query_stats(bs->file, query_backing);
> + s->parent = bdrv_query_stats(bs->file->bs, query_backing);
> }
>
> if (query_backing && bs->backing_hd) {
> diff --git a/block/qcow.c b/block/qcow.c
> index 6e35db1..4d20cd5 100644
> --- a/block/qcow.c
> +++ b/block/qcow.c
> @@ -100,7 +100,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
> int ret;
> QCowHeader header;
>
> - ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
> + ret = bdrv_pread(bs->file->bs, 0, &header, sizeof(header));
> if (ret < 0) {
> goto fail;
> }
> @@ -193,7 +193,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
> goto fail;
> }
>
> - ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
> + ret = bdrv_pread(bs->file->bs, s->l1_table_offset, s->l1_table,
> s->l1_size * sizeof(uint64_t));
> if (ret < 0) {
> goto fail;
> @@ -205,7 +205,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
>
> /* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */
> s->l2_cache =
> - qemu_try_blockalign(bs->file,
> + qemu_try_blockalign(bs->file->bs,
> s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
> if (s->l2_cache == NULL) {
> error_setg(errp, "Could not allocate L2 table cache");
> @@ -224,7 +224,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
> ret = -EINVAL;
> goto fail;
> }
> - ret = bdrv_pread(bs->file, header.backing_file_offset,
> + ret = bdrv_pread(bs->file->bs, header.backing_file_offset,
> bs->backing_file, len);
> if (ret < 0) {
> goto fail;
> @@ -369,13 +369,13 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
> if (!allocate)
> return 0;
> /* allocate a new l2 entry */
> - l2_offset = bdrv_getlength(bs->file);
> + l2_offset = bdrv_getlength(bs->file->bs);
> /* round to cluster size */
> l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
> /* update the L1 entry */
> s->l1_table[l1_index] = l2_offset;
> tmp = cpu_to_be64(l2_offset);
> - if (bdrv_pwrite_sync(bs->file,
> + if (bdrv_pwrite_sync(bs->file->bs,
> s->l1_table_offset + l1_index * sizeof(tmp),
> &tmp, sizeof(tmp)) < 0)
> return 0;
> @@ -405,11 +405,12 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
> l2_table = s->l2_cache + (min_index << s->l2_bits);
> if (new_l2_table) {
> memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
> - if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
> + if (bdrv_pwrite_sync(bs->file->bs, l2_offset, l2_table,
> s->l2_size * sizeof(uint64_t)) < 0)
> return 0;
> } else {
> - if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
> + if (bdrv_pread(bs->file->bs, l2_offset, l2_table,
> + s->l2_size * sizeof(uint64_t)) !=
> s->l2_size * sizeof(uint64_t))
> return 0;
> }
> @@ -430,20 +431,21 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
> overwritten */
> if (decompress_cluster(bs, cluster_offset) < 0)
> return 0;
> - cluster_offset = bdrv_getlength(bs->file);
> + cluster_offset = bdrv_getlength(bs->file->bs);
> cluster_offset = (cluster_offset + s->cluster_size - 1) &
> ~(s->cluster_size - 1);
> /* write the cluster content */
> - if (bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache, s->cluster_size) !=
> + if (bdrv_pwrite(bs->file->bs, cluster_offset, s->cluster_cache,
> + s->cluster_size) !=
> s->cluster_size)
> return -1;
> } else {
> - cluster_offset = bdrv_getlength(bs->file);
> + cluster_offset = bdrv_getlength(bs->file->bs);
> if (allocate == 1) {
> /* round to cluster size */
> cluster_offset = (cluster_offset + s->cluster_size - 1) &
> ~(s->cluster_size - 1);
> - bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
> + bdrv_truncate(bs->file->bs, cluster_offset + s->cluster_size);
> /* if encrypted, we must initialize the cluster
> content which won't be written */
> if (bs->encrypted &&
> @@ -463,7 +465,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
> errno = EIO;
> return -1;
> }
> - if (bdrv_pwrite(bs->file, cluster_offset + i * 512,
> + if (bdrv_pwrite(bs->file->bs, cluster_offset + i * 512,
> s->cluster_data, 512) != 512)
> return -1;
> }
> @@ -477,7 +479,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
> /* update L2 table */
> tmp = cpu_to_be64(cluster_offset);
> l2_table[l2_index] = tmp;
> - if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
> + if (bdrv_pwrite_sync(bs->file->bs, l2_offset + l2_index * sizeof(tmp),
> &tmp, sizeof(tmp)) < 0)
> return 0;
> }
> @@ -546,7 +548,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
> if (s->cluster_cache_offset != coffset) {
> csize = cluster_offset >> (63 - s->cluster_bits);
> csize &= (s->cluster_size - 1);
> - ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize);
> + ret = bdrv_pread(bs->file->bs, coffset, s->cluster_data, csize);
> if (ret != csize)
> return -1;
> if (decompress_buffer(s->cluster_cache, s->cluster_size,
> @@ -625,7 +627,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
> 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->file,
> + ret = bdrv_co_readv(bs->file->bs,
> (cluster_offset >> 9) + index_in_cluster,
> n, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> @@ -727,7 +729,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
> hd_iov.iov_len = n * 512;
> qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
> qemu_co_mutex_unlock(&s->lock);
> - ret = bdrv_co_writev(bs->file,
> + ret = bdrv_co_writev(bs->file->bs,
> (cluster_offset >> 9) + index_in_cluster,
> n, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> @@ -879,10 +881,10 @@ static int qcow_make_empty(BlockDriverState *bs)
> int ret;
>
> memset(s->l1_table, 0, l1_length);
> - if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
> + if (bdrv_pwrite_sync(bs->file->bs, s->l1_table_offset, s->l1_table,
> l1_length) < 0)
> return -1;
> - ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
> + ret = bdrv_truncate(bs->file->bs, s->l1_table_offset + l1_length);
> if (ret < 0)
> return ret;
>
> @@ -962,7 +964,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
> }
>
> cluster_offset &= s->cluster_offset_mask;
> - ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
> + ret = bdrv_pwrite(bs->file->bs, cluster_offset, out_buf, out_len);
> if (ret < 0) {
> goto fail;
> }
> diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
> index 7b14c5c..86dd7f2 100644
> --- a/block/qcow2-cache.c
> +++ b/block/qcow2-cache.c
> @@ -127,7 +127,7 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
> c = g_new0(Qcow2Cache, 1);
> c->size = num_tables;
> c->entries = g_try_new0(Qcow2CachedTable, num_tables);
> - c->table_array = qemu_try_blockalign(bs->file,
> + c->table_array = qemu_try_blockalign(bs->file->bs,
> (size_t) num_tables * s->cluster_size);
>
> if (!c->entries || !c->table_array) {
> @@ -185,7 +185,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
> if (c->depends) {
> ret = qcow2_cache_flush_dependency(bs, c);
> } else if (c->depends_on_flush) {
> - ret = bdrv_flush(bs->file);
> + ret = bdrv_flush(bs->file->bs);
> if (ret >= 0) {
> c->depends_on_flush = false;
> }
> @@ -216,7 +216,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
> BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
> }
>
> - ret = bdrv_pwrite(bs->file, c->entries[i].offset,
> + ret = bdrv_pwrite(bs->file->bs, c->entries[i].offset,
> qcow2_cache_get_table_addr(bs, c, i), s->cluster_size);
> if (ret < 0) {
> return ret;
> @@ -244,7 +244,7 @@ int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
> }
>
> if (result == 0) {
> - ret = bdrv_flush(bs->file);
> + ret = bdrv_flush(bs->file->bs);
> if (ret < 0) {
> result = ret;
> }
> @@ -356,7 +356,8 @@ static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
> BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
> }
>
> - ret = bdrv_pread(bs->file, offset, qcow2_cache_get_table_addr(bs, c, i),
> + ret = bdrv_pread(bs->file->bs, offset,
> + qcow2_cache_get_table_addr(bs, c, i),
> s->cluster_size);
> if (ret < 0) {
> return ret;
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index 6ede629..7844f8e 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -72,7 +72,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
> #endif
>
> new_l1_size2 = sizeof(uint64_t) * new_l1_size;
> - new_l1_table = qemu_try_blockalign(bs->file,
> + new_l1_table = qemu_try_blockalign(bs->file->bs,
> align_offset(new_l1_size2, 512));
> if (new_l1_table == NULL) {
> return -ENOMEM;
> @@ -105,7 +105,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
> BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
> for(i = 0; i < s->l1_size; i++)
> new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
> - ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
> + ret = bdrv_pwrite_sync(bs->file->bs, new_l1_table_offset,
> + new_l1_table, new_l1_size2);
> if (ret < 0)
> goto fail;
> for(i = 0; i < s->l1_size; i++)
> @@ -115,7 +116,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
> BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
> cpu_to_be32w((uint32_t*)data, new_l1_size);
> stq_be_p(data + 4, new_l1_table_offset);
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
> + ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, l1_size),
> + data, sizeof(data));
> if (ret < 0) {
> goto fail;
> }
> @@ -182,8 +184,9 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
> - ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
> - buf, sizeof(buf));
> + ret = bdrv_pwrite_sync(bs->file->bs,
> + s->l1_table_offset + 8 * l1_start_index,
> + buf, sizeof(buf));
> if (ret < 0) {
> return ret;
> }
> @@ -440,7 +443,8 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
> - ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);
> + ret = bdrv_co_writev(bs->file->bs, (cluster_offset >> 9) + n_start, n,
> + &qiov);
> if (ret < 0) {
> goto out;
> }
> @@ -817,7 +821,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
>
> /*
> * If this was a COW, we need to decrease the refcount of the old cluster.
> - * Also flush bs->file to get the right order for L2 and refcount update.
> + * Also flush bs->file->bs to get the right order for L2 and refcount update.
> *
> * Don't discard clusters that reach a refcount of 0 (e.g. compressed
> * clusters), the next write will reuse them anyway.
> @@ -1412,7 +1416,8 @@ int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
> sector_offset = coffset & 511;
> csize = nb_csectors * 512 - sector_offset;
> BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
> - ret = bdrv_read(bs->file, coffset >> 9, s->cluster_data, nb_csectors);
> + ret = bdrv_read(bs->file->bs, coffset >> 9, s->cluster_data,
> + nb_csectors);
> if (ret < 0) {
> return ret;
> }
> @@ -1645,7 +1650,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
> if (!is_active_l1) {
> /* inactive L2 tables require a buffer to be stored in when loading
> * them from disk */
> - l2_table = qemu_try_blockalign(bs->file, s->cluster_size);
> + l2_table = qemu_try_blockalign(bs->file->bs, s->cluster_size);
> if (l2_table == NULL) {
> return -ENOMEM;
> }
> @@ -1679,8 +1684,8 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
> (void **)&l2_table);
> } else {
> /* load inactive L2 tables from disk */
> - ret = bdrv_read(bs->file, l2_offset / BDRV_SECTOR_SIZE,
> - (void *)l2_table, s->cluster_sectors);
> + ret = bdrv_read(bs->file->bs, l2_offset / BDRV_SECTOR_SIZE,
> + (void *)l2_table, s->cluster_sectors);
> }
> if (ret < 0) {
> goto fail;
> @@ -1754,7 +1759,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
> goto fail;
> }
>
> - ret = bdrv_write_zeroes(bs->file, offset / BDRV_SECTOR_SIZE,
> + ret = bdrv_write_zeroes(bs->file->bs, offset / BDRV_SECTOR_SIZE,
> s->cluster_sectors, 0);
> if (ret < 0) {
> if (!preallocated) {
> @@ -1787,8 +1792,8 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
> goto fail;
> }
>
> - ret = bdrv_write(bs->file, l2_offset / BDRV_SECTOR_SIZE,
> - (void *)l2_table, s->cluster_sectors);
> + ret = bdrv_write(bs->file->bs, l2_offset / BDRV_SECTOR_SIZE,
> + (void *)l2_table, s->cluster_sectors);
> if (ret < 0) {
> goto fail;
> }
> @@ -1861,8 +1866,9 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs,
>
> l1_table = g_realloc(l1_table, l1_sectors * BDRV_SECTOR_SIZE);
>
> - ret = bdrv_read(bs->file, s->snapshots[i].l1_table_offset /
> - BDRV_SECTOR_SIZE, (void *)l1_table, l1_sectors);
> + ret = bdrv_read(bs->file->bs,
> + s->snapshots[i].l1_table_offset / BDRV_SECTOR_SIZE,
> + (void *)l1_table, l1_sectors);
> if (ret < 0) {
> goto fail;
> }
> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index 2110839..4b81c8d 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -101,7 +101,7 @@ int qcow2_refcount_init(BlockDriverState *bs)
> goto fail;
> }
> BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
> - ret = bdrv_pread(bs->file, s->refcount_table_offset,
> + ret = bdrv_pread(bs->file->bs, s->refcount_table_offset,
> s->refcount_table, refcount_table_size2);
> if (ret < 0) {
> goto fail;
> @@ -431,7 +431,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
> if (refcount_table_index < s->refcount_table_size) {
> uint64_t data64 = cpu_to_be64(new_block);
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
> - ret = bdrv_pwrite_sync(bs->file,
> + ret = bdrv_pwrite_sync(bs->file->bs,
> s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
> &data64, sizeof(data64));
> if (ret < 0) {
> @@ -535,7 +535,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
>
> /* Write refcount blocks to disk */
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
> - ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
> + ret = bdrv_pwrite_sync(bs->file->bs, meta_offset, new_blocks,
> blocks_clusters * s->cluster_size);
> g_free(new_blocks);
> new_blocks = NULL;
> @@ -549,7 +549,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
> - ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
> + ret = bdrv_pwrite_sync(bs->file->bs, table_offset, new_table,
> table_size * sizeof(uint64_t));
> if (ret < 0) {
> goto fail_table;
> @@ -564,8 +564,9 @@ static int alloc_refcount_block(BlockDriverState *bs,
> cpu_to_be64w((uint64_t*)data, table_offset);
> cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),
> - data, sizeof(data));
> + ret = bdrv_pwrite_sync(bs->file->bs,
> + offsetof(QCowHeader, refcount_table_offset),
> + data, sizeof(data));
> if (ret < 0) {
> goto fail_table;
> }
> @@ -613,7 +614,7 @@ void qcow2_process_discards(BlockDriverState *bs, int ret)
>
> /* Discard is optional, ignore the return value */
> if (ret >= 0) {
> - bdrv_discard(bs->file,
> + bdrv_discard(bs->file->bs,
> d->offset >> BDRV_SECTOR_BITS,
> d->bytes >> BDRV_SECTOR_BITS);
> }
> @@ -1068,7 +1069,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
> }
> l1_allocated = true;
>
> - ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);
> + ret = bdrv_pread(bs->file->bs, l1_table_offset, l1_table, l1_size2);
> if (ret < 0) {
> goto fail;
> }
> @@ -1221,7 +1222,8 @@ fail:
> cpu_to_be64s(&l1_table[i]);
> }
>
> - ret = bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table, l1_size2);
> + ret = bdrv_pwrite_sync(bs->file->bs, l1_table_offset,
> + l1_table, l1_size2);
>
> for (i = 0; i < l1_size; i++) {
> be64_to_cpus(&l1_table[i]);
> @@ -1376,7 +1378,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
> l2_size = s->l2_size * sizeof(uint64_t);
> l2_table = g_malloc(l2_size);
>
> - ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);
> + ret = bdrv_pread(bs->file->bs, l2_offset, l2_table, l2_size);
> if (ret < 0) {
> fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");
> res->check_errors++;
> @@ -1508,7 +1510,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
> res->check_errors++;
> goto fail;
> }
> - ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);
> + ret = bdrv_pread(bs->file->bs, l1_table_offset, l1_table, l1_size2);
> if (ret < 0) {
> fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");
> res->check_errors++;
> @@ -1606,7 +1608,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
> }
> }
>
> - ret = bdrv_pread(bs->file, l2_offset, l2_table,
> + ret = bdrv_pread(bs->file->bs, l2_offset, l2_table,
> s->l2_size * sizeof(uint64_t));
> if (ret < 0) {
> fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
> @@ -1658,7 +1660,8 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
> goto fail;
> }
>
> - ret = bdrv_pwrite(bs->file, l2_offset, l2_table, s->cluster_size);
> + ret = bdrv_pwrite(bs->file->bs, l2_offset, l2_table,
> + s->cluster_size);
> if (ret < 0) {
> fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
> strerror(-ret));
> @@ -1713,11 +1716,11 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
> goto resize_fail;
> }
>
> - ret = bdrv_truncate(bs->file, offset + s->cluster_size);
> + ret = bdrv_truncate(bs->file->bs, offset + s->cluster_size);
> if (ret < 0) {
> goto resize_fail;
> }
> - size = bdrv_getlength(bs->file);
> + size = bdrv_getlength(bs->file->bs);
> if (size < 0) {
> ret = size;
> goto resize_fail;
> @@ -2091,7 +2094,7 @@ write_refblocks:
> on_disk_refblock = (void *)((char *) *refcount_table +
> refblock_index * s->cluster_size);
>
> - ret = bdrv_write(bs->file, refblock_offset / BDRV_SECTOR_SIZE,
> + ret = bdrv_write(bs->file->bs, refblock_offset / BDRV_SECTOR_SIZE,
> on_disk_refblock, s->cluster_sectors);
> if (ret < 0) {
> fprintf(stderr, "ERROR writing refblock: %s\n", strerror(-ret));
> @@ -2140,7 +2143,7 @@ write_refblocks:
> }
>
> assert(reftable_size < INT_MAX / sizeof(uint64_t));
> - ret = bdrv_pwrite(bs->file, reftable_offset, on_disk_reftable,
> + ret = bdrv_pwrite(bs->file->bs, reftable_offset, on_disk_reftable,
> reftable_size * sizeof(uint64_t));
> if (ret < 0) {
> fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
> @@ -2152,8 +2155,8 @@ write_refblocks:
> reftable_offset);
> cpu_to_be32w(&reftable_offset_and_clusters.reftable_clusters,
> size_to_clusters(s, reftable_size * sizeof(uint64_t)));
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader,
> - refcount_table_offset),
> + ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader,
> + refcount_table_offset),
> &reftable_offset_and_clusters,
> sizeof(reftable_offset_and_clusters));
> if (ret < 0) {
> @@ -2191,7 +2194,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
> bool rebuild = false;
> int ret;
>
> - size = bdrv_getlength(bs->file);
> + size = bdrv_getlength(bs->file->bs);
> if (size < 0) {
> res->check_errors++;
> return size;
> @@ -2400,7 +2403,7 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
> return -ENOMEM;
> }
>
> - ret = bdrv_pread(bs->file, l1_ofs, l1, l1_sz2);
> + ret = bdrv_pread(bs->file->bs, l1_ofs, l1, l1_sz2);
> if (ret < 0) {
> g_free(l1);
> return ret;
> diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
> index 92f4dfc..def7201 100644
> --- a/block/qcow2-snapshot.c
> +++ b/block/qcow2-snapshot.c
> @@ -64,7 +64,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
> for(i = 0; i < s->nb_snapshots; i++) {
> /* Read statically sized part of the snapshot header */
> offset = align_offset(offset, 8);
> - ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
> + ret = bdrv_pread(bs->file->bs, offset, &h, sizeof(h));
> if (ret < 0) {
> goto fail;
> }
> @@ -83,7 +83,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
> name_size = be16_to_cpu(h.name_size);
>
> /* Read extra data */
> - ret = bdrv_pread(bs->file, offset, &extra,
> + ret = bdrv_pread(bs->file->bs, offset, &extra,
> MIN(sizeof(extra), extra_data_size));
> if (ret < 0) {
> goto fail;
> @@ -102,7 +102,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
>
> /* Read snapshot ID */
> sn->id_str = g_malloc(id_str_size + 1);
> - ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
> + ret = bdrv_pread(bs->file->bs, offset, sn->id_str, id_str_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -111,7 +111,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
>
> /* Read snapshot name */
> sn->name = g_malloc(name_size + 1);
> - ret = bdrv_pread(bs->file, offset, sn->name, name_size);
> + ret = bdrv_pread(bs->file->bs, offset, sn->name, name_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -214,25 +214,25 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
> h.name_size = cpu_to_be16(name_size);
> offset = align_offset(offset, 8);
>
> - ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
> + ret = bdrv_pwrite(bs->file->bs, offset, &h, sizeof(h));
> if (ret < 0) {
> goto fail;
> }
> offset += sizeof(h);
>
> - ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
> + ret = bdrv_pwrite(bs->file->bs, offset, &extra, sizeof(extra));
> if (ret < 0) {
> goto fail;
> }
> offset += sizeof(extra);
>
> - ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
> + ret = bdrv_pwrite(bs->file->bs, offset, sn->id_str, id_str_size);
> if (ret < 0) {
> goto fail;
> }
> offset += id_str_size;
>
> - ret = bdrv_pwrite(bs->file, offset, sn->name, name_size);
> + ret = bdrv_pwrite(bs->file->bs, offset, sn->name, name_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -254,7 +254,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
> header_data.nb_snapshots = cpu_to_be32(s->nb_snapshots);
> header_data.snapshots_offset = cpu_to_be64(snapshots_offset);
>
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
> + ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, nb_snapshots),
> &header_data, sizeof(header_data));
> if (ret < 0) {
> goto fail;
> @@ -396,7 +396,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
> goto fail;
> }
>
> - ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
> + ret = bdrv_pwrite(bs->file->bs, sn->l1_table_offset, l1_table,
> s->l1_size * sizeof(uint64_t));
> if (ret < 0) {
> goto fail;
> @@ -509,7 +509,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
> goto fail;
> }
>
> - ret = bdrv_pread(bs->file, sn->l1_table_offset, sn_l1_table, sn_l1_bytes);
> + ret = bdrv_pread(bs->file->bs, sn->l1_table_offset,
> + sn_l1_table, sn_l1_bytes);
> if (ret < 0) {
> goto fail;
> }
> @@ -526,7 +527,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
> goto fail;
> }
>
> - ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
> + ret = bdrv_pwrite_sync(bs->file->bs, s->l1_table_offset, sn_l1_table,
> cur_l1_bytes);
> if (ret < 0) {
> goto fail;
> @@ -706,13 +707,14 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs,
> return -EFBIG;
> }
> new_l1_bytes = sn->l1_size * sizeof(uint64_t);
> - new_l1_table = qemu_try_blockalign(bs->file,
> + new_l1_table = qemu_try_blockalign(bs->file->bs,
> align_offset(new_l1_bytes, 512));
> if (new_l1_table == NULL) {
> return -ENOMEM;
> }
>
> - ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
> + ret = bdrv_pread(bs->file->bs, sn->l1_table_offset,
> + new_l1_table, new_l1_bytes);
> if (ret < 0) {
> error_setg(errp, "Failed to read l1 table for snapshot");
> qemu_vfree(new_l1_table);
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 56ad808..38b2797 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -104,7 +104,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
> printf("attempting to read extended header in offset %lu\n", offset);
> #endif
>
> - ret = bdrv_pread(bs->file, offset, &ext, sizeof(ext));
> + ret = bdrv_pread(bs->file->bs, offset, &ext, sizeof(ext));
> if (ret < 0) {
> error_setg_errno(errp, -ret, "qcow2_read_extension: ERROR: "
> "pread fail from offset %" PRIu64, offset);
> @@ -132,7 +132,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
> sizeof(bs->backing_format));
> return 2;
> }
> - ret = bdrv_pread(bs->file, offset, bs->backing_format, ext.len);
> + ret = bdrv_pread(bs->file->bs, offset, bs->backing_format, ext.len);
> if (ret < 0) {
> error_setg_errno(errp, -ret, "ERROR: ext_backing_format: "
> "Could not read format name");
> @@ -148,7 +148,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
> case QCOW2_EXT_MAGIC_FEATURE_TABLE:
> if (p_feature_table != NULL) {
> void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));
> - ret = bdrv_pread(bs->file, offset , feature_table, ext.len);
> + ret = bdrv_pread(bs->file->bs, offset , feature_table, ext.len);
> if (ret < 0) {
> error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "
> "Could not read table");
> @@ -169,7 +169,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
> uext->len = ext.len;
> QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);
>
> - ret = bdrv_pread(bs->file, offset , uext->data, uext->len);
> + ret = bdrv_pread(bs->file->bs, offset , uext->data, uext->len);
> if (ret < 0) {
> error_setg_errno(errp, -ret, "ERROR: unknown extension: "
> "Could not read data");
> @@ -260,12 +260,12 @@ int qcow2_mark_dirty(BlockDriverState *bs)
> }
>
> val = cpu_to_be64(s->incompatible_features | QCOW2_INCOMPAT_DIRTY);
> - ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, incompatible_features),
> + ret = bdrv_pwrite(bs->file->bs, offsetof(QCowHeader, incompatible_features),
> &val, sizeof(val));
> if (ret < 0) {
> return ret;
> }
> - ret = bdrv_flush(bs->file);
> + ret = bdrv_flush(bs->file->bs);
> if (ret < 0) {
> return ret;
> }
> @@ -828,7 +828,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
> uint64_t ext_end;
> uint64_t l1_vm_state_index;
>
> - ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
> + ret = bdrv_pread(bs->file->bs, 0, &header, sizeof(header));
> if (ret < 0) {
> error_setg_errno(errp, -ret, "Could not read qcow2 header");
> goto fail;
> @@ -903,7 +903,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
> if (header.header_length > sizeof(header)) {
> s->unknown_header_fields_size = header.header_length - sizeof(header);
> s->unknown_header_fields = g_malloc(s->unknown_header_fields_size);
> - ret = bdrv_pread(bs->file, sizeof(header), s->unknown_header_fields,
> + ret = bdrv_pread(bs->file->bs, sizeof(header), s->unknown_header_fields,
> s->unknown_header_fields_size);
> if (ret < 0) {
> error_setg_errno(errp, -ret, "Could not read unknown qcow2 header "
> @@ -1056,14 +1056,14 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
>
>
> if (s->l1_size > 0) {
> - s->l1_table = qemu_try_blockalign(bs->file,
> + s->l1_table = qemu_try_blockalign(bs->file->bs,
> align_offset(s->l1_size * sizeof(uint64_t), 512));
> if (s->l1_table == NULL) {
> error_setg(errp, "Could not allocate L1 table");
> ret = -ENOMEM;
> goto fail;
> }
> - ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
> + ret = bdrv_pread(bs->file->bs, s->l1_table_offset, s->l1_table,
> s->l1_size * sizeof(uint64_t));
> if (ret < 0) {
> error_setg_errno(errp, -ret, "Could not read L1 table");
> @@ -1082,7 +1082,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
>
> s->cluster_cache = g_malloc(s->cluster_size);
> /* one more sector for decompressed data alignment */
> - s->cluster_data = qemu_try_blockalign(bs->file, QCOW_MAX_CRYPT_CLUSTERS
> + s->cluster_data = qemu_try_blockalign(bs->file->bs, QCOW_MAX_CRYPT_CLUSTERS
> * s->cluster_size + 512);
> if (s->cluster_data == NULL) {
> error_setg(errp, "Could not allocate temporary cluster buffer");
> @@ -1119,7 +1119,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
> ret = -EINVAL;
> goto fail;
> }
> - ret = bdrv_pread(bs->file, header.backing_file_offset,
> + ret = bdrv_pread(bs->file->bs, header.backing_file_offset,
> bs->backing_file, len);
> if (ret < 0) {
> error_setg_errno(errp, -ret, "Could not read backing file name");
> @@ -1429,8 +1429,9 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
> */
> if (!cluster_data) {
> cluster_data =
> - qemu_try_blockalign(bs->file, QCOW_MAX_CRYPT_CLUSTERS
> - * s->cluster_size);
> + qemu_try_blockalign(bs->file->bs,
> + QCOW_MAX_CRYPT_CLUSTERS
> + * s->cluster_size);
> if (cluster_data == NULL) {
> ret = -ENOMEM;
> goto fail;
> @@ -1446,7 +1447,7 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
>
> BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
> qemu_co_mutex_unlock(&s->lock);
> - ret = bdrv_co_readv(bs->file,
> + ret = bdrv_co_readv(bs->file->bs,
> (cluster_offset >> 9) + index_in_cluster,
> cur_nr_sectors, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> @@ -1543,7 +1544,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
> Error *err = NULL;
> assert(s->cipher);
> if (!cluster_data) {
> - cluster_data = qemu_try_blockalign(bs->file,
> + cluster_data = qemu_try_blockalign(bs->file->bs,
> QCOW_MAX_CRYPT_CLUSTERS
> * s->cluster_size);
> if (cluster_data == NULL) {
> @@ -1580,7 +1581,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
> BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
> trace_qcow2_writev_data(qemu_coroutine_self(),
> (cluster_offset >> 9) + index_in_cluster);
> - ret = bdrv_co_writev(bs->file,
> + ret = bdrv_co_writev(bs->file->bs,
> (cluster_offset >> 9) + index_in_cluster,
> cur_nr_sectors, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> @@ -1703,7 +1704,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
>
> qcow2_close(bs);
>
> - bdrv_invalidate_cache(bs->file, &local_err);
> + bdrv_invalidate_cache(bs->file->bs, &local_err);
> if (local_err) {
> error_propagate(errp, local_err);
> return;
> @@ -1911,7 +1912,7 @@ int qcow2_update_header(BlockDriverState *bs)
> }
>
> /* Write the new header */
> - ret = bdrv_pwrite(bs->file, 0, header, s->cluster_size);
> + ret = bdrv_pwrite(bs->file->bs, 0, header, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -1991,7 +1992,8 @@ static int preallocate(BlockDriverState *bs)
> if (host_offset != 0) {
> uint8_t buf[BDRV_SECTOR_SIZE];
> memset(buf, 0, BDRV_SECTOR_SIZE);
> - ret = bdrv_write(bs->file, (host_offset >> BDRV_SECTOR_BITS) + num - 1,
> + ret = bdrv_write(bs->file->bs,
> + (host_offset >> BDRV_SECTOR_BITS) + num - 1,
> buf, 1);
> if (ret < 0) {
> return ret;
> @@ -2403,7 +2405,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
>
> /* write updated header.size */
> offset = cpu_to_be64(offset);
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
> + ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, size),
> &offset, sizeof(uint64_t));
> if (ret < 0) {
> return ret;
> @@ -2427,8 +2429,8 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
> if (nb_sectors == 0) {
> /* align end of file to a sector boundary to ease reading with
> sector based I/Os */
> - cluster_offset = bdrv_getlength(bs->file);
> - return bdrv_truncate(bs->file, cluster_offset);
> + cluster_offset = bdrv_getlength(bs->file->bs);
> + return bdrv_truncate(bs->file->bs, cluster_offset);
> }
>
> if (nb_sectors != s->cluster_sectors) {
> @@ -2495,7 +2497,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
> - ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
> + ret = bdrv_pwrite(bs->file->bs, cluster_offset, out_buf, out_len);
> if (ret < 0) {
> goto fail;
> }
> @@ -2544,7 +2546,7 @@ static int make_completely_empty(BlockDriverState *bs)
> /* After this call, neither the in-memory nor the on-disk refcount
> * information accurately describe the actual references */
>
> - ret = bdrv_write_zeroes(bs->file, s->l1_table_offset / BDRV_SECTOR_SIZE,
> + ret = bdrv_write_zeroes(bs->file->bs, s->l1_table_offset / BDRV_SECTOR_SIZE,
> l1_clusters * s->cluster_sectors, 0);
> if (ret < 0) {
> goto fail_broken_refcounts;
> @@ -2558,7 +2560,7 @@ static int make_completely_empty(BlockDriverState *bs)
> * overwrite parts of the existing refcount and L1 table, which is not
> * an issue because the dirty flag is set, complete data loss is in fact
> * desired and partial data loss is consequently fine as well */
> - ret = bdrv_write_zeroes(bs->file, s->cluster_size / BDRV_SECTOR_SIZE,
> + ret = bdrv_write_zeroes(bs->file->bs, s->cluster_size / BDRV_SECTOR_SIZE,
> (2 + l1_clusters) * s->cluster_size /
> BDRV_SECTOR_SIZE, 0);
> /* This call (even if it failed overall) may have overwritten on-disk
> @@ -2578,7 +2580,7 @@ static int make_completely_empty(BlockDriverState *bs)
> cpu_to_be64w(&l1_ofs_rt_ofs_cls.l1_offset, 3 * s->cluster_size);
> cpu_to_be64w(&l1_ofs_rt_ofs_cls.reftable_offset, s->cluster_size);
> cpu_to_be32w(&l1_ofs_rt_ofs_cls.reftable_clusters, 1);
> - ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_table_offset),
> + ret = bdrv_pwrite_sync(bs->file->bs, offsetof(QCowHeader, l1_table_offset),
> &l1_ofs_rt_ofs_cls, sizeof(l1_ofs_rt_ofs_cls));
> if (ret < 0) {
> goto fail_broken_refcounts;
> @@ -2609,7 +2611,7 @@ static int make_completely_empty(BlockDriverState *bs)
>
> /* Enter the first refblock into the reftable */
> rt_entry = cpu_to_be64(2 * s->cluster_size);
> - ret = bdrv_pwrite_sync(bs->file, s->cluster_size,
> + ret = bdrv_pwrite_sync(bs->file->bs, s->cluster_size,
> &rt_entry, sizeof(rt_entry));
> if (ret < 0) {
> goto fail_broken_refcounts;
> @@ -2634,7 +2636,7 @@ static int make_completely_empty(BlockDriverState *bs)
> goto fail;
> }
>
> - ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size);
> + ret = bdrv_truncate(bs->file->bs, (3 + l1_clusters) * s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -2769,7 +2771,7 @@ static void dump_refcounts(BlockDriverState *bs)
> int64_t nb_clusters, k, k1, size;
> int refcount;
>
> - size = bdrv_getlength(bs->file);
> + size = bdrv_getlength(bs->file->bs);
> nb_clusters = size_to_clusters(s, size);
> for(k = 0; k < nb_clusters;) {
> k1 = k;
> diff --git a/block/qed-table.c b/block/qed-table.c
> index 513aa87..f4219b8 100644
> --- a/block/qed-table.c
> +++ b/block/qed-table.c
> @@ -63,7 +63,7 @@ static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
> read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size,
>
> qemu_iovec_init_external(qiov, &read_table_cb->iov, 1);
> - bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
> + bdrv_aio_readv(s->bs->file->bs, offset / BDRV_SECTOR_SIZE, qiov,
> qiov->size / BDRV_SECTOR_SIZE,
> qed_read_table_cb, read_table_cb);
> }
> @@ -152,7 +152,7 @@ static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
> /* Adjust for offset into table */
> offset += start * sizeof(uint64_t);
>
> - bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
> + bdrv_aio_writev(s->bs->file->bs, offset / BDRV_SECTOR_SIZE,
> &write_table_cb->qiov,
> write_table_cb->qiov.size / BDRV_SECTOR_SIZE,
> qed_write_table_cb, write_table_cb);
> diff --git a/block/qed.c b/block/qed.c
> index a7ff1d9..d953f8c 100644
> --- a/block/qed.c
> +++ b/block/qed.c
> @@ -82,7 +82,7 @@ int qed_write_header_sync(BDRVQEDState *s)
> int ret;
>
> qed_header_cpu_to_le(&s->header, &le);
> - ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le));
> + ret = bdrv_pwrite(s->bs->file->bs, 0, &le, sizeof(le));
> if (ret != sizeof(le)) {
> return ret;
> }
> @@ -119,7 +119,7 @@ static void qed_write_header_read_cb(void *opaque, int ret)
> /* Update header */
> qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf);
>
> - bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov,
> + bdrv_aio_writev(s->bs->file->bs, 0, &write_header_cb->qiov,
> write_header_cb->nsectors, qed_write_header_cb,
> write_header_cb);
> }
> @@ -152,7 +152,7 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb,
> write_header_cb->iov.iov_len = len;
> qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1);
>
> - bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors,
> + bdrv_aio_readv(s->bs->file->bs, 0, &write_header_cb->qiov, nsectors,
> qed_write_header_read_cb, write_header_cb);
> }
>
> @@ -392,7 +392,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> s->bs = bs;
> QSIMPLEQ_INIT(&s->allocating_write_reqs);
>
> - ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));
> + ret = bdrv_pread(bs->file->bs, 0, &le_header, sizeof(le_header));
> if (ret < 0) {
> return ret;
> }
> @@ -416,7 +416,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* Round down file size to the last cluster */
> - file_size = bdrv_getlength(bs->file);
> + file_size = bdrv_getlength(bs->file->bs);
> if (file_size < 0) {
> return file_size;
> }
> @@ -452,7 +452,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> return -EINVAL;
> }
>
> - ret = qed_read_string(bs->file, s->header.backing_filename_offset,
> + ret = qed_read_string(bs->file->bs, s->header.backing_filename_offset,
> s->header.backing_filename_size, bs->backing_file,
> sizeof(bs->backing_file));
> if (ret < 0) {
> @@ -471,7 +471,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> * feature is no longer valid.
> */
> if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&
> - !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) {
> + !bdrv_is_read_only(bs->file->bs) && !(flags & BDRV_O_INCOMING)) {
> s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;
>
> ret = qed_write_header_sync(s);
> @@ -480,7 +480,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* From here on only known autoclear feature bits are valid */
> - bdrv_flush(bs->file);
> + bdrv_flush(bs->file->bs);
> }
>
> s->l1_table = qed_alloc_table(s);
> @@ -498,7 +498,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
> * potentially inconsistent images to be opened read-only. This can
> * aid data recovery from an otherwise inconsistent image.
> */
> - if (!bdrv_is_read_only(bs->file) &&
> + if (!bdrv_is_read_only(bs->file->bs) &&
> !(flags & BDRV_O_INCOMING)) {
> BdrvCheckResult result = {0};
>
> @@ -541,7 +541,7 @@ static void bdrv_qed_close(BlockDriverState *bs)
> bdrv_qed_detach_aio_context(bs);
>
> /* Ensure writes reach stable storage */
> - bdrv_flush(bs->file);
> + bdrv_flush(bs->file->bs);
>
> /* Clean shutdown, no check required on next open */
> if (s->header.features & QED_F_NEED_CHECK) {
> @@ -839,7 +839,7 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret)
> }
>
> BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE);
> - bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE,
> + bdrv_aio_writev(s->bs->file->bs, copy_cb->offset / BDRV_SECTOR_SIZE,
> ©_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE,
> qed_copy_from_backing_file_cb, copy_cb);
> }
> @@ -1055,7 +1055,7 @@ static void qed_aio_write_flush_before_l2_update(void *opaque, int ret)
> QEDAIOCB *acb = opaque;
> BDRVQEDState *s = acb_to_s(acb);
>
> - if (!bdrv_aio_flush(s->bs->file, qed_aio_write_l2_update_cb, opaque)) {
> + if (!bdrv_aio_flush(s->bs->file->bs, qed_aio_write_l2_update_cb, opaque)) {
> qed_aio_complete(acb, -EIO);
> }
> }
> @@ -1089,7 +1089,7 @@ static void qed_aio_write_main(void *opaque, int ret)
> }
>
> BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO);
> - bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE,
> + bdrv_aio_writev(s->bs->file->bs, offset / BDRV_SECTOR_SIZE,
> &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
> next_fn, acb);
> }
> @@ -1321,7 +1321,7 @@ static void qed_aio_read_data(void *opaque, int ret,
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
> - bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE,
> + bdrv_aio_readv(bs->file->bs, offset / BDRV_SECTOR_SIZE,
> &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE,
> qed_aio_next_io, acb);
> return;
> @@ -1580,7 +1580,7 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
> }
>
> /* Write new header */
> - ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len);
> + ret = bdrv_pwrite_sync(bs->file->bs, 0, buffer, buffer_len);
> g_free(buffer);
> if (ret == 0) {
> memcpy(&s->header, &new_header, sizeof(new_header));
> @@ -1596,7 +1596,7 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs, Error **errp)
>
> bdrv_qed_close(bs);
>
> - bdrv_invalidate_cache(bs->file, &local_err);
> + bdrv_invalidate_cache(bs->file->bs, &local_err);
> if (local_err) {
> error_propagate(errp, local_err);
> return;
> diff --git a/block/raw_bsd.c b/block/raw_bsd.c
> index e3d2d04..63ee911 100644
> --- a/block/raw_bsd.c
> +++ b/block/raw_bsd.c
> @@ -52,7 +52,7 @@ static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
> int nb_sectors, QEMUIOVector *qiov)
> {
> BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
> - return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);
> + return bdrv_co_readv(bs->file->bs, sector_num, nb_sectors, qiov);
> }
>
> static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
> @@ -75,7 +75,7 @@ static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
> return 0;
> }
>
> - buf = qemu_try_blockalign(bs->file, 512);
> + buf = qemu_try_blockalign(bs->file->bs, 512);
> if (!buf) {
> ret = -ENOMEM;
> goto fail;
> @@ -102,7 +102,7 @@ static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
> }
>
> BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
> - ret = bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
> + ret = bdrv_co_writev(bs->file->bs, sector_num, nb_sectors, qiov);
>
> fail:
> if (qiov == &local_qiov) {
> @@ -125,58 +125,58 @@ static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
> int64_t sector_num, int nb_sectors,
> BdrvRequestFlags flags)
> {
> - return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors, flags);
> + return bdrv_co_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags);
> }
>
> static int coroutine_fn raw_co_discard(BlockDriverState *bs,
> int64_t sector_num, int nb_sectors)
> {
> - return bdrv_co_discard(bs->file, sector_num, nb_sectors);
> + return bdrv_co_discard(bs->file->bs, sector_num, nb_sectors);
> }
>
> static int64_t raw_getlength(BlockDriverState *bs)
> {
> - return bdrv_getlength(bs->file);
> + return bdrv_getlength(bs->file->bs);
> }
>
> static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
> {
> - return bdrv_get_info(bs->file, bdi);
> + return bdrv_get_info(bs->file->bs, bdi);
> }
>
> static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
> {
> - bs->bl = bs->file->bl;
> + bs->bl = bs->file->bs->bl;
> }
>
> static int raw_truncate(BlockDriverState *bs, int64_t offset)
> {
> - return bdrv_truncate(bs->file, offset);
> + return bdrv_truncate(bs->file->bs, offset);
> }
>
> static int raw_is_inserted(BlockDriverState *bs)
> {
> - return bdrv_is_inserted(bs->file);
> + return bdrv_is_inserted(bs->file->bs);
> }
>
> static int raw_media_changed(BlockDriverState *bs)
> {
> - return bdrv_media_changed(bs->file);
> + return bdrv_media_changed(bs->file->bs);
> }
>
> static void raw_eject(BlockDriverState *bs, bool eject_flag)
> {
> - bdrv_eject(bs->file, eject_flag);
> + bdrv_eject(bs->file->bs, eject_flag);
> }
>
> static void raw_lock_medium(BlockDriverState *bs, bool locked)
> {
> - bdrv_lock_medium(bs->file, locked);
> + bdrv_lock_medium(bs->file->bs, locked);
> }
>
> static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
> {
> - return bdrv_ioctl(bs->file, req, buf);
> + return bdrv_ioctl(bs->file->bs, req, buf);
> }
>
> static BlockAIOCB *raw_aio_ioctl(BlockDriverState *bs,
> @@ -184,12 +184,12 @@ static BlockAIOCB *raw_aio_ioctl(BlockDriverState *bs,
> BlockCompletionFunc *cb,
> void *opaque)
> {
> - return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
> + return bdrv_aio_ioctl(bs->file->bs, req, buf, cb, opaque);
> }
>
> static int raw_has_zero_init(BlockDriverState *bs)
> {
> - return bdrv_has_zero_init(bs->file);
> + return bdrv_has_zero_init(bs->file->bs);
> }
>
> static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
> @@ -207,7 +207,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
> static int raw_open(BlockDriverState *bs, QDict *options, int flags,
> Error **errp)
> {
> - bs->sg = bs->file->sg;
> + bs->sg = bs->file->bs->sg;
>
> if (bs->probed && !bdrv_is_read_only(bs)) {
> fprintf(stderr,
> @@ -217,7 +217,7 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
> "raw images, write operations on block 0 will be restricted.\n"
> " Specify the 'raw' format explicitly to remove the "
> "restrictions.\n",
> - bs->file->filename);
> + bs->file->bs->filename);
> }
>
> return 0;
> @@ -237,12 +237,12 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
>
> static int raw_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
> {
> - return bdrv_probe_blocksizes(bs->file, bsz);
> + return bdrv_probe_blocksizes(bs->file->bs, bsz);
> }
>
> static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
> {
> - return bdrv_probe_geometry(bs->file, geo);
> + return bdrv_probe_geometry(bs->file->bs, geo);
> }
>
> BlockDriver bdrv_raw = {
> diff --git a/block/snapshot.c b/block/snapshot.c
> index 49e143e..89500f2 100644
> --- a/block/snapshot.c
> +++ b/block/snapshot.c
> @@ -149,7 +149,7 @@ int bdrv_can_snapshot(BlockDriverState *bs)
>
> if (!drv->bdrv_snapshot_create) {
> if (bs->file != NULL) {
> - return bdrv_can_snapshot(bs->file);
> + return bdrv_can_snapshot(bs->file->bs);
> }
> return 0;
> }
> @@ -168,7 +168,7 @@ int bdrv_snapshot_create(BlockDriverState *bs,
> return drv->bdrv_snapshot_create(bs, sn_info);
> }
> if (bs->file) {
> - return bdrv_snapshot_create(bs->file, sn_info);
> + return bdrv_snapshot_create(bs->file->bs, sn_info);
> }
> return -ENOTSUP;
> }
> @@ -188,10 +188,10 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
>
> if (bs->file) {
> drv->bdrv_close(bs);
> - ret = bdrv_snapshot_goto(bs->file, snapshot_id);
> + ret = bdrv_snapshot_goto(bs->file->bs, snapshot_id);
> open_ret = drv->bdrv_open(bs, NULL, bs->open_flags, NULL);
> if (open_ret < 0) {
> - bdrv_unref(bs->file);
> + bdrv_unref(bs->file->bs);
> bs->drv = NULL;
> return open_ret;
> }
> @@ -245,7 +245,7 @@ int bdrv_snapshot_delete(BlockDriverState *bs,
> return drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
> }
> if (bs->file) {
> - return bdrv_snapshot_delete(bs->file, snapshot_id, name, errp);
> + return bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp);
> }
> error_setg(errp, "Block format '%s' used by device '%s' "
> "does not support internal snapshot deletion",
> @@ -283,7 +283,7 @@ int bdrv_snapshot_list(BlockDriverState *bs,
> return drv->bdrv_snapshot_list(bs, psn_info);
> }
> if (bs->file) {
> - return bdrv_snapshot_list(bs->file, psn_info);
> + return bdrv_snapshot_list(bs->file->bs, psn_info);
> }
> return -ENOTSUP;
> }
> diff --git a/block/vdi.c b/block/vdi.c
> index 062a654..17626d4 100644
> --- a/block/vdi.c
> +++ b/block/vdi.c
> @@ -399,7 +399,7 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
>
> logout("\n");
>
> - ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1);
> + ret = bdrv_read(bs->file->bs, 0, (uint8_t *)&header, 1);
> if (ret < 0) {
> goto fail;
> }
> @@ -490,13 +490,14 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
>
> bmap_size = header.blocks_in_image * sizeof(uint32_t);
> bmap_size = DIV_ROUND_UP(bmap_size, SECTOR_SIZE);
> - s->bmap = qemu_try_blockalign(bs->file, bmap_size * SECTOR_SIZE);
> + s->bmap = qemu_try_blockalign(bs->file->bs, bmap_size * SECTOR_SIZE);
> if (s->bmap == NULL) {
> ret = -ENOMEM;
> goto fail;
> }
>
> - ret = bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size);
> + ret = bdrv_read(bs->file->bs, s->bmap_sector, (uint8_t *)s->bmap,
> + bmap_size);
> if (ret < 0) {
> goto fail_free_bmap;
> }
> @@ -585,7 +586,7 @@ static int vdi_co_read(BlockDriverState *bs,
> uint64_t offset = s->header.offset_data / SECTOR_SIZE +
> (uint64_t)bmap_entry * s->block_sectors +
> sector_in_block;
> - ret = bdrv_read(bs->file, offset, buf, n_sectors);
> + ret = bdrv_read(bs->file->bs, offset, buf, n_sectors);
> }
> logout("%u sectors read\n", n_sectors);
>
> @@ -653,7 +654,7 @@ static int vdi_co_write(BlockDriverState *bs,
> * acquire the lock and thus the padded cluster is written before
> * the other coroutines can write to the affected area. */
> qemu_co_mutex_lock(&s->write_lock);
> - ret = bdrv_write(bs->file, offset, block, s->block_sectors);
> + ret = bdrv_write(bs->file->bs, offset, block, s->block_sectors);
> qemu_co_mutex_unlock(&s->write_lock);
> } else {
> uint64_t offset = s->header.offset_data / SECTOR_SIZE +
> @@ -669,7 +670,7 @@ static int vdi_co_write(BlockDriverState *bs,
> * that that write operation has returned (there may be other writes
> * in flight, but they do not concern this very operation). */
> qemu_co_mutex_unlock(&s->write_lock);
> - ret = bdrv_write(bs->file, offset, buf, n_sectors);
> + ret = bdrv_write(bs->file->bs, offset, buf, n_sectors);
> }
>
> nb_sectors -= n_sectors;
> @@ -694,7 +695,7 @@ static int vdi_co_write(BlockDriverState *bs,
> assert(VDI_IS_ALLOCATED(bmap_first));
> *header = s->header;
> vdi_header_to_le(header);
> - ret = bdrv_write(bs->file, 0, block, 1);
> + ret = bdrv_write(bs->file->bs, 0, block, 1);
> g_free(block);
> block = NULL;
>
> @@ -712,7 +713,7 @@ static int vdi_co_write(BlockDriverState *bs,
> base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;
> logout("will write %u block map sectors starting from entry %u\n",
> n_sectors, bmap_first);
> - ret = bdrv_write(bs->file, offset, base, n_sectors);
> + ret = bdrv_write(bs->file->bs, offset, base, n_sectors);
> }
>
> return ret;
> diff --git a/block/vhdx-log.c b/block/vhdx-log.c
> index 47fec63..47ae4b1 100644
> --- a/block/vhdx-log.c
> +++ b/block/vhdx-log.c
> @@ -81,7 +81,7 @@ static int vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log,
>
> offset = log->offset + read;
>
> - ret = bdrv_pread(bs->file, offset, hdr, sizeof(VHDXLogEntryHeader));
> + ret = bdrv_pread(bs->file->bs, offset, hdr, sizeof(VHDXLogEntryHeader));
> if (ret < 0) {
> goto exit;
> }
> @@ -141,7 +141,7 @@ static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
> }
> offset = log->offset + read;
>
> - ret = bdrv_pread(bs->file, offset, buffer, VHDX_LOG_SECTOR_SIZE);
> + ret = bdrv_pread(bs->file->bs, offset, buffer, VHDX_LOG_SECTOR_SIZE);
> if (ret < 0) {
> goto exit;
> }
> @@ -191,7 +191,8 @@ static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log,
> /* full */
> break;
> }
> - ret = bdrv_pwrite(bs->file, offset, buffer_tmp, VHDX_LOG_SECTOR_SIZE);
> + ret = bdrv_pwrite(bs->file->bs, offset, buffer_tmp,
> + VHDX_LOG_SECTOR_SIZE);
> if (ret < 0) {
> goto exit;
> }
> @@ -353,7 +354,7 @@ static int vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s,
> }
>
> desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);
> - desc_entries = qemu_try_blockalign(bs->file,
> + desc_entries = qemu_try_blockalign(bs->file->bs,
> desc_sectors * VHDX_LOG_SECTOR_SIZE);
> if (desc_entries == NULL) {
> ret = -ENOMEM;
> @@ -462,7 +463,7 @@ static int vhdx_log_flush_desc(BlockDriverState *bs, VHDXLogDescriptor *desc,
>
> /* count is only > 1 if we are writing zeroes */
> for (i = 0; i < count; i++) {
> - ret = bdrv_pwrite_sync(bs->file, file_offset, buffer,
> + ret = bdrv_pwrite_sync(bs->file->bs, file_offset, buffer,
> VHDX_LOG_SECTOR_SIZE);
> if (ret < 0) {
> goto exit;
> @@ -509,7 +510,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
> /* if the log shows a FlushedFileOffset larger than our current file
> * size, then that means the file has been truncated / corrupted, and
> * we must refused to open it / use it */
> - if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file)) {
> + if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) {
> ret = -EINVAL;
> goto exit;
> }
> @@ -539,12 +540,12 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
> goto exit;
> }
> }
> - if (bdrv_getlength(bs->file) < desc_entries->hdr.last_file_offset) {
> + if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) {
> new_file_size = desc_entries->hdr.last_file_offset;
> 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, new_file_size);
> + bdrv_truncate(bs->file->bs, new_file_size);
> }
> }
> qemu_vfree(desc_entries);
> @@ -908,8 +909,8 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
> .sequence_number = s->log.sequence,
> .descriptor_count = sectors,
> .reserved = 0,
> - .flushed_file_offset = bdrv_getlength(bs->file),
> - .last_file_offset = bdrv_getlength(bs->file),
> + .flushed_file_offset = bdrv_getlength(bs->file->bs),
> + .last_file_offset = bdrv_getlength(bs->file->bs),
> };
>
> new_hdr.log_guid = header->log_guid;
> @@ -940,7 +941,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
>
> if (i == 0 && leading_length) {
> /* partial sector at the front of the buffer */
> - ret = bdrv_pread(bs->file, file_offset, merged_sector,
> + ret = bdrv_pread(bs->file->bs, file_offset, merged_sector,
> VHDX_LOG_SECTOR_SIZE);
> if (ret < 0) {
> goto exit;
> @@ -950,7 +951,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
> sector_write = merged_sector;
> } else if (i == sectors - 1 && trailing_length) {
> /* partial sector at the end of the buffer */
> - ret = bdrv_pread(bs->file,
> + ret = bdrv_pread(bs->file->bs,
> file_offset,
> merged_sector + trailing_length,
> VHDX_LOG_SECTOR_SIZE - trailing_length);
> diff --git a/block/vhdx.c b/block/vhdx.c
> index d3bb1bd..2fe9a5e 100644
> --- a/block/vhdx.c
> +++ b/block/vhdx.c
> @@ -375,7 +375,7 @@ static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s,
> inactive_header->log_guid = *log_guid;
> }
>
> - ret = vhdx_write_header(bs->file, inactive_header, header_offset, true);
> + ret = vhdx_write_header(bs->file->bs, inactive_header, header_offset, true);
> if (ret < 0) {
> goto exit;
> }
> @@ -427,7 +427,8 @@ static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
> /* We have to read the whole VHDX_HEADER_SIZE instead of
> * sizeof(VHDXHeader), because the checksum is over the whole
> * region */
> - ret = bdrv_pread(bs->file, VHDX_HEADER1_OFFSET, buffer, VHDX_HEADER_SIZE);
> + ret = bdrv_pread(bs->file->bs, VHDX_HEADER1_OFFSET, buffer,
> + VHDX_HEADER_SIZE);
> if (ret < 0) {
> goto fail;
> }
> @@ -443,7 +444,8 @@ static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,
> }
> }
>
> - ret = bdrv_pread(bs->file, VHDX_HEADER2_OFFSET, buffer, VHDX_HEADER_SIZE);
> + ret = bdrv_pread(bs->file->bs, VHDX_HEADER2_OFFSET, buffer,
> + VHDX_HEADER_SIZE);
> if (ret < 0) {
> goto fail;
> }
> @@ -516,7 +518,7 @@ static int vhdx_open_region_tables(BlockDriverState *bs, BDRVVHDXState *s)
> * whole block */
> buffer = qemu_blockalign(bs, VHDX_HEADER_BLOCK_SIZE);
>
> - ret = bdrv_pread(bs->file, VHDX_REGION_TABLE_OFFSET, buffer,
> + ret = bdrv_pread(bs->file->bs, VHDX_REGION_TABLE_OFFSET, buffer,
> VHDX_HEADER_BLOCK_SIZE);
> if (ret < 0) {
> goto fail;
> @@ -629,7 +631,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
>
> buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE);
>
> - ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer,
> + ret = bdrv_pread(bs->file->bs, s->metadata_rt.file_offset, buffer,
> VHDX_METADATA_TABLE_MAX_SIZE);
> if (ret < 0) {
> goto exit;
> @@ -732,7 +734,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
> goto exit;
> }
>
> - ret = bdrv_pread(bs->file,
> + ret = bdrv_pread(bs->file->bs,
> s->metadata_entries.file_parameters_entry.offset
> + s->metadata_rt.file_offset,
> &s->params,
> @@ -767,7 +769,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
> /* determine virtual disk size, logical sector size,
> * and phys sector size */
>
> - ret = bdrv_pread(bs->file,
> + ret = bdrv_pread(bs->file->bs,
> s->metadata_entries.virtual_disk_size_entry.offset
> + s->metadata_rt.file_offset,
> &s->virtual_disk_size,
> @@ -775,7 +777,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
> if (ret < 0) {
> goto exit;
> }
> - ret = bdrv_pread(bs->file,
> + ret = bdrv_pread(bs->file->bs,
> s->metadata_entries.logical_sector_size_entry.offset
> + s->metadata_rt.file_offset,
> &s->logical_sector_size,
> @@ -783,7 +785,7 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
> if (ret < 0) {
> goto exit;
> }
> - ret = bdrv_pread(bs->file,
> + ret = bdrv_pread(bs->file->bs,
> s->metadata_entries.phys_sector_size_entry.offset
> + s->metadata_rt.file_offset,
> &s->physical_sector_size,
> @@ -906,7 +908,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
> QLIST_INIT(&s->regions);
>
> /* validate the file signature */
> - ret = bdrv_pread(bs->file, 0, &signature, sizeof(uint64_t));
> + ret = bdrv_pread(bs->file->bs, 0, &signature, sizeof(uint64_t));
> if (ret < 0) {
> goto fail;
> }
> @@ -959,13 +961,13 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* s->bat is freed in vhdx_close() */
> - s->bat = qemu_try_blockalign(bs->file, s->bat_rt.length);
> + s->bat = qemu_try_blockalign(bs->file->bs, s->bat_rt.length);
> if (s->bat == NULL) {
> ret = -ENOMEM;
> goto fail;
> }
>
> - ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);
> + ret = bdrv_pread(bs->file->bs, s->bat_offset, s->bat, s->bat_rt.length);
> if (ret < 0) {
> goto fail;
> }
> @@ -1118,7 +1120,7 @@ static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
> break;
> case PAYLOAD_BLOCK_FULLY_PRESENT:
> qemu_co_mutex_unlock(&s->lock);
> - ret = bdrv_co_readv(bs->file,
> + ret = bdrv_co_readv(bs->file->bs,
> sinfo.file_offset >> BDRV_SECTOR_BITS,
> sinfo.sectors_avail, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> @@ -1156,12 +1158,12 @@ exit:
> static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
> uint64_t *new_offset)
> {
> - *new_offset = bdrv_getlength(bs->file);
> + *new_offset = bdrv_getlength(bs->file->bs);
>
> /* 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, *new_offset + s->block_size);
> + return bdrv_truncate(bs->file->bs, *new_offset + s->block_size);
> }
>
> /*
> @@ -1260,7 +1262,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
> /* Queue another write of zero buffers if the underlying file
> * does not zero-fill on file extension */
>
> - if (bdrv_has_zero_init(bs->file) == 0) {
> + if (bdrv_has_zero_init(bs->file->bs) == 0) {
> use_zero_buffers = true;
>
> /* zero fill the front, if any */
> @@ -1327,7 +1329,7 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
> }
> /* block exists, so we can just overwrite it */
> qemu_co_mutex_unlock(&s->lock);
> - ret = bdrv_co_writev(bs->file,
> + ret = bdrv_co_writev(bs->file->bs,
> sinfo.file_offset >> BDRV_SECTOR_BITS,
> sectors_to_write, &hd_qiov);
> qemu_co_mutex_lock(&s->lock);
> diff --git a/block/vmdk.c b/block/vmdk.c
> index 9702132..9f7e7db 100644
> --- a/block/vmdk.c
> +++ b/block/vmdk.c
> @@ -221,7 +221,7 @@ static void vmdk_free_extents(BlockDriverState *bs)
> g_free(e->l2_cache);
> g_free(e->l1_backup_table);
> g_free(e->type);
> - if (e->file != bs->file_child) {
> + if (e->file != bs->file) {
> bdrv_unref_child(bs, e->file);
> }
> }
> @@ -248,7 +248,7 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
> BDRVVmdkState *s = bs->opaque;
> int ret;
>
> - ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
> + ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
> if (ret < 0) {
> return 0;
> }
> @@ -278,7 +278,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
> BDRVVmdkState *s = bs->opaque;
> int ret;
>
> - ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
> + ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
> if (ret < 0) {
> return ret;
> }
> @@ -297,7 +297,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
> pstrcat(desc, sizeof(desc), tmp_desc);
> }
>
> - ret = bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE);
> + ret = bdrv_pwrite_sync(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
> if (ret < 0) {
> return ret;
> }
> @@ -340,7 +340,7 @@ static int vmdk_parent_open(BlockDriverState *bs)
> int ret;
>
> desc[DESC_SIZE] = '\0';
> - ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
> + ret = bdrv_pread(bs->file->bs, s->desc_offset, desc, DESC_SIZE);
> if (ret < 0) {
> return ret;
> }
> @@ -621,7 +621,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
> } QEMU_PACKED footer;
>
> ret = bdrv_pread(file->bs,
> - bs->file->total_sectors * 512 - 1536,
> + bs->file->bs->total_sectors * 512 - 1536,
> &footer, sizeof(footer));
> if (ret < 0) {
> error_setg_errno(errp, -ret, "Failed to read footer");
> @@ -819,7 +819,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
> !desc_file_path[0])
> {
> error_setg(errp, "Cannot use relative extent paths with VMDK "
> - "descriptor file '%s'", bs->file->filename);
> + "descriptor file '%s'", bs->file->bs->filename);
> return -EINVAL;
> }
>
> @@ -905,7 +905,8 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
> }
> s->create_type = g_strdup(ct);
> s->desc_offset = 0;
> - ret = vmdk_parse_extents(buf, bs, bs->file->exact_filename, options, errp);
> + ret = vmdk_parse_extents(buf, bs, bs->file->bs->exact_filename, options,
> + errp);
> exit:
> return ret;
> }
> @@ -918,7 +919,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
> BDRVVmdkState *s = bs->opaque;
> uint32_t magic;
>
> - buf = vmdk_read_desc(bs->file, 0, errp);
> + buf = vmdk_read_desc(bs->file->bs, 0, errp);
> if (!buf) {
> return -EINVAL;
> }
> @@ -927,7 +928,7 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
> switch (magic) {
> case VMDK3_MAGIC:
> case VMDK4_MAGIC:
> - ret = vmdk_open_sparse(bs, bs->file_child, flags, buf, options,
> + ret = vmdk_open_sparse(bs, bs->file, flags, buf, options,
> errp);
> s->desc_offset = 0x200;
> break;
> @@ -1275,7 +1276,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
> break;
> case VMDK_OK:
> ret = BDRV_BLOCK_DATA;
> - if (extent->file == bs->file_child && !extent->compressed) {
> + if (extent->file == bs->file && !extent->compressed) {
> ret |= BDRV_BLOCK_OFFSET_VALID | offset;
> }
>
> @@ -2051,12 +2052,12 @@ static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
> int64_t r;
> BDRVVmdkState *s = bs->opaque;
>
> - ret = bdrv_get_allocated_file_size(bs->file);
> + ret = bdrv_get_allocated_file_size(bs->file->bs);
> if (ret < 0) {
> return ret;
> }
> for (i = 0; i < s->num_extents; i++) {
> - if (s->extents[i].file == bs->file_child) {
> + if (s->extents[i].file == bs->file) {
> continue;
> }
> r = bdrv_get_allocated_file_size(s->extents[i].file->bs);
> diff --git a/block/vpc.c b/block/vpc.c
> index 2b3b518..299d373 100644
> --- a/block/vpc.c
> +++ b/block/vpc.c
> @@ -172,14 +172,14 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
> int disk_type = VHD_DYNAMIC;
> int ret;
>
> - ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);
> + ret = bdrv_pread(bs->file->bs, 0, s->footer_buf, HEADER_SIZE);
> if (ret < 0) {
> goto fail;
> }
>
> footer = (VHDFooter *) s->footer_buf;
> if (strncmp(footer->creator, "conectix", 8)) {
> - int64_t offset = bdrv_getlength(bs->file);
> + int64_t offset = bdrv_getlength(bs->file->bs);
> if (offset < 0) {
> ret = offset;
> goto fail;
> @@ -189,7 +189,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> /* If a fixed disk, the footer is found only at the end of the file */
> - ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,
> + ret = bdrv_pread(bs->file->bs, offset-HEADER_SIZE, s->footer_buf,
> HEADER_SIZE);
> if (ret < 0) {
> goto fail;
> @@ -232,7 +232,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
> }
>
> if (disk_type == VHD_DYNAMIC) {
> - ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
> + ret = bdrv_pread(bs->file->bs, be64_to_cpu(footer->data_offset), buf,
> HEADER_SIZE);
> if (ret < 0) {
> goto fail;
> @@ -280,7 +280,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
>
> pagetable_size = (uint64_t) s->max_table_entries * 4;
>
> - s->pagetable = qemu_try_blockalign(bs->file, pagetable_size);
> + s->pagetable = qemu_try_blockalign(bs->file->bs, pagetable_size);
> if (s->pagetable == NULL) {
> ret = -ENOMEM;
> goto fail;
> @@ -288,7 +288,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
>
> s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
>
> - ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable, pagetable_size);
> + ret = bdrv_pread(bs->file->bs, s->bat_offset, s->pagetable,
> + pagetable_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -308,7 +309,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
> }
> }
>
> - if (s->free_data_block_offset > bdrv_getlength(bs->file)) {
> + if (s->free_data_block_offset > bdrv_getlength(bs->file->bs)) {
> error_setg(errp, "block-vpc: free_data_block_offset points after "
> "the end of file. The image has been truncated.");
> ret = -EINVAL;
> @@ -383,7 +384,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
>
> s->last_bitmap_offset = bitmap_offset;
> memset(bitmap, 0xff, s->bitmap_size);
> - bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
> + bdrv_pwrite_sync(bs->file->bs, bitmap_offset, bitmap, s->bitmap_size);
> }
>
> return block_offset;
> @@ -401,7 +402,7 @@ static int rewrite_footer(BlockDriverState* bs)
> BDRVVPCState *s = bs->opaque;
> int64_t offset = s->free_data_block_offset;
>
> - ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
> + ret = bdrv_pwrite_sync(bs->file->bs, offset, s->footer_buf, HEADER_SIZE);
> if (ret < 0)
> return ret;
>
> @@ -436,7 +437,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
>
> // Initialize the block's bitmap
> memset(bitmap, 0xff, s->bitmap_size);
> - ret = bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
> + ret = bdrv_pwrite_sync(bs->file->bs, s->free_data_block_offset, bitmap,
> s->bitmap_size);
> if (ret < 0) {
> return ret;
> @@ -451,7 +452,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
> // Write BAT entry to disk
> bat_offset = s->bat_offset + (4 * index);
> bat_value = cpu_to_be32(s->pagetable[index]);
> - ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
> + ret = bdrv_pwrite_sync(bs->file->bs, bat_offset, &bat_value, 4);
> if (ret < 0)
> goto fail;
>
> @@ -485,7 +486,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
> VHDFooter *footer = (VHDFooter *) s->footer_buf;
>
> if (be32_to_cpu(footer->type) == VHD_FIXED) {
> - return bdrv_read(bs->file, sector_num, buf, nb_sectors);
> + return bdrv_read(bs->file->bs, sector_num, buf, nb_sectors);
> }
> while (nb_sectors > 0) {
> offset = get_sector_offset(bs, sector_num, 0);
> @@ -499,7 +500,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
> if (offset == -1) {
> memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
> } else {
> - ret = bdrv_pread(bs->file, offset, buf,
> + ret = bdrv_pread(bs->file->bs, offset, buf,
> sectors * BDRV_SECTOR_SIZE);
> if (ret != sectors * BDRV_SECTOR_SIZE) {
> return -1;
> @@ -534,7 +535,7 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
> VHDFooter *footer = (VHDFooter *) s->footer_buf;
>
> if (be32_to_cpu(footer->type) == VHD_FIXED) {
> - return bdrv_write(bs->file, sector_num, buf, nb_sectors);
> + return bdrv_write(bs->file->bs, sector_num, buf, nb_sectors);
> }
> while (nb_sectors > 0) {
> offset = get_sector_offset(bs, sector_num, 1);
> @@ -551,7 +552,8 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
> return -1;
> }
>
> - ret = bdrv_pwrite(bs->file, offset, buf, sectors * BDRV_SECTOR_SIZE);
> + ret = bdrv_pwrite(bs->file->bs, offset, buf,
> + sectors * BDRV_SECTOR_SIZE);
> if (ret != sectors * BDRV_SECTOR_SIZE) {
> return -1;
> }
> @@ -878,7 +880,7 @@ static int vpc_has_zero_init(BlockDriverState *bs)
> VHDFooter *footer = (VHDFooter *) s->footer_buf;
>
> if (be32_to_cpu(footer->type) == VHD_FIXED) {
> - return bdrv_has_zero_init(bs->file);
> + return bdrv_has_zero_init(bs->file->bs);
> } else {
> return 1;
> }
> diff --git a/include/block/block.h b/include/block/block.h
> index 2dd6630..7ebb35d 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -585,7 +585,13 @@ typedef enum {
> BLKDBG_EVENT_MAX,
> } BlkDebugEvent;
>
> -#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
> +#define BLKDBG_EVENT(child, evt) \
> + do { \
> + if (child) { \
> + bdrv_debug_event(child->bs, evt); \
> + } \
> + } while(0)
> +
I'm a bit surprised you changed the argument type to BdrvChild, since adding a
BLKDBG_EVENT_CHILD is more natural to me. But that probably doesn't hurt much:
Reviewed-by: Fam Zheng <famz@redhat.com>
next prev parent reply other threads:[~2015-10-08 10:24 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-01 13:13 [Qemu-devel] [PATCH v2 00/16] block: Get rid of bdrv_swap() Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 01/16] block: Introduce BDS.file_child Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 02/16] vmdk: Use BdrvChild instead of BDS for references to extents Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 03/16] blkverify: Convert s->test_file to BdrvChild Kevin Wolf
2015-10-05 12:07 ` Alberto Garcia
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 04/16] quorum: Convert " Kevin Wolf
2015-10-07 18:16 ` Max Reitz
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 05/16] block: Convert bs->file " Kevin Wolf
2015-10-02 17:06 ` Max Reitz
2015-10-05 12:31 ` Alberto Garcia
2015-10-08 10:23 ` Fam Zheng [this message]
2015-10-09 11:34 ` Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 06/16] block: Remove bdrv_open_image() Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 07/16] block: Convert bs->backing_hd to BdrvChild Kevin Wolf
2015-10-02 17:14 ` Max Reitz
2015-10-05 12:59 ` Alberto Garcia
2015-10-09 1:39 ` Fam Zheng
2015-10-09 11:36 ` Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 08/16] block: Manage backing file references in bdrv_set_backing_hd() Kevin Wolf
2015-10-02 17:18 ` Max Reitz
2015-10-05 13:31 ` Alberto Garcia
2015-10-09 1:49 ` Fam Zheng
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 09/16] block: Split bdrv_move_feature_fields() Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 10/16] block/io: Make bdrv_requests_pending() public Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 11/16] block-backend: Add blk_set_bs() Kevin Wolf
2015-10-02 17:21 ` Max Reitz
2015-10-05 13:33 ` Alberto Garcia
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 12/16] block: Introduce parents list Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 13/16] block: Implement bdrv_append() without bdrv_swap() Kevin Wolf
2015-10-02 17:32 ` Max Reitz
2015-10-09 14:54 ` Stefan Hajnoczi
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 14/16] blockjob: Store device name at job creation Kevin Wolf
2015-10-02 17:44 ` Max Reitz
2015-10-06 13:10 ` Alberto Garcia
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 15/16] block: Add and use bdrv_replace_in_backing_chain() Kevin Wolf
2015-10-01 13:13 ` [Qemu-devel] [PATCH v2 16/16] block: Remove bdrv_swap() Kevin Wolf
2015-10-09 2:10 ` [Qemu-devel] [PATCH v2 00/16] block: Get rid of bdrv_swap() Fam Zheng
2015-10-09 14:56 ` Stefan Hajnoczi
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=20151008102301.GA10388@ad.nay.redhat.com \
--to=famz@redhat.com \
--cc=armbru@redhat.com \
--cc=berto@igalia.com \
--cc=jcody@redhat.com \
--cc=kwolf@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.