From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56822) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yvir2-0004IV-Q6 for qemu-devel@nongnu.org; Fri, 22 May 2015 05:03:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yvir1-0004rM-Qi for qemu-devel@nongnu.org; Fri, 22 May 2015 05:02:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39188) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yvir1-0004qt-JV for qemu-devel@nongnu.org; Fri, 22 May 2015 05:02:55 -0400 From: Stefan Hajnoczi Date: Fri, 22 May 2015 10:01:51 +0100 Message-Id: <1432285330-13994-20-git-send-email-stefanha@redhat.com> In-Reply-To: <1432285330-13994-1-git-send-email-stefanha@redhat.com> References: <1432285330-13994-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PULL 19/38] block/parallels: implement parallels_check method of block driver List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Peter Maydell , Roman Kagan , Stefan Hajnoczi , "Denis V. Lunev" From: "Denis V. Lunev" The check is very simple at the moment. It calculates necessary stats and fix only the following errors: - space leak at the end of the image. This would happens due to preallocation - clusters outside the image are zeroed. Nothing else could be done here Signed-off-by: Denis V. Lunev Reviewed-by: Roman Kagan Reviewed-by: Stefan Hajnoczi Signed-off-by: Roman Kagan Message-id: 1430207220-24458-20-git-send-email-den@openvz.org CC: Kevin Wolf Signed-off-by: Stefan Hajnoczi --- block/parallels.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/block/parallels.c b/block/parallels.c index 35ffb6f..35f231a 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -242,6 +242,90 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs, return ret; } + +static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, + BdrvCheckMode fix) +{ + BDRVParallelsState *s = bs->opaque; + int64_t size, prev_off, high_off; + int ret; + uint32_t i; + bool flush_bat = false; + int cluster_size = s->tracks << BDRV_SECTOR_BITS; + + size = bdrv_getlength(bs->file); + if (size < 0) { + res->check_errors++; + return size; + } + + res->bfi.total_clusters = s->bat_size; + res->bfi.compressed_clusters = 0; /* compression is not supported */ + + high_off = 0; + prev_off = 0; + for (i = 0; i < s->bat_size; i++) { + int64_t off = bat2sect(s, i) << BDRV_SECTOR_BITS; + if (off == 0) { + prev_off = 0; + continue; + } + + /* cluster outside the image */ + if (off > size) { + fprintf(stderr, "%s cluster %u is outside image\n", + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); + res->corruptions++; + if (fix & BDRV_FIX_ERRORS) { + prev_off = 0; + s->bat_bitmap[i] = 0; + res->corruptions_fixed++; + flush_bat = true; + continue; + } + } + + res->bfi.allocated_clusters++; + if (off > high_off) { + high_off = off; + } + + if (prev_off != 0 && (prev_off + cluster_size) != off) { + res->bfi.fragmented_clusters++; + } + prev_off = off; + } + + if (flush_bat) { + ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size); + if (ret < 0) { + res->check_errors++; + return ret; + } + } + + res->image_end_offset = high_off + cluster_size; + if (size > res->image_end_offset) { + int64_t count; + count = DIV_ROUND_UP(size - res->image_end_offset, 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) { + ret = bdrv_truncate(bs->file, res->image_end_offset); + if (ret < 0) { + res->check_errors++; + return ret; + } + res->leaks_fixed += count; + } + } + + return 0; +} + + static int parallels_create(const char *filename, QemuOpts *opts, Error **errp) { int64_t total_size, cl_size; @@ -449,6 +533,7 @@ static BlockDriver bdrv_parallels = { .bdrv_co_writev = parallels_co_writev, .bdrv_create = parallels_create, + .bdrv_check = parallels_check, .create_opts = ¶llels_create_opts, }; -- 2.1.0