From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LQ4k0-0006jK-RP for qemu-devel@nongnu.org; Thu, 22 Jan 2009 13:57:24 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LQ4jz-0006gc-RU for qemu-devel@nongnu.org; Thu, 22 Jan 2009 13:57:24 -0500 Received: from [199.232.76.173] (port=46433 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LQ4jz-0006gA-KA for qemu-devel@nongnu.org; Thu, 22 Jan 2009 13:57:23 -0500 Received: from savannah.gnu.org ([199.232.41.3]:54205 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LQ4jz-0002Rn-Ac for qemu-devel@nongnu.org; Thu, 22 Jan 2009 13:57:23 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1LQ4jy-0004g6-Rc for qemu-devel@nongnu.org; Thu, 22 Jan 2009 18:57:22 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1LQ4jy-0004g2-It for qemu-devel@nongnu.org; Thu, 22 Jan 2009 18:57:22 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Thu, 22 Jan 2009 18:57:22 +0000 Subject: [Qemu-devel] [6404] block-qcow2: keep highest allocated byte (Uri Lublin) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 6404 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6404 Author: aliguori Date: 2009-01-22 18:57:22 +0000 (Thu, 22 Jan 2009) Log Message: ----------- block-qcow2: keep highest allocated byte (Uri Lublin) We want to know the highest written offset for qcow2 images. This gives a pretty good (and easy to calculate) estimation to how much more allocation can be done for the block device. It can be usefull for allocating more diskspace for that image (if possible, e.g. lvm) before we run out-of-disk-space Signed-off-by: Uri Lublin Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/block-qcow2.c Modified: trunk/block-qcow2.c =================================================================== --- trunk/block-qcow2.c 2009-01-22 18:39:53 UTC (rev 6403) +++ trunk/block-qcow2.c 2009-01-22 18:57:22 UTC (rev 6404) @@ -143,6 +143,9 @@ uint32_t crypt_method_header; AES_KEY aes_encrypt_key; AES_KEY aes_decrypt_key; + + int64_t highest_alloc; /* highest cluester allocated (in clusters) */ + uint64_t snapshots_offset; int snapshots_size; int nb_snapshots; @@ -170,7 +173,9 @@ #ifdef DEBUG_ALLOC static void check_refcounts(BlockDriverState *bs); #endif +static void scan_refcount(BlockDriverState *bs, int64_t *high); + static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) { const QCowHeader *cow_header = (const void *)buf; @@ -278,6 +283,8 @@ if (refcount_init(bs) < 0) goto fail; + scan_refcount(bs, &s->highest_alloc); + /* read the backing file name */ if (header.backing_file_offset != 0) { len = header.backing_file_size; @@ -2206,6 +2213,29 @@ return 0; } +static void scan_refcount(BlockDriverState *bs, int64_t *high) +{ + BDRVQcowState *s = bs->opaque; + int64_t refcnt_index, cluster_index, cluster_end, h = 0; + + for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){ + if (s->refcount_table[refcnt_index] == 0) { + continue; + } + cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT); + cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT); + for ( ; cluster_index < cluster_end; cluster_index++) { + if (get_refcount(bs, cluster_index) == 0) + /* do nothing -- reserved for free counting */; + else + h = cluster_index; + } + } + + if (high) + *high = (h+1); +} + static int get_refcount(BlockDriverState *bs, int64_t cluster_index) { BDRVQcowState *s = bs->opaque; @@ -2246,6 +2276,10 @@ size, (s->free_cluster_index - nb_clusters) << s->cluster_bits); #endif + + if (s->highest_alloc < s->free_cluster_index) + s->highest_alloc = s->free_cluster_index; + return (s->free_cluster_index - nb_clusters) << s->cluster_bits; }