From patchwork Wed Mar 11 10:28:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 448896 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E1E93140172 for ; Wed, 11 Mar 2015 21:29:04 +1100 (AEDT) Received: from localhost ([::1]:53574 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVdst-0001yF-2X for incoming@patchwork.ozlabs.org; Wed, 11 Mar 2015 06:29:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34503) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVdrk-0008Py-GC for qemu-devel@nongnu.org; Wed, 11 Mar 2015 06:27:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YVdrf-0003xr-84 for qemu-devel@nongnu.org; Wed, 11 Mar 2015 06:27:52 -0400 Received: from mailhub.sw.ru ([195.214.232.25]:34589 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVdre-0003tx-K9 for qemu-devel@nongnu.org; Wed, 11 Mar 2015 06:27:46 -0400 Received: from hades.sw.ru ([10.30.8.132]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id t2BARgbe017637; Wed, 11 Mar 2015 13:27:43 +0300 (MSK) From: "Denis V. Lunev" To: Date: Wed, 11 Mar 2015 13:28:12 +0300 Message-Id: <1426069701-1405-19-git-send-email-den@openvz.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1426069701-1405-1-git-send-email-den@openvz.org> References: <1426069701-1405-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.0 [fuzzy] X-Received-From: 195.214.232.25 Cc: Kevin Wolf , "Denis V. Lunev" , qemu-devel@nongnu.org, Stefan Hajnoczi , Roman Kagan Subject: [Qemu-devel] [PATCH 18/27] block/parallels: implement parallels_check method of block driver X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 CC: Roman Kagan CC: Kevin Wolf CC: Stefan Hajnoczi Reviewed-by: Roman Kagan Reviewed-by: Stefan Hajnoczi --- block/parallels.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/block/parallels.c b/block/parallels.c index 3d71624..0e5d4c3 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -229,6 +229,90 @@ fail: 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; @@ -432,6 +516,7 @@ static BlockDriver bdrv_parallels = { .bdrv_co_writev = parallels_co_writev, .bdrv_create = parallels_create, + .bdrv_check = parallels_check, .create_opts = ¶llels_create_opts, };