*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "trace.h"
#include "block/block_int.h"
#include "block/blockjob_int.h"
}
if (base_len < s->common.len) {
- ret = blk_truncate(s->base, s->common.len);
+ ret = blk_truncate(s->base, s->common.len, NULL);
if (ret) {
goto out;
}
return bdrv_co_preadv(bs->backing, offset, bytes, qiov, flags);
}
+static int64_t coroutine_fn bdrv_commit_top_get_block_status(
+ BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
+ BlockDriverState **file)
+{
+ *pnum = nb_sectors;
+ *file = bs->backing->bs;
+ return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID | BDRV_BLOCK_DATA |
+ (sector_num << BDRV_SECTOR_BITS);
+}
+
+static void bdrv_commit_top_refresh_filename(BlockDriverState *bs, QDict *opts)
+{
+ bdrv_refresh_filename(bs->backing->bs);
+ pstrcpy(bs->exact_filename, sizeof(bs->exact_filename),
+ bs->backing->bs->filename);
+}
+
static void bdrv_commit_top_close(BlockDriverState *bs)
{
}
/* Dummy node that provides consistent read to its users without requiring it
* from its backing file and that allows writes on the backing file chain. */
static BlockDriver bdrv_commit_top = {
- .format_name = "commit_top",
- .bdrv_co_preadv = bdrv_commit_top_preadv,
- .bdrv_close = bdrv_commit_top_close,
- .bdrv_child_perm = bdrv_commit_top_child_perm,
+ .format_name = "commit_top",
+ .bdrv_co_preadv = bdrv_commit_top_preadv,
+ .bdrv_co_get_block_status = bdrv_commit_top_get_block_status,
+ .bdrv_refresh_filename = bdrv_commit_top_refresh_filename,
+ .bdrv_close = bdrv_commit_top_close,
+ .bdrv_child_perm = bdrv_commit_top_child_perm,
};
void commit_start(const char *job_id, BlockDriverState *bs,
if (commit_top_bs == NULL) {
goto fail;
}
+ commit_top_bs->total_sectors = top->total_sectors;
+ bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));
- bdrv_set_backing_hd(commit_top_bs, top, &error_abort);
- bdrv_set_backing_hd(overlay_bs, commit_top_bs, &error_abort);
+ bdrv_set_backing_hd(commit_top_bs, top, &local_err);
+ if (local_err) {
+ bdrv_unref(commit_top_bs);
+ commit_top_bs = NULL;
+ error_propagate(errp, local_err);
+ goto fail;
+ }
+ bdrv_set_backing_hd(overlay_bs, commit_top_bs, &local_err);
+ if (local_err) {
+ bdrv_unref(commit_top_bs);
+ commit_top_bs = NULL;
+ error_propagate(errp, local_err);
+ goto fail;
+ }
s->commit_top_bs = commit_top_bs;
bdrv_unref(commit_top_bs);
/* Required permissions are already taken with block_job_add_bdrv() */
s->top = blk_new(0, BLK_PERM_ALL);
- blk_insert_bs(s->top, top, errp);
+ ret = blk_insert_bs(s->top, top, errp);
if (ret < 0) {
goto fail;
}
error_report_err(local_err);
goto ro_cleanup;
}
+ bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(backing_file_bs));
bdrv_set_backing_hd(commit_top_bs, backing_file_bs, &error_abort);
bdrv_set_backing_hd(bs, commit_top_bs, &error_abort);
* grow the backing file image if possible. If not possible,
* we must return an error */
if (length > backing_length) {
- ret = blk_truncate(backing, length);
+ ret = blk_truncate(backing, length, &local_err);
if (ret < 0) {
+ error_report_err(local_err);
goto ro_cleanup;
}
}