Revision 1e3e8f1a
b/block/qcow2-cluster.c | ||
---|---|---|
481 | 481 |
* the l2 table offset in the qcow2 file and the cluster index |
482 | 482 |
* in the l2 table are given to the caller. |
483 | 483 |
* |
484 |
* Returns 0 on success, -errno in failure case |
|
484 | 485 |
*/ |
485 |
|
|
486 | 486 |
static int get_cluster_table(BlockDriverState *bs, uint64_t offset, |
487 | 487 |
uint64_t **new_l2_table, |
488 | 488 |
uint64_t *new_l2_offset, |
... | ... | |
498 | 498 |
l1_index = offset >> (s->l2_bits + s->cluster_bits); |
499 | 499 |
if (l1_index >= s->l1_size) { |
500 | 500 |
ret = qcow2_grow_l1_table(bs, l1_index + 1); |
501 |
if (ret < 0) |
|
502 |
return 0; |
|
501 |
if (ret < 0) { |
|
502 |
return ret; |
|
503 |
} |
|
503 | 504 |
} |
504 | 505 |
l2_offset = s->l1_table[l1_index]; |
505 | 506 |
|
... | ... | |
509 | 510 |
/* load the l2 table in memory */ |
510 | 511 |
l2_offset &= ~QCOW_OFLAG_COPIED; |
511 | 512 |
l2_table = l2_load(bs, l2_offset); |
512 |
if (l2_table == NULL) |
|
513 |
return 0; |
|
513 |
if (l2_table == NULL) { |
|
514 |
return -EIO; |
|
515 |
} |
|
514 | 516 |
} else { |
515 | 517 |
if (l2_offset) |
516 | 518 |
qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t)); |
517 | 519 |
l2_table = l2_allocate(bs, l1_index); |
518 |
if (l2_table == NULL) |
|
519 |
return 0; |
|
520 |
if (l2_table == NULL) { |
|
521 |
return -EIO; |
|
522 |
} |
|
520 | 523 |
l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED; |
521 | 524 |
} |
522 | 525 |
|
... | ... | |
528 | 531 |
*new_l2_offset = l2_offset; |
529 | 532 |
*new_l2_index = l2_index; |
530 | 533 |
|
531 |
return 1;
|
|
534 |
return 0;
|
|
532 | 535 |
} |
533 | 536 |
|
534 | 537 |
/* |
... | ... | |
554 | 557 |
int nb_csectors; |
555 | 558 |
|
556 | 559 |
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index); |
557 |
if (ret == 0)
|
|
560 |
if (ret < 0) {
|
|
558 | 561 |
return 0; |
562 |
} |
|
559 | 563 |
|
560 | 564 |
cluster_offset = be64_to_cpu(l2_table[l2_index]); |
561 | 565 |
if (cluster_offset & QCOW_OFLAG_COPIED) |
... | ... | |
635 | 639 |
goto err; |
636 | 640 |
} |
637 | 641 |
|
638 |
ret = -EIO; |
|
639 | 642 |
/* update L2 table */ |
640 |
if (!get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index)) |
|
643 |
ret = get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index); |
|
644 |
if (ret < 0) { |
|
641 | 645 |
goto err; |
646 |
} |
|
642 | 647 |
|
643 | 648 |
for (i = 0; i < m->nb_clusters; i++) { |
644 | 649 |
/* if two concurrent writes happen to the same unallocated cluster |
... | ... | |
694 | 699 |
QCowL2Meta *old_alloc; |
695 | 700 |
|
696 | 701 |
ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index); |
697 |
if (ret == 0)
|
|
702 |
if (ret < 0) {
|
|
698 | 703 |
return 0; |
704 |
} |
|
699 | 705 |
|
700 | 706 |
nb_clusters = size_to_clusters(s, n_end << 9); |
701 | 707 |
|
Also available in: Unified diff