Message ID | 20211104103849.46855-2-hreitz@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block: Attempt on fixing 030-reported errors | expand |
04.11.2021 13:38, Hanna Reitz wrote: > bdrv_cor_filter_drop() modifies the block graph. That means that other > parties can also modify the block graph before it returns. Therefore, > we cannot assume that the result of a graph traversal we did before > remains valid afterwards. > > We should thus fetch `base` and `unfiltered_base` afterwards instead of > before. > > Signed-off-by: Hanna Reitz <hreitz@redhat.com> The fact that other parties can modify graph during our graph modification is a global problem.. The patch doesn't fix it, but reduces its effect in specific case.. OK. Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > --- > block/stream.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/block/stream.c b/block/stream.c > index 97bee482dc..e45113aed6 100644 > --- a/block/stream.c > +++ b/block/stream.c > @@ -54,8 +54,8 @@ static int stream_prepare(Job *job) > { > StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); > BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs); > - BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base); > - BlockDriverState *unfiltered_base = bdrv_skip_filters(base); > + BlockDriverState *base; > + BlockDriverState *unfiltered_base; > Error *local_err = NULL; > int ret = 0; > > @@ -63,6 +63,9 @@ static int stream_prepare(Job *job) > bdrv_cor_filter_drop(s->cor_filter_bs); > s->cor_filter_bs = NULL; > > + base = bdrv_filter_or_cow_bs(s->above_base); > + unfiltered_base = bdrv_skip_filters(base); > + > if (bdrv_cow_child(unfiltered_bs)) { > const char *base_id = NULL, *base_fmt = NULL; > if (unfiltered_base) { >
diff --git a/block/stream.c b/block/stream.c index 97bee482dc..e45113aed6 100644 --- a/block/stream.c +++ b/block/stream.c @@ -54,8 +54,8 @@ static int stream_prepare(Job *job) { StreamBlockJob *s = container_of(job, StreamBlockJob, common.job); BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs); - BlockDriverState *base = bdrv_filter_or_cow_bs(s->above_base); - BlockDriverState *unfiltered_base = bdrv_skip_filters(base); + BlockDriverState *base; + BlockDriverState *unfiltered_base; Error *local_err = NULL; int ret = 0; @@ -63,6 +63,9 @@ static int stream_prepare(Job *job) bdrv_cor_filter_drop(s->cor_filter_bs); s->cor_filter_bs = NULL; + base = bdrv_filter_or_cow_bs(s->above_base); + unfiltered_base = bdrv_skip_filters(base); + if (bdrv_cow_child(unfiltered_bs)) { const char *base_id = NULL, *base_fmt = NULL; if (unfiltered_base) {
bdrv_cor_filter_drop() modifies the block graph. That means that other parties can also modify the block graph before it returns. Therefore, we cannot assume that the result of a graph traversal we did before remains valid afterwards. We should thus fetch `base` and `unfiltered_base` afterwards instead of before. Signed-off-by: Hanna Reitz <hreitz@redhat.com> --- block/stream.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)