int snapshot_error;
} BDRVCopyBeforeWriteState;
-static coroutine_fn int cbw_co_preadv(
- BlockDriverState *bs, int64_t offset, int64_t bytes,
- QEMUIOVector *qiov, BdrvRequestFlags flags)
+static int coroutine_fn GRAPH_RDLOCK
+cbw_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
}
return 0;
}
-static int coroutine_fn cbw_co_pdiscard(BlockDriverState *bs,
- int64_t offset, int64_t bytes)
+static int coroutine_fn GRAPH_RDLOCK
+cbw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, 0);
if (ret < 0) {
return bdrv_co_pdiscard(bs->file, offset, bytes);
}
-static int coroutine_fn cbw_co_pwrite_zeroes(BlockDriverState *bs,
- int64_t offset, int64_t bytes, BdrvRequestFlags flags)
+static int coroutine_fn GRAPH_RDLOCK
+cbw_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ BdrvRequestFlags flags)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) {
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
-static coroutine_fn int cbw_co_pwritev(BlockDriverState *bs,
- int64_t offset,
- int64_t bytes,
- QEMUIOVector *qiov,
- BdrvRequestFlags flags)
+static coroutine_fn GRAPH_RDLOCK
+int cbw_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, BdrvRequestFlags flags)
{
int ret = cbw_do_copy_before_write(bs, offset, bytes, flags);
if (ret < 0) {
return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
}
-static int coroutine_fn cbw_co_flush(BlockDriverState *bs)
+static int coroutine_fn GRAPH_RDLOCK cbw_co_flush(BlockDriverState *bs)
{
if (!bs->file) {
return 0;
g_free(req);
}
-static coroutine_fn int
+static int coroutine_fn GRAPH_RDLOCK
cbw_co_preadv_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes,
QEMUIOVector *qiov, size_t qiov_offset)
{
return 0;
}
-static int coroutine_fn
+static int coroutine_fn GRAPH_RDLOCK
cbw_co_snapshot_block_status(BlockDriverState *bs,
bool want_zero, int64_t offset, int64_t bytes,
int64_t *pnum, int64_t *map,
return -EACCES;
}
- ret = bdrv_block_status(child->bs, offset, cur_bytes, pnum, map, file);
+ ret = bdrv_co_block_status(child->bs, offset, cur_bytes, pnum, map, file);
if (child == s->target) {
/*
* We refer to s->target only for areas that we've written to it.
return ret;
}
-static int coroutine_fn cbw_co_pdiscard_snapshot(BlockDriverState *bs,
- int64_t offset, int64_t bytes)
+static int coroutine_fn GRAPH_RDLOCK
+cbw_co_pdiscard_snapshot(BlockDriverState *bs, int64_t offset, int64_t bytes)
{
BDRVCopyBeforeWriteState *s = bs->opaque;
bs->file->bs->filename);
}
-static void cbw_child_perm(BlockDriverState *bs, BdrvChild *c,
- BdrvChildRole role,
- BlockReopenQueue *reopen_queue,
- uint64_t perm, uint64_t shared,
- uint64_t *nperm, uint64_t *nshared)
+static void GRAPH_RDLOCK
+cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role,
+ BlockReopenQueue *reopen_queue,
+ uint64_t perm, uint64_t shared,
+ uint64_t *nperm, uint64_t *nshared)
{
if (!(role & BDRV_CHILD_FILTERED)) {
/*
int64_t cluster_size;
g_autoptr(BlockdevOptions) full_opts = NULL;
BlockdevOptionsCbw *opts;
+ AioContext *ctx;
int ret;
full_opts = cbw_parse_options(options, errp);
return -EINVAL;
}
+ ctx = bdrv_get_aio_context(bs);
+ aio_context_acquire(ctx);
+
if (opts->bitmap) {
bitmap = block_dirty_bitmap_lookup(opts->bitmap->node,
opts->bitmap->name, NULL, errp);
if (!bitmap) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
}
s->on_cbw_error = opts->has_on_cbw_error ? opts->on_cbw_error :
s->bcs = block_copy_state_new(bs->file, s->target, bitmap, errp);
if (!s->bcs) {
error_prepend(errp, "Cannot create block-copy-state: ");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
cluster_size = block_copy_cluster_size(s->bcs);
s->done_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
if (!s->done_bitmap) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
bdrv_disable_dirty_bitmap(s->done_bitmap);
/* s->access_bitmap starts equal to bcs bitmap */
s->access_bitmap = bdrv_create_dirty_bitmap(bs, cluster_size, NULL, errp);
if (!s->access_bitmap) {
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
bdrv_disable_dirty_bitmap(s->access_bitmap);
bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
qemu_co_mutex_init(&s->lock);
QLIST_INIT(&s->frozen_read_reqs);
- return 0;
+ ret = 0;
+out:
+ aio_context_release(ctx);
+ return ret;
}
static void cbw_close(BlockDriverState *bs)
s->bcs = NULL;
}
-BlockDriver bdrv_cbw_filter = {
+static BlockDriver bdrv_cbw_filter = {
.format_name = "copy-before-write",
.instance_size = sizeof(BDRVCopyBeforeWriteState),