diff --git a/block.c b/block.c index c6404ebbf8..5df17de5a4 100644 --- a/block.c +++ b/block.c @@ -1857,8 +1857,11 @@ int bdrv_commit(BlockDriverState *bs) buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE); for (sector = 0; sector < total_sectors; sector += n) { - if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) { - + ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n); + if (ret < 0) { + goto ro_cleanup; + } + if (ret) { if (bdrv_read(bs, sector, buf, n) != 0) { ret = -EIO; goto ro_cleanup; diff --git a/block/cow.c b/block/cow.c index f4eca10e3f..7450801cb7 100644 --- a/block/cow.c +++ b/block/cow.c @@ -212,7 +212,11 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, int ret, n; while (nb_sectors > 0) { - if (cow_co_is_allocated(bs, sector_num, nb_sectors, &n)) { + ret = cow_co_is_allocated(bs, sector_num, nb_sectors, &n); + if (ret < 0) { + return ret; + } + if (ret) { ret = bdrv_pread(bs->file, s->cow_sectors_offset + sector_num * 512, buf, n * 512); diff --git a/block/qcow2.c b/block/qcow2.c index 4d7bd78b94..cf03a14ae0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -696,13 +696,11 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs, int ret; *pnum = nb_sectors; - /* FIXME We can get errors here, but the bdrv_co_is_allocated interface - * can't pass them on today */ qemu_co_mutex_lock(&s->lock); ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset); qemu_co_mutex_unlock(&s->lock); if (ret < 0) { - *pnum = 0; + return ret; } return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO); diff --git a/block/stream.c b/block/stream.c index e640bc57e5..078ce4aa6a 100644 --- a/block/stream.c +++ b/block/stream.c @@ -124,7 +124,7 @@ wait: 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_is_allocated_above(bs->backing_hd, base, diff --git a/qemu-img.c b/qemu-img.c index 744c0d9e4d..27cc0064b6 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1508,8 +1508,15 @@ static int img_convert(int argc, char **argv) are present in both the output's and input's base images (no need to copy them). */ if (out_baseimg) { - if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, - n, &n1)) { + ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, + n, &n1); + if (ret < 0) { + error_report("error while reading metadata for sector " + "%" PRId64 ": %s", + sector_num - bs_offset, strerror(-ret)); + goto out; + } + if (!ret) { sector_num += n1; continue; } @@ -2099,6 +2106,11 @@ static int img_rebase(int argc, char **argv) /* If the cluster is allocated, we don't need to take action */ ret = bdrv_is_allocated(bs, sector, n, &n); + if (ret < 0) { + error_report("error while reading image metadata: %s", + strerror(-ret)); + goto out; + } if (ret) { continue; } diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index f91b6c4f02..8565d49336 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1830,6 +1830,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv) sector_num = offset >> 9; while (remaining) { ret = bdrv_is_allocated(bs, sector_num, remaining, &num); + if (ret < 0) { + printf("is_allocated failed: %s\n", strerror(-ret)); + return 0; + } sector_num += num; remaining -= num; if (ret) {