* [Qemu-devel] [PATCH 1/3] block-qcow2: keep highest allocated offset (bytes)
@ 2009-01-08 18:52 Uri Lublin
0 siblings, 0 replies; only message in thread
From: Uri Lublin @ 2009-01-08 18:52 UTC (permalink / raw)
To: qemu-devel; +Cc: Uri Lublin
From: Uri Lublin <uril@redhat.com>
We want to know the highest written offset for qcow2 images.
This gives a maximal limit (and easy to calculate) on how
many bytes were allocated (and maybe freed internally) for a qcow2 image.
It can be useful for truncation of backing file images (ftruncate).
Also it may be useful for defragmentation later (although we'll need
the number of free blocks as well).
Signed-off-by: Uri Lublin <uril@redhat.com>
---
block-qcow2.c | 34 ++++++++++++++++++++++++++++++++++
1 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/block-qcow2.c b/block-qcow2.c
index 9aa7261..184c70c 100644
--- a/block-qcow2.c
+++ b/block-qcow2.c
@@ -143,6 +143,9 @@ typedef struct BDRVQcowState {
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,6 +173,8 @@ static void free_clusters(BlockDriverState *bs,
#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)
{
@@ -278,6 +283,8 @@ static int qcow_open(BlockDriverState *bs, const char
*filename, int flags)
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;
@@ -2198,6 +2205,29 @@ static int load_refcount_block(BlockDriverState *bs,
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;
@@ -2238,6 +2268,10 @@ retry:
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;
}
--
1.6.0.6
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2009-01-08 18:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-08 18:52 [Qemu-devel] [PATCH 1/3] block-qcow2: keep highest allocated offset (bytes) Uri Lublin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).