Revision 9b036055

b/block/qcow2.c
795 795
    return qcow2_update_ext_header(bs, backing_file, backing_fmt);
796 796
}
797 797

  
798
#if 0
799
static int get_bits_from_size(size_t size)
800
{
801
    int res = 0;
802

  
803
    if (size == 0) {
804
        return -1;
805
    }
806

  
807
    while (size != 1) {
808
        /* Not a power of two */
809
        if (size & 1) {
810
            return -1;
811
        }
812

  
813
        size >>= 1;
814
        res++;
815
    }
816

  
817
    return res;
818
}
819
#endif
820

  
821

  
822 798
static int preallocate(BlockDriverState *bs)
823 799
{
824 800
    uint64_t nb_sectors;
......
872 848
    return 0;
873 849
}
874 850

  
875
#if 0
876
static int qcow_create2(const char *filename, int64_t total_size,
877
                        const char *backing_file, const char *backing_format,
878
                        int flags, size_t cluster_size, int prealloc)
879
{
880

  
881
    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
882
    int ref_clusters, reftable_clusters, backing_format_len = 0;
883
    int rounded_ext_bf_len = 0;
884
    QCowHeader header;
885
    uint64_t tmp, offset;
886
    uint64_t old_ref_clusters;
887
    QCowCreateState s1, *s = &s1;
888
    QCowExtension ext_bf = {0, 0};
889
    int ret;
890

  
891
    memset(s, 0, sizeof(*s));
892

  
893
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
894
    if (fd < 0)
895
        return -errno;
896
    memset(&header, 0, sizeof(header));
897
    header.magic = cpu_to_be32(QCOW_MAGIC);
898
    header.version = cpu_to_be32(QCOW_VERSION);
899
    header.size = cpu_to_be64(total_size * 512);
900
    header_size = sizeof(header);
901
    backing_filename_len = 0;
902
    if (backing_file) {
903
        if (backing_format) {
904
            ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;
905
            backing_format_len = strlen(backing_format);
906
            ext_bf.len = backing_format_len;
907
            rounded_ext_bf_len = (sizeof(ext_bf) + ext_bf.len + 7) & ~7;
908
            header_size += rounded_ext_bf_len;
909
        }
910
        header.backing_file_offset = cpu_to_be64(header_size);
911
        backing_filename_len = strlen(backing_file);
912
        header.backing_file_size = cpu_to_be32(backing_filename_len);
913
        header_size += backing_filename_len;
914
    }
915

  
916
    /* Cluster size */
917
    s->cluster_bits = get_bits_from_size(cluster_size);
918
    if (s->cluster_bits < MIN_CLUSTER_BITS ||
919
        s->cluster_bits > MAX_CLUSTER_BITS)
920
    {
921
        fprintf(stderr, "Cluster size must be a power of two between "
922
            "%d and %dk\n",
923
            1 << MIN_CLUSTER_BITS,
924
            1 << (MAX_CLUSTER_BITS - 10));
925
        return -EINVAL;
926
    }
927
    s->cluster_size = 1 << s->cluster_bits;
928

  
929
    header.cluster_bits = cpu_to_be32(s->cluster_bits);
930
    header_size = (header_size + 7) & ~7;
931
    if (flags & BLOCK_FLAG_ENCRYPT) {
932
        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
933
    } else {
934
        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
935
    }
936
    l2_bits = s->cluster_bits - 3;
937
    shift = s->cluster_bits + l2_bits;
938
    l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
939
    offset = align_offset(header_size, s->cluster_size);
940
    s->l1_table_offset = offset;
941
    header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
942
    header.l1_size = cpu_to_be32(l1_size);
943
    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
944

  
945
    /* count how many refcount blocks needed */
946

  
947
#define NUM_CLUSTERS(bytes) \
948
    (((bytes) + (s->cluster_size) - 1) / (s->cluster_size))
949

  
950
    ref_clusters = NUM_CLUSTERS(NUM_CLUSTERS(offset) * sizeof(uint16_t));
951

  
952
    do {
953
        uint64_t image_clusters;
954
        old_ref_clusters = ref_clusters;
955

  
956
        /* Number of clusters used for the refcount table */
957
        reftable_clusters = NUM_CLUSTERS(ref_clusters * sizeof(uint64_t));
958

  
959
        /* Number of clusters that the whole image will have */
960
        image_clusters = NUM_CLUSTERS(offset) + ref_clusters
961
            + reftable_clusters;
962

  
963
        /* Number of refcount blocks needed for the image */
964
        ref_clusters = NUM_CLUSTERS(image_clusters * sizeof(uint16_t));
965

  
966
    } while (ref_clusters != old_ref_clusters);
967

  
968
    s->refcount_table = qemu_mallocz(reftable_clusters * s->cluster_size);
969

  
970
    s->refcount_table_offset = offset;
971
    header.refcount_table_offset = cpu_to_be64(offset);
972
    header.refcount_table_clusters = cpu_to_be32(reftable_clusters);
973
    offset += (reftable_clusters * s->cluster_size);
974
    s->refcount_block_offset = offset;
975

  
976
    for (i=0; i < ref_clusters; i++) {
977
        s->refcount_table[i] = cpu_to_be64(offset);
978
        offset += s->cluster_size;
979
    }
980

  
981
    s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
982

  
983
    /* update refcounts */
984
    qcow2_create_refcount_update(s, 0, header_size);
985
    qcow2_create_refcount_update(s, s->l1_table_offset,
986
        l1_size * sizeof(uint64_t));
987
    qcow2_create_refcount_update(s, s->refcount_table_offset,
988
        reftable_clusters * s->cluster_size);
989
    qcow2_create_refcount_update(s, s->refcount_block_offset,
990
        ref_clusters * s->cluster_size);
991

  
992
    /* write all the data */
993
    ret = qemu_write_full(fd, &header, sizeof(header));
994
    if (ret != sizeof(header)) {
995
        ret = -errno;
996
        goto exit;
997
    }
998
    if (backing_file) {
999
        if (backing_format_len) {
1000
            char zero[16];
1001
            int padding = rounded_ext_bf_len - (ext_bf.len + sizeof(ext_bf));
1002

  
1003
            memset(zero, 0, sizeof(zero));
1004
            cpu_to_be32s(&ext_bf.magic);
1005
            cpu_to_be32s(&ext_bf.len);
1006
            ret = qemu_write_full(fd, &ext_bf, sizeof(ext_bf));
1007
            if (ret != sizeof(ext_bf)) {
1008
                ret = -errno;
1009
                goto exit;
1010
            }
1011
            ret = qemu_write_full(fd, backing_format, backing_format_len);
1012
            if (ret != backing_format_len) {
1013
                ret = -errno;
1014
                goto exit;
1015
            }
1016
            if (padding > 0) {
1017
                ret = qemu_write_full(fd, zero, padding);
1018
                if (ret != padding) {
1019
                    ret = -errno;
1020
                    goto exit;
1021
                }
1022
            }
1023
        }
1024
        ret = qemu_write_full(fd, backing_file, backing_filename_len);
1025
        if (ret != backing_filename_len) {
1026
            ret = -errno;
1027
            goto exit;
1028
        }
1029
    }
1030
    lseek(fd, s->l1_table_offset, SEEK_SET);
1031
    tmp = 0;
1032
    for(i = 0;i < l1_size; i++) {
1033
        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
1034
        if (ret != sizeof(tmp)) {
1035
            ret = -errno;
1036
            goto exit;
1037
        }
1038
    }
1039
    lseek(fd, s->refcount_table_offset, SEEK_SET);
1040
    ret = qemu_write_full(fd, s->refcount_table,
1041
        reftable_clusters * s->cluster_size);
1042
    if (ret != reftable_clusters * s->cluster_size) {
1043
        ret = -errno;
1044
        goto exit;
1045
    }
1046

  
1047
    lseek(fd, s->refcount_block_offset, SEEK_SET);
1048
    ret = qemu_write_full(fd, s->refcount_block,
1049
		    ref_clusters * s->cluster_size);
1050
    if (ret != ref_clusters * s->cluster_size) {
1051
        ret = -errno;
1052
        goto exit;
1053
    }
1054

  
1055
    ret = 0;
1056
exit:
1057
    qemu_free(s->refcount_table);
1058
    qemu_free(s->refcount_block);
1059
    close(fd);
1060

  
1061
    /* Preallocate metadata */
1062
    if (ret == 0 && prealloc) {
1063
        BlockDriverState *bs;
1064
        BlockDriver *drv = bdrv_find_format("qcow2");
1065
        bs = bdrv_new("");
1066
        bdrv_open(bs, filename, BDRV_O_CACHE_WB | BDRV_O_RDWR, drv);
1067
        ret = preallocate(bs);
1068
        bdrv_close(bs);
1069
    }
1070

  
1071
    return ret;
1072
}
1073
#else
1074 851
static int qcow_create2(const char *filename, int64_t total_size,
1075 852
                        const char *backing_file, const char *backing_format,
1076 853
                        int flags, size_t cluster_size, int prealloc,
......
1196 973
    bdrv_delete(bs);
1197 974
    return ret;
1198 975
}
1199
#endif
1200 976

  
1201 977
static int qcow_create(const char *filename, QEMUOptionParameter *options)
1202 978
{

Also available in: Unified diff