Commit 5d4cbd78aa33f6d034a62207c99ad0b64af44621

Authored by aliguori
1 parent f18be901

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 <uril@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6404 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 34 additions and 0 deletions
block-qcow2.c
@@ -143,6 +143,9 @@ typedef struct BDRVQcowState { @@ -143,6 +143,9 @@ typedef struct BDRVQcowState {
143 uint32_t crypt_method_header; 143 uint32_t crypt_method_header;
144 AES_KEY aes_encrypt_key; 144 AES_KEY aes_encrypt_key;
145 AES_KEY aes_decrypt_key; 145 AES_KEY aes_decrypt_key;
  146 +
  147 + int64_t highest_alloc; /* highest cluester allocated (in clusters) */
  148 +
146 uint64_t snapshots_offset; 149 uint64_t snapshots_offset;
147 int snapshots_size; 150 int snapshots_size;
148 int nb_snapshots; 151 int nb_snapshots;
@@ -170,6 +173,8 @@ static void free_clusters(BlockDriverState *bs, @@ -170,6 +173,8 @@ static void free_clusters(BlockDriverState *bs,
170 #ifdef DEBUG_ALLOC 173 #ifdef DEBUG_ALLOC
171 static void check_refcounts(BlockDriverState *bs); 174 static void check_refcounts(BlockDriverState *bs);
172 #endif 175 #endif
  176 +static void scan_refcount(BlockDriverState *bs, int64_t *high);
  177 +
173 178
174 static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) 179 static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
175 { 180 {
@@ -278,6 +283,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags) @@ -278,6 +283,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
278 if (refcount_init(bs) < 0) 283 if (refcount_init(bs) < 0)
279 goto fail; 284 goto fail;
280 285
  286 + scan_refcount(bs, &s->highest_alloc);
  287 +
281 /* read the backing file name */ 288 /* read the backing file name */
282 if (header.backing_file_offset != 0) { 289 if (header.backing_file_offset != 0) {
283 len = header.backing_file_size; 290 len = header.backing_file_size;
@@ -2206,6 +2213,29 @@ static int load_refcount_block(BlockDriverState *bs, @@ -2206,6 +2213,29 @@ static int load_refcount_block(BlockDriverState *bs,
2206 return 0; 2213 return 0;
2207 } 2214 }
2208 2215
  2216 +static void scan_refcount(BlockDriverState *bs, int64_t *high)
  2217 +{
  2218 + BDRVQcowState *s = bs->opaque;
  2219 + int64_t refcnt_index, cluster_index, cluster_end, h = 0;
  2220 +
  2221 + for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){
  2222 + if (s->refcount_table[refcnt_index] == 0) {
  2223 + continue;
  2224 + }
  2225 + cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT);
  2226 + cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT);
  2227 + for ( ; cluster_index < cluster_end; cluster_index++) {
  2228 + if (get_refcount(bs, cluster_index) == 0)
  2229 + /* do nothing -- reserved for free counting */;
  2230 + else
  2231 + h = cluster_index;
  2232 + }
  2233 + }
  2234 +
  2235 + if (high)
  2236 + *high = (h+1);
  2237 +}
  2238 +
2209 static int get_refcount(BlockDriverState *bs, int64_t cluster_index) 2239 static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
2210 { 2240 {
2211 BDRVQcowState *s = bs->opaque; 2241 BDRVQcowState *s = bs->opaque;
@@ -2246,6 +2276,10 @@ retry: @@ -2246,6 +2276,10 @@ retry:
2246 size, 2276 size,
2247 (s->free_cluster_index - nb_clusters) << s->cluster_bits); 2277 (s->free_cluster_index - nb_clusters) << s->cluster_bits);
2248 #endif 2278 #endif
  2279 +
  2280 + if (s->highest_alloc < s->free_cluster_index)
  2281 + s->highest_alloc = s->free_cluster_index;
  2282 +
2249 return (s->free_cluster_index - nb_clusters) << s->cluster_bits; 2283 return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
2250 } 2284 }
2251 2285