From patchwork Tue Mar 26 16:50:10 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 231475 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B07A42C0787 for ; Wed, 27 Mar 2013 03:56:07 +1100 (EST) Received: from localhost ([::1]:39395 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UKXAJ-0003NO-LN for incoming@patchwork.ozlabs.org; Tue, 26 Mar 2013 12:56:03 -0400 Received: from eggs.gnu.org ([208.118.235.92]:55617) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UKX5G-0003bm-69 for qemu-devel@nongnu.org; Tue, 26 Mar 2013 12:50:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UKX5C-0001PQ-Nx for qemu-devel@nongnu.org; Tue, 26 Mar 2013 12:50:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:21540) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UKX5C-0001PB-Es for qemu-devel@nongnu.org; Tue, 26 Mar 2013 12:50:46 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2QGoj90009626 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 26 Mar 2013 12:50:45 -0400 Received: from dhcp-200-207.str.redhat.com (ovpn-116-61.ams2.redhat.com [10.36.116.61]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r2QGoG34030068; Tue, 26 Mar 2013 12:50:44 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Tue, 26 Mar 2013 17:50:10 +0100 Message-Id: <1364316613-31223-19-git-send-email-kwolf@redhat.com> In-Reply-To: <1364316613-31223-1-git-send-email-kwolf@redhat.com> References: <1364316613-31223-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH v2 18/21] qcow2: Use byte granularity in qcow2_alloc_cluster_offset() 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 This gets rid of the nb_clusters and keep_clusters and the associated complicated calculations. Just advance the number of bytes that have been processed and everything is fine. This patch advances the variables even after the last operation even though they aren't used any more afterwards to make things look more uniform. A later patch will turn the whole thing into a loop and then it actually starts making sense. Signed-off-by: Kevin Wolf --- block/qcow2-cluster.c | 84 +++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 56 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 4f43d41..78e7db9 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1127,28 +1127,24 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m) { BDRVQcowState *s = bs->opaque; - int l2_index, ret, sectors; - unsigned int nb_clusters, keep_clusters; + uint64_t start, remaining; uint64_t cluster_offset; uint64_t cur_bytes; + int ret; trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, n_start, n_end); + assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset)); + offset = start_of_cluster(s, offset); + again: + start = offset + (n_start << BDRV_SECTOR_BITS); + remaining = (n_end - n_start) << BDRV_SECTOR_BITS; cluster_offset = 0; *host_offset = 0; /* - * Calculate the number of clusters to look for. We stop at L2 table - * boundaries to keep things simple. - */ - l2_index = offset_to_l2_index(s, offset); - nb_clusters = MIN(size_to_clusters(s, n_end << BDRV_SECTOR_BITS), - s->l2_size - l2_index); - n_end = MIN(n_end, nb_clusters * s->cluster_sectors); - - /* * Now start gathering as many contiguous clusters as possible: * * 1. Check for overlaps with in-flight allocations @@ -1165,8 +1161,8 @@ again: * cluster_offset to write to the same cluster and set up the right * synchronisation between the in-flight request and the new one. */ - cur_bytes = (n_end - n_start) * BDRV_SECTOR_SIZE; - ret = handle_dependencies(bs, offset, &cur_bytes); + cur_bytes = remaining; + ret = handle_dependencies(bs, start, &cur_bytes); if (ret == -EAGAIN) { goto again; } else if (ret < 0) { @@ -1177,33 +1173,28 @@ again: * correctly during the next loop iteration. */ } - nb_clusters = size_to_clusters(s, offset + cur_bytes) - - (offset >> s->cluster_bits); - /* * 2. Count contiguous COPIED clusters. */ - uint64_t tmp_bytes = cur_bytes; - ret = handle_copied(bs, offset, &cluster_offset, &tmp_bytes, m); + ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m); if (ret < 0) { return ret; } else if (ret) { - keep_clusters = - size_to_clusters(s, tmp_bytes + offset_into_cluster(s, offset)); - nb_clusters -= keep_clusters; - if (!*host_offset) { *host_offset = start_of_cluster(s, cluster_offset); } + + start += cur_bytes; + remaining -= cur_bytes; + cluster_offset += cur_bytes; + + cur_bytes = remaining; } else if (cur_bytes == 0) { - keep_clusters = 0; goto done; - } else { - keep_clusters = 0; } /* If there is something left to allocate, do that now */ - if (nb_clusters == 0) { + if (remaining == 0) { goto done; } @@ -1211,43 +1202,24 @@ again: * 3. If the request still hasn't completed, allocate new clusters, * considering any cluster_offset of steps 1c or 2. */ - int alloc_n_start; - int alloc_n_end; - - if (keep_clusters != 0) { - offset = start_of_cluster(s, offset - + keep_clusters * s->cluster_size); - cluster_offset = start_of_cluster(s, cluster_offset - + keep_clusters * s->cluster_size); - - alloc_n_start = 0; - alloc_n_end = n_end - keep_clusters * s->cluster_sectors; - } else { - alloc_n_start = n_start; - alloc_n_end = n_end; - } - - cur_bytes = MIN(cur_bytes, ((alloc_n_end - alloc_n_start) << BDRV_SECTOR_BITS)); - - ret = handle_alloc(bs, offset, &cluster_offset, &cur_bytes, m); + ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m); if (ret < 0) { return ret; - } + } else if (ret) { + if (!*host_offset) { + *host_offset = start_of_cluster(s, cluster_offset); + } - if (!*host_offset) { - *host_offset = start_of_cluster(s, cluster_offset); + start += cur_bytes; + remaining -= cur_bytes; + cluster_offset += cur_bytes; } - nb_clusters = size_to_clusters(s, cur_bytes + offset_into_cluster(s, offset)); /* Some cleanup work */ done: - sectors = (keep_clusters + nb_clusters) << (s->cluster_bits - 9); - if (sectors > n_end) { - sectors = n_end; - } - - assert(sectors > n_start); - *num = sectors - n_start; + *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS); + assert(*num > 0); + assert(*host_offset != 0); return 0; }