Revision 73c632ed

b/block/qcow2.c
62 62

  
63 63
#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
64 64

  
65
#define MIN_CLUSTER_BITS 9
66
#define MAX_CLUSTER_BITS 16
67

  
65 68
typedef struct QCowHeader {
66 69
    uint32_t magic;
67 70
    uint32_t version;
......
300 303
    if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
301 304
        goto fail;
302 305
    if (header.size <= 1 ||
303
        header.cluster_bits < 9 ||
304
        header.cluster_bits > 16)
306
        header.cluster_bits < MIN_CLUSTER_BITS ||
307
        header.cluster_bits > MAX_CLUSTER_BITS)
305 308
        goto fail;
306 309
    if (header.crypt_method > QCOW_CRYPT_AES)
307 310
        goto fail;
......
1583 1586
    }
1584 1587
}
1585 1588

  
1589
static int get_bits_from_size(size_t size)
1590
{
1591
    int res = 0;
1592

  
1593
    if (size == 0) {
1594
        return -1;
1595
    }
1596

  
1597
    while (size != 1) {
1598
        /* Not a power of two */
1599
        if (size & 1) {
1600
            return -1;
1601
        }
1602

  
1603
        size >>= 1;
1604
        res++;
1605
    }
1606

  
1607
    return res;
1608
}
1609

  
1586 1610
static int qcow_create2(const char *filename, int64_t total_size,
1587 1611
                        const char *backing_file, const char *backing_format,
1588
                        int flags)
1612
                        int flags, size_t cluster_size)
1589 1613
{
1590 1614

  
1591 1615
    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
......
1619 1643
        header.backing_file_size = cpu_to_be32(backing_filename_len);
1620 1644
        header_size += backing_filename_len;
1621 1645
    }
1622
    s->cluster_bits = 12;  /* 4 KB clusters */
1646

  
1647
    /* Cluster size */
1648
    s->cluster_bits = get_bits_from_size(cluster_size);
1649
    if (s->cluster_bits < MIN_CLUSTER_BITS ||
1650
        s->cluster_bits > MAX_CLUSTER_BITS)
1651
    {
1652
        fprintf(stderr, "Cluster size must be a power of two between "
1653
            "%d and %dk\n",
1654
            1 << MIN_CLUSTER_BITS,
1655
            1 << (MAX_CLUSTER_BITS - 10));
1656
        return -EINVAL;
1657
    }
1623 1658
    s->cluster_size = 1 << s->cluster_bits;
1659

  
1624 1660
    header.cluster_bits = cpu_to_be32(s->cluster_bits);
1625 1661
    header_size = (header_size + 7) & ~7;
1626 1662
    if (flags & BLOCK_FLAG_ENCRYPT) {
......
1702 1738
    const char *backing_fmt = NULL;
1703 1739
    uint64_t sectors = 0;
1704 1740
    int flags = 0;
1741
    size_t cluster_size = 4096;
1705 1742

  
1706 1743
    /* Read out options */
1707 1744
    while (options && options->name) {
......
1713 1750
            backing_fmt = options->value.s;
1714 1751
        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
1715 1752
            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
1753
        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
1754
            if (options->value.n) {
1755
                cluster_size = options->value.n;
1756
            }
1716 1757
        }
1717 1758
        options++;
1718 1759
    }
1719 1760

  
1720
    return qcow_create2(filename, sectors, backing_file, backing_fmt, flags);
1761
    return qcow_create2(filename, sectors, backing_file, backing_fmt, flags,
1762
        cluster_size);
1721 1763
}
1722 1764

  
1723 1765
static int qcow_make_empty(BlockDriverState *bs)
......
2920 2962
    { BLOCK_OPT_BACKING_FILE,   OPT_STRING },
2921 2963
    { BLOCK_OPT_BACKING_FMT,    OPT_STRING },
2922 2964
    { BLOCK_OPT_ENCRYPT,        OPT_FLAG },
2965
    { BLOCK_OPT_CLUSTER_SIZE,   OPT_SIZE },
2923 2966
    { NULL }
2924 2967
};
2925 2968

  
b/block_int.h
36 36
#define BLOCK_OPT_COMPAT6       "compat6"
37 37
#define BLOCK_OPT_BACKING_FILE  "backing_file"
38 38
#define BLOCK_OPT_BACKING_FMT   "backing_fmt"
39
#define BLOCK_OPT_CLUSTER_SIZE  "cluster_size"
39 40

  
40 41
typedef struct AIOPool {
41 42
    void (*cancel)(BlockDriverAIOCB *acb);

Also available in: Unified diff