This helper will be reused in the next patch for duplications check. Signed-off-by: Alexander Ivanov <alexander.iva...@virtuozzo.com> --- block/parallels.c | 65 +++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 22 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c index 7b4e997ebd..dbcaf5d310 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -475,37 +475,23 @@ static int parallels_check_outside_image(BlockDriverState *bs, return 0; } -static int parallels_check_leak(BlockDriverState *bs, - BdrvCheckResult *res, - BdrvCheckMode fix) +static int64_t parallels_handle_leak(BlockDriverState *bs, + BdrvCheckResult *res, + int64_t high_off, + bool fix) { BDRVParallelsState *s = bs->opaque; - int64_t size, off, high_off, count; - uint32_t i; + int64_t size; int ret; size = bdrv_getlength(bs->file->bs); if (size < 0) { - res->check_errors++; return size; } - high_off = 0; - for (i = 0; i < s->bat_size; i++) { - off = bat2sect(s, i) << BDRV_SECTOR_BITS; - if (off > high_off) { - high_off = off; - } - } - res->image_end_offset = high_off + s->cluster_size; if (size > res->image_end_offset) { - count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size); - fprintf(stderr, "%s space leaked at the end of the image %" PRId64 "\n", - fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR", - size - res->image_end_offset); - res->leaks += count; - if (fix & BDRV_FIX_LEAKS) { + if (fix) { Error *local_err = NULL; /* @@ -516,13 +502,48 @@ static int parallels_check_leak(BlockDriverState *bs, PREALLOC_MODE_OFF, 0, &local_err); if (ret < 0) { error_report_err(local_err); - res->check_errors++; return ret; } - res->leaks_fixed += count; } } + return size - res->image_end_offset; +} + +static int parallels_check_leak(BlockDriverState *bs, + BdrvCheckResult *res, + BdrvCheckMode fix) +{ + BDRVParallelsState *s = bs->opaque; + int64_t off, high_off, count, cut_out; + uint32_t i; + + high_off = 0; + for (i = 0; i < s->bat_size; i++) { + off = bat2sect(s, i) << BDRV_SECTOR_BITS; + if (off > high_off) { + high_off = off; + } + } + + cut_out = parallels_handle_leak(bs, res, high_off, fix & BDRV_FIX_LEAKS); + if (cut_out < 0) { + res->check_errors++; + return cut_out; + } + if (cut_out == 0) { + return 0; + } + + count = DIV_ROUND_UP(cut_out, s->cluster_size); + fprintf(stderr, "%s space leaked at the end of the image %" PRId64 "\n", + fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR", cut_out); + + res->leaks += count; + if (fix & BDRV_FIX_LEAKS) { + res->leaks_fixed += count; + } + return 0; } -- 2.34.1