/* Must assign before bdrv_delete() to prevent traversing dangling pointer
* while we delete backing image instances.
*/
- top->backing_hd = base;
+ bdrv_set_backing_hd(top, base);
while (intermediate) {
BlockDriverState *unused;
unused = intermediate;
intermediate = intermediate->backing_hd;
- unused->backing_hd = NULL;
+ bdrv_set_backing_hd(unused, NULL);
bdrv_unref(unused);
}
+
+ bdrv_refresh_limits(top);
}
static void coroutine_fn stream_run(void *opaque)
int n = 0;
void *buf;
+ if (!bs->backing_hd) {
+ block_job_completed(&s->common, 0);
+ return;
+ }
+
s->common.len = bdrv_getlength(bs);
if (s->common.len < 0) {
block_job_completed(&s->common, s->common.len);
break;
}
- ret = bdrv_co_is_allocated(bs, sector_num,
- STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
+ copy = false;
+
+ ret = bdrv_is_allocated(bs, sector_num,
+ STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
if (ret == 1) {
/* Allocated in the top, no need to copy. */
- copy = false;
- } else {
+ } else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [sector_num, sector_num+n). */
- ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
- sector_num, n, &n);
+ ret = bdrv_is_allocated_above(bs->backing_hd, base,
+ sector_num, n, &n);
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
copy = (ret == 1);
}
trace_stream_one_iteration(s, sector_num, n, ret);
- if (ret >= 0 && copy) {
+ if (copy) {
if (s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
if (delay_ns > 0) {
ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
}
-static const BlockJobType stream_job_type = {
+static const BlockJobDriver stream_job_driver = {
.instance_size = sizeof(StreamBlockJob),
- .job_type = "stream",
+ .job_type = BLOCK_JOB_TYPE_STREAM,
.set_speed = stream_set_speed,
};
return;
}
- s = block_job_create(&stream_job_type, bs, speed, cb, opaque, errp);
+ s = block_job_create(&stream_job_driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}