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 |
|