diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2012-03-26 21:22:10 -0300 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2012-04-05 15:11:37 +0200 |
commit | 5a67a1048e1294b35940e7432d57d8cd801e6571 (patch) | |
tree | 15c28cf4bfa490b0101a98c3d2f387cbf1baac4e /block | |
parent | 28d3d1658a3692f9c34c3ecce14941faa1d2fe92 (diff) |
block stream: close unused files and update ->backing_hd
Close the now unused images that were part of the previous backing file
chain and adjust ->backing_hd, backing_filename and backing_format
properly.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=801449
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r-- | block/stream.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/block/stream.c b/block/stream.c index 61ff7a236..0efe1adfd 100644 --- a/block/stream.c +++ b/block/stream.c @@ -76,6 +76,39 @@ static int coroutine_fn stream_populate(BlockDriverState *bs, return bdrv_co_copy_on_readv(bs, sector_num, nb_sectors, &qiov); } +static void close_unused_images(BlockDriverState *top, BlockDriverState *base, + const char *base_id) +{ + BlockDriverState *intermediate; + intermediate = top->backing_hd; + + while (intermediate) { + BlockDriverState *unused; + + /* reached base */ + if (intermediate == base) { + break; + } + + unused = intermediate; + intermediate = intermediate->backing_hd; + unused->backing_hd = NULL; + bdrv_delete(unused); + } + top->backing_hd = base; + + pstrcpy(top->backing_file, sizeof(top->backing_file), ""); + pstrcpy(top->backing_format, sizeof(top->backing_format), ""); + if (base_id) { + pstrcpy(top->backing_file, sizeof(top->backing_file), base_id); + if (base->drv) { + pstrcpy(top->backing_format, sizeof(top->backing_format), + base->drv->format_name); + } + } + +} + /* * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP] * @@ -223,6 +256,7 @@ retry: base_id = s->backing_file_id; } ret = bdrv_change_backing_file(bs, base_id, NULL); + close_unused_images(bs, base, base_id); } qemu_vfree(buf); |