Revision 108534b9 block-qcow2.c

b/block-qcow2.c
480 480
    return -EIO;
481 481
}
482 482

  
483
/* 'allocate' is:
483
/*
484
 * seek_l2_table
485
 *
486
 * seek l2_offset in the l2_cache table
487
 * if not found, return NULL,
488
 * if found,
489
 *   increments the l2 cache hit count of the entry,
490
 *   if counter overflow, divide by two all counters
491
 *   return the pointer to the l2 cache entry
492
 *
493
 */
494

  
495
static uint64_t *seek_l2_table(BDRVQcowState *s, uint64_t l2_offset)
496
{
497
    int i, j;
498

  
499
    for(i = 0; i < L2_CACHE_SIZE; i++) {
500
        if (l2_offset == s->l2_cache_offsets[i]) {
501
            /* increment the hit count */
502
            if (++s->l2_cache_counts[i] == 0xffffffff) {
503
                for(j = 0; j < L2_CACHE_SIZE; j++) {
504
                    s->l2_cache_counts[j] >>= 1;
505
                }
506
            }
507
            return s->l2_cache + (i << s->l2_bits);
508
        }
509
    }
510
    return NULL;
511
}
512

  
513
/*
514
 * l2_load
484 515
 *
485
 * 0 not to allocate.
516
 * Loads a L2 table into memory. If the table is in the cache, the cache
517
 * is used; otherwise the L2 table is loaded from the image file.
486 518
 *
487
 * 1 to allocate a normal cluster (for sector indexes 'n_start' to
488
 * 'n_end')
519
 * Returns a pointer to the L2 table on success, or NULL if the read from
520
 * the image file failed.
521
 */
522

  
523
static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset)
524
{
525
    BDRVQcowState *s = bs->opaque;
526
    int min_index;
527
    uint64_t *l2_table;
528

  
529
    /* seek if the table for the given offset is in the cache */
530

  
531
    l2_table = seek_l2_table(s, l2_offset);
532
    if (l2_table != NULL)
533
        return l2_table;
534

  
535
    /* not found: load a new entry in the least used one */
536

  
537
    min_index = l2_cache_new_entry(bs);
538
    l2_table = s->l2_cache + (min_index << s->l2_bits);
539
    if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
540
        s->l2_size * sizeof(uint64_t))
541
        return NULL;
542
    s->l2_cache_offsets[min_index] = l2_offset;
543
    s->l2_cache_counts[min_index] = 1;
544

  
545
    return l2_table;
546
}
547

  
548
/*
549
 * l2_allocate
489 550
 *
490
 * 2 to allocate a compressed cluster of size
491
 * 'compressed_size'. 'compressed_size' must be > 0 and <
492
 * cluster_size
551
 * Allocate a new l2 entry in the file. If l1_index points to an already
552
 * used entry in the L2 table (i.e. we are doing a copy on write for the L2
553
 * table) copy the contents of the old L2 table into the newly allocated one.
554
 * Otherwise the new table is initialized with zeros.
493 555
 *
494
 * return 0 if not allocated.
495 556
 */
557

  
558
static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)
559
{
560
    BDRVQcowState *s = bs->opaque;
561
    int min_index;
562
    uint64_t old_l2_offset, tmp;
563
    uint64_t *l2_table, l2_offset;
564

  
565
    old_l2_offset = s->l1_table[l1_index];
566

  
567
    /* allocate a new l2 entry */
568

  
569
    l2_offset = alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
570

  
571
    /* update the L1 entry */
572

  
573
    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
574

  
575
    tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED);
576
    if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
577
                    &tmp, sizeof(tmp)) != sizeof(tmp))
578
        return NULL;
579

  
580
    /* allocate a new entry in the l2 cache */
581

  
582
    min_index = l2_cache_new_entry(bs);
583
    l2_table = s->l2_cache + (min_index << s->l2_bits);
584

  
585
    if (old_l2_offset == 0) {
586
        /* if there was no old l2 table, clear the new table */
587
        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
588
    } else {
589
        /* if there was an old l2 table, read it from the disk */
590
        if (bdrv_pread(s->hd, old_l2_offset,
591
                       l2_table, s->l2_size * sizeof(uint64_t)) !=
592
            s->l2_size * sizeof(uint64_t))
593
            return NULL;
594
    }
595
    /* write the l2 table to the file */
596
    if (bdrv_pwrite(s->hd, l2_offset,
597
                    l2_table, s->l2_size * sizeof(uint64_t)) !=
598
        s->l2_size * sizeof(uint64_t))
599
        return NULL;
600

  
601
    /* update the l2 cache entry */
602

  
603
    s->l2_cache_offsets[min_index] = l2_offset;
604
    s->l2_cache_counts[min_index] = 1;
605

  
606
    return l2_table;
607
}
608

  
496 609
static uint64_t get_cluster_offset(BlockDriverState *bs,
497 610
                                   uint64_t offset, int allocate,
498 611
                                   int compressed_size,
499 612
                                   int n_start, int n_end)
500 613
{
501 614
    BDRVQcowState *s = bs->opaque;
502
    int min_index, i, j, l1_index, l2_index, ret;
503
    uint64_t l2_offset, *l2_table, cluster_offset, tmp, old_l2_offset;
615
    int l1_index, l2_index, ret;
616
    uint64_t l2_offset, *l2_table, cluster_offset, tmp;
617

  
618
    /* seek the the l2 offset in the l1 table */
504 619

  
505 620
    l1_index = offset >> (s->l2_bits + s->cluster_bits);
506 621
    if (l1_index >= s->l1_size) {
507 622
        /* outside l1 table is allowed: we grow the table if needed */
508 623
        if (!allocate)
509 624
            return 0;
510
        if (grow_l1_table(bs, l1_index + 1) < 0)
625
        ret = grow_l1_table(bs, l1_index + 1);
626
        if (ret < 0)
511 627
            return 0;
512 628
    }
513 629
    l2_offset = s->l1_table[l1_index];
630

  
631
    /* seek the l2 table of the given l2 offset */
632

  
514 633
    if (!l2_offset) {
634
        /* the l2 table doesn't exist */
515 635
        if (!allocate)
516 636
            return 0;
517
    l2_allocate:
518
        old_l2_offset = l2_offset;
519
        /* allocate a new l2 entry */
520
        l2_offset = alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
521
        /* update the L1 entry */
522
        s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
523
        tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED);
524
        if (bdrv_pwrite(s->hd, s->l1_table_offset + l1_index * sizeof(tmp),
525
                        &tmp, sizeof(tmp)) != sizeof(tmp))
526
            return 0;
527
        min_index = l2_cache_new_entry(bs);
528
        l2_table = s->l2_cache + (min_index << s->l2_bits);
529

  
530
        if (old_l2_offset == 0) {
531
            memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
532
        } else {
533
            if (bdrv_pread(s->hd, old_l2_offset,
534
                           l2_table, s->l2_size * sizeof(uint64_t)) !=
535
                s->l2_size * sizeof(uint64_t))
536
                return 0;
537
        }
538
        if (bdrv_pwrite(s->hd, l2_offset,
539
                        l2_table, s->l2_size * sizeof(uint64_t)) !=
540
            s->l2_size * sizeof(uint64_t))
637
        /* allocate a new l2 table for this offset */
638
        l2_table = l2_allocate(bs, l1_index);
639
        if (l2_table == NULL)
541 640
            return 0;
641
        l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
542 642
    } else {
543
        if (!(l2_offset & QCOW_OFLAG_COPIED)) {
544
            if (allocate) {
545
                free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
546
                goto l2_allocate;
547
            }
643
        /* the l2 table exists */
644
        if (!(l2_offset & QCOW_OFLAG_COPIED) && allocate) {
645
            /* duplicate the l2 table, and free the old table */
646
            free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
647
            l2_table = l2_allocate(bs, l1_index);
648
            if (l2_table == NULL)
649
                return 0;
650
            l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;
548 651
        } else {
652
            /* load the l2 table in memory */
549 653
            l2_offset &= ~QCOW_OFLAG_COPIED;
654
            l2_table = l2_load(bs, l2_offset);
655
            if (l2_table == NULL)
656
                return 0;
550 657
        }
551
        for(i = 0; i < L2_CACHE_SIZE; i++) {
552
            if (l2_offset == s->l2_cache_offsets[i]) {
553
                /* increment the hit count */
554
                if (++s->l2_cache_counts[i] == 0xffffffff) {
555
                    for(j = 0; j < L2_CACHE_SIZE; j++) {
556
                        s->l2_cache_counts[j] >>= 1;
557
                    }
558
                }
559
                l2_table = s->l2_cache + (i << s->l2_bits);
560
                goto found;
561
            }
562
        }
563
        /* not found: load a new entry in the least used one */
564
        min_index = l2_cache_new_entry(bs);
565
        l2_table = s->l2_cache + (min_index << s->l2_bits);
566
        if (bdrv_pread(s->hd, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
567
            s->l2_size * sizeof(uint64_t))
568
            return 0;
569 658
    }
570
    s->l2_cache_offsets[min_index] = l2_offset;
571
    s->l2_cache_counts[min_index] = 1;
572
 found:
659

  
660
    /* find the cluster offset for the given disk offset */
661

  
573 662
    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
574 663
    cluster_offset = be64_to_cpu(l2_table[l2_index]);
575 664
    if (!cluster_offset) {
665
        /* cluster doesn't exist */
576 666
        if (!allocate)
577
            return cluster_offset;
667
            return 0;
578 668
    } else if (!(cluster_offset & QCOW_OFLAG_COPIED)) {
579 669
        if (!allocate)
580 670
            return cluster_offset;
......
592 682
        cluster_offset &= ~QCOW_OFLAG_COPIED;
593 683
        return cluster_offset;
594 684
    }
685

  
595 686
    if (allocate == 1) {
596 687
        /* allocate a new cluster */
597 688
        cluster_offset = alloc_clusters(bs, s->cluster_size);

Also available in: Unified diff