mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
mirror: Fix access of uninitialised fields during start
bdrv_mirror_top_pwritev() accesses the job object when active mirroring is enabled. It disables this code during early initialisation while s->job isn't set yet. However, s->job is still set way too early when the job object isn't fully initialised. For example, &s->ops_in_flight isn't initialised yet and the in_flight bitmap doesn't exist yet. This causes crashes when a write request comes in too early. Move the assignment of s->job to when the mirror job is actually fully initialised to make sure that the mirror_top driver doesn't access it too early. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20230203152202.49054-3-kwolf@redhat.com> Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
10e5d70787
commit
32125b1460
1 changed files with 7 additions and 1 deletions
|
@ -896,6 +896,7 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||||
{
|
{
|
||||||
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||||
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
|
BlockDriverState *bs = s->mirror_top_bs->backing->bs;
|
||||||
|
MirrorBDSOpaque *mirror_top_opaque = s->mirror_top_bs->opaque;
|
||||||
BlockDriverState *target_bs = blk_bs(s->target);
|
BlockDriverState *target_bs = blk_bs(s->target);
|
||||||
bool need_drain = true;
|
bool need_drain = true;
|
||||||
BlockDeviceIoStatus iostatus;
|
BlockDeviceIoStatus iostatus;
|
||||||
|
@ -985,6 +986,12 @@ static int coroutine_fn mirror_run(Job *job, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only now the job is fully initialised and mirror_top_bs should start
|
||||||
|
* accessing it.
|
||||||
|
*/
|
||||||
|
mirror_top_opaque->job = s;
|
||||||
|
|
||||||
assert(!s->dbi);
|
assert(!s->dbi);
|
||||||
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
|
s->dbi = bdrv_dirty_iter_new(s->dirty_bitmap);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -1704,7 +1711,6 @@ static BlockJob *mirror_start_job(
|
||||||
if (!s) {
|
if (!s) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
bs_opaque->job = s;
|
|
||||||
|
|
||||||
/* The block job now has a reference to this node */
|
/* The block job now has a reference to this node */
|
||||||
bdrv_unref(mirror_top_bs);
|
bdrv_unref(mirror_top_bs);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue