~davewalker/ubuntu/maverick/qemu-kvm/623830

« back to all changes in this revision

Viewing changes to block/qcow2-refcount.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-08-10 08:51:54 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100810085154-ok0jzlkr75dplmc7
Tags: 0.12.5+noroms-0ubuntu1
* New upstream release
* Removed patch which is now upstream:
  0001-Fix-missing-symbols-in-.rel-.rela.plt-sections.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
        return 0;
43
43
    }
44
44
 
45
 
    if (bdrv_pwrite(s->hd, s->refcount_block_cache_offset,
46
 
            s->refcount_block_cache, size) != size)
 
45
    if (bdrv_pwrite_sync(s->hd, s->refcount_block_cache_offset,
 
46
            s->refcount_block_cache, size) < 0)
47
47
    {
48
48
        return -EIO;
49
49
    }
215
215
 
216
216
    /* Allocate the refcount block itself and mark it as used */
217
217
    uint64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
218
 
    memset(s->refcount_block_cache, 0, s->cluster_size);
219
 
    s->refcount_block_cache_offset = new_block;
220
218
 
221
219
#ifdef DEBUG_ALLOC2
222
220
    fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64
225
223
#endif
226
224
 
227
225
    if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {
 
226
        /* Zero the new refcount block before updating it */
 
227
        memset(s->refcount_block_cache, 0, s->cluster_size);
 
228
        s->refcount_block_cache_offset = new_block;
 
229
 
228
230
        /* The block describes itself, need to update the cache */
229
231
        int block_index = (new_block >> s->cluster_bits) &
230
232
            ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
236
238
        if (ret < 0) {
237
239
            goto fail_block;
238
240
        }
 
241
 
 
242
        /* Initialize the new refcount block only after updating its refcount,
 
243
         * update_refcount uses the refcount cache itself */
 
244
        memset(s->refcount_block_cache, 0, s->cluster_size);
 
245
        s->refcount_block_cache_offset = new_block;
239
246
    }
240
247
 
241
248
    /* Now the new refcount block needs to be written to disk */
242
 
    ret = bdrv_pwrite(s->hd, new_block, s->refcount_block_cache,
 
249
    ret = bdrv_pwrite_sync(s->hd, new_block, s->refcount_block_cache,
243
250
        s->cluster_size);
244
251
    if (ret < 0) {
245
252
        goto fail_block;
248
255
    /* If the refcount table is big enough, just hook the block up there */
249
256
    if (refcount_table_index < s->refcount_table_size) {
250
257
        uint64_t data64 = cpu_to_be64(new_block);
251
 
        ret = bdrv_pwrite(s->hd,
 
258
        ret = bdrv_pwrite_sync(s->hd,
252
259
            s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
253
260
            &data64, sizeof(data64));
254
261
        if (ret < 0) {
325
332
    }
326
333
 
327
334
    /* Write refcount blocks to disk */
328
 
    ret = bdrv_pwrite(s->hd, meta_offset, new_blocks,
 
335
    ret = bdrv_pwrite_sync(s->hd, meta_offset, new_blocks,
329
336
        blocks_clusters * s->cluster_size);
330
337
    qemu_free(new_blocks);
331
338
    if (ret < 0) {
337
344
        cpu_to_be64s(&new_table[i]);
338
345
    }
339
346
 
340
 
    ret = bdrv_pwrite(s->hd, table_offset, new_table,
 
347
    ret = bdrv_pwrite_sync(s->hd, table_offset, new_table,
341
348
        table_size * sizeof(uint64_t));
342
349
    if (ret < 0) {
343
350
        goto fail_table;
351
358
    uint8_t data[12];
352
359
    cpu_to_be64w((uint64_t*)data, table_offset);
353
360
    cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
354
 
    ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, refcount_table_offset),
 
361
    ret = bdrv_pwrite_sync(s->hd, offsetof(QCowHeader, refcount_table_offset),
355
362
        data, sizeof(data));
356
363
    if (ret < 0) {
357
364
        goto fail_table;
390
397
    int64_t refcount_block_offset, int first_index, int last_index)
391
398
{
392
399
    size_t size;
 
400
    int ret;
393
401
 
394
402
    if (cache_refcount_updates) {
395
403
        return 0;
396
404
    }
397
405
 
 
406
    if (first_index < 0) {
 
407
        return 0;
 
408
    }
 
409
 
398
410
    first_index &= ~(REFCOUNTS_PER_SECTOR - 1);
399
411
    last_index = (last_index + REFCOUNTS_PER_SECTOR)
400
412
        & ~(REFCOUNTS_PER_SECTOR - 1);
401
413
 
402
414
    size = (last_index - first_index) << REFCOUNT_SHIFT;
403
 
    if (bdrv_pwrite(s->hd,
 
415
    ret = bdrv_pwrite_sync(s->hd,
404
416
        refcount_block_offset + (first_index << REFCOUNT_SHIFT),
405
 
        &s->refcount_block_cache[first_index], size) != size)
406
 
    {
407
 
        return -EIO;
 
417
        &s->refcount_block_cache[first_index], size);
 
418
    if (ret < 0) {
 
419
        return ret;
408
420
    }
409
421
 
410
422
    return 0;
620
632
    ret = update_refcount(bs, offset, size, -1);
621
633
    if (ret < 0) {
622
634
        fprintf(stderr, "qcow2_free_clusters failed: %s\n", strerror(-ret));
623
 
        abort();
 
635
        /* TODO Remember the clusters to free them later and avoid leaking */
624
636
    }
625
637
}
626
638
 
760
772
                }
761
773
            }
762
774
            if (l2_modified) {
763
 
                if (bdrv_pwrite(s->hd,
764
 
                                l2_offset, l2_table, l2_size) != l2_size)
 
775
                if (bdrv_pwrite_sync(s->hd,
 
776
                                l2_offset, l2_table, l2_size) < 0)
765
777
                    goto fail;
766
778
            }
767
779
 
782
794
    if (l1_modified) {
783
795
        for(i = 0; i < l1_size; i++)
784
796
            cpu_to_be64s(&l1_table[i]);
785
 
        if (bdrv_pwrite(s->hd, l1_table_offset, l1_table,
786
 
                        l1_size2) != l1_size2)
 
797
        if (bdrv_pwrite_sync(s->hd, l1_table_offset, l1_table,
 
798
                        l1_size2) < 0)
787
799
            goto fail;
788
800
        for(i = 0; i < l1_size; i++)
789
801
            be64_to_cpus(&l1_table[i]);