Revision a35e1c17 block/qcow2.c
b/block/qcow2.c | ||
---|---|---|
638 | 638 |
return res; |
639 | 639 |
} |
640 | 640 |
|
641 |
|
|
642 |
static int preallocate(BlockDriverState *bs) |
|
643 |
{ |
|
644 |
BDRVQcowState *s = bs->opaque; |
|
645 |
uint64_t cluster_offset; |
|
646 |
uint64_t nb_sectors; |
|
647 |
uint64_t offset; |
|
648 |
int num; |
|
649 |
QCowL2Meta meta; |
|
650 |
|
|
651 |
nb_sectors = bdrv_getlength(bs) >> 9; |
|
652 |
offset = 0; |
|
653 |
|
|
654 |
while (nb_sectors) { |
|
655 |
num = MIN(nb_sectors, INT_MAX >> 9); |
|
656 |
cluster_offset = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, |
|
657 |
&meta); |
|
658 |
|
|
659 |
if (cluster_offset == 0) { |
|
660 |
return -1; |
|
661 |
} |
|
662 |
|
|
663 |
if (qcow2_alloc_cluster_link_l2(bs, cluster_offset, &meta) < 0) { |
|
664 |
qcow2_free_any_clusters(bs, cluster_offset, meta.nb_clusters); |
|
665 |
return -1; |
|
666 |
} |
|
667 |
|
|
668 |
/* TODO Preallocate data if requested */ |
|
669 |
|
|
670 |
nb_sectors -= num; |
|
671 |
offset += num << 9; |
|
672 |
} |
|
673 |
|
|
674 |
/* |
|
675 |
* It is expected that the image file is large enough to actually contain |
|
676 |
* all of the allocated clusters (otherwise we get failing reads after |
|
677 |
* EOF). Extend the image to the last allocated sector. |
|
678 |
*/ |
|
679 |
if (cluster_offset != 0) { |
|
680 |
bdrv_truncate(s->hd, cluster_offset + (num << 9)); |
|
681 |
} |
|
682 |
|
|
683 |
return 0; |
|
684 |
} |
|
685 |
|
|
641 | 686 |
static int qcow_create2(const char *filename, int64_t total_size, |
642 | 687 |
const char *backing_file, const char *backing_format, |
643 |
int flags, size_t cluster_size) |
|
688 |
int flags, size_t cluster_size, int prealloc)
|
|
644 | 689 |
{ |
645 | 690 |
|
646 | 691 |
int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits; |
... | ... | |
762 | 807 |
qemu_free(s->refcount_table); |
763 | 808 |
qemu_free(s->refcount_block); |
764 | 809 |
close(fd); |
810 |
|
|
811 |
/* Preallocate metadata */ |
|
812 |
if (prealloc) { |
|
813 |
BlockDriverState *bs; |
|
814 |
bs = bdrv_new(""); |
|
815 |
bdrv_open(bs, filename, BDRV_O_CACHE_WB); |
|
816 |
preallocate(bs); |
|
817 |
bdrv_close(bs); |
|
818 |
} |
|
819 |
|
|
765 | 820 |
return 0; |
766 | 821 |
} |
767 | 822 |
|
... | ... | |
772 | 827 |
uint64_t sectors = 0; |
773 | 828 |
int flags = 0; |
774 | 829 |
size_t cluster_size = 65536; |
830 |
int prealloc = 0; |
|
775 | 831 |
|
776 | 832 |
/* Read out options */ |
777 | 833 |
while (options && options->name) { |
... | ... | |
787 | 843 |
if (options->value.n) { |
788 | 844 |
cluster_size = options->value.n; |
789 | 845 |
} |
846 |
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { |
|
847 |
if (!options->value.s || !strcmp(options->value.s, "off")) { |
|
848 |
prealloc = 0; |
|
849 |
} else if (!strcmp(options->value.s, "metadata")) { |
|
850 |
prealloc = 1; |
|
851 |
} else { |
|
852 |
fprintf(stderr, "Invalid preallocation mode: '%s'\n", |
|
853 |
options->value.s); |
|
854 |
return -EINVAL; |
|
855 |
} |
|
790 | 856 |
} |
791 | 857 |
options++; |
792 | 858 |
} |
793 | 859 |
|
860 |
if (backing_file && prealloc) { |
|
861 |
fprintf(stderr, "Backing file and preallocation cannot be used at " |
|
862 |
"the same time\n"); |
|
863 |
return -EINVAL; |
|
864 |
} |
|
865 |
|
|
794 | 866 |
return qcow_create2(filename, sectors, backing_file, backing_fmt, flags, |
795 |
cluster_size); |
|
867 |
cluster_size, prealloc);
|
|
796 | 868 |
} |
797 | 869 |
|
798 | 870 |
static int qcow_make_empty(BlockDriverState *bs) |
... | ... | |
982 | 1054 |
.type = OPT_SIZE, |
983 | 1055 |
.help = "qcow2 cluster size" |
984 | 1056 |
}, |
1057 |
{ |
|
1058 |
.name = BLOCK_OPT_PREALLOC, |
|
1059 |
.type = OPT_STRING, |
|
1060 |
.help = "Preallocation mode (allowed values: off, metadata)" |
|
1061 |
}, |
|
985 | 1062 |
{ NULL } |
986 | 1063 |
}; |
987 | 1064 |
|
Also available in: Unified diff