This helper will be reused in the next patch for duplications check. Signed-off-by: Alexander Ivanov <alexander.iva...@virtuozzo.com> --- block/parallels.c | 83 ++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 30 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c index ce04a4da71..eba064247a 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -469,19 +469,48 @@ static int parallels_check_outside_image(BlockDriverState *bs, return 0; } +static int64_t parallels_handle_leak(BlockDriverState *bs, + BdrvCheckResult *res, + int64_t high_off, + bool fix) +{ + BDRVParallelsState *s = bs->opaque; + int64_t size; + int ret; + + size = bdrv_getlength(bs->file->bs); + if (size < 0) { + return size; + } + + res->image_end_offset = high_off + s->cluster_size; + if (size <= res->image_end_offset) { + return 0; + } + + if (fix) { + Error *local_err = NULL; + /* + * In order to really repair the image, we must shrink it. + * That means we have to pass exact=true. + */ + ret = bdrv_truncate(bs->file, res->image_end_offset, true, + PREALLOC_MODE_OFF, 0, &local_err); + if (ret < 0) { + error_report_err(local_err); + return ret; + } + } + return size - res->image_end_offset; +} + static int parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix) { BDRVParallelsState *s = bs->opaque; - int64_t size, off, high_off, count; - int i, ret; - - size = bdrv_getlength(bs->file->bs); - if (size < 0) { - res->check_errors++; - return size; - } + int64_t off, high_off, count, cut_out; + int i; high_off = 0; for (i = 0; i < s->bat_size; i++) { @@ -491,30 +520,24 @@ static int parallels_check_leak(BlockDriverState *bs, } } - 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) { - Error *local_err = NULL; + 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; + } - /* - * In order to really repair the image, we must shrink it. - * That means we have to pass exact=true. - */ - ret = bdrv_truncate(bs->file, res->image_end_offset, true, - PREALLOC_MODE_OFF, 0, &local_err); - if (ret < 0) { - error_report_err(local_err); - res->check_errors++; - return ret; - } - res->leaks_fixed += count; - } + 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