aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorAnthony Liguori <anthony@codemonkey.ws>2013-09-30 17:14:49 -0500
committerAnthony Liguori <anthony@codemonkey.ws>2013-09-30 17:14:49 -0500
commit4235d77349e93e7157555f20f1892088f55edff4 (patch)
treea992e65b5dec476a5658e1aa6bff273b02850f04 /block
parent3469a60d9f6f7ba6fca3fe0788391f7285ead631 (diff)
parent61653008adad45026464f962759112995802fe01 (diff)
Merge remote-tracking branch 'kwolf/for-anthony' into staging
# By Max Reitz (10) and others # Via Kevin Wolf * kwolf/for-anthony: (30 commits) qcow2: Remove useless count_contiguous_clusters() parameter qcow2: COMPRESSED on count_contiguous_clusters qcow2: count_contiguous_clusters and compression qcow2: Free only newly allocated clusters on error qcow2: Always use error path in l2_allocate qcow2: Don't put invalid L2 table into cache qemu-iotests: Preallocated zero clusters in 061 qcow2: Correct bitmap size in zero expansion qemu-iotests: Quote $TEST_IMG* and $TEST_DIR usage qemu-iotests: Add basic ability to use binary sample images qemu-iotests: fix qmp.py search path block: use DIV_ROUND_UP in bdrv_co_do_readv qcow2: Assert against currently impossible overflow block: qed - use QEMU_PACKED for on-disk structures block: qcow2 - used QEMU_PACKED for on-disk structures block: vpc - use QEMU_PACKED for on-disk structures block: vdi - use QEMU_PACKED for on-disk structures rbd: avoid qemu_rbd_snap_list() memory leaks qdict: Extract qdict_extract_subqdict block: Fix compiler warning (-Werror=uninitialized) ... Message-id: 1380296370-14523-1-git-send-email-kwolf@redhat.com
Diffstat (limited to 'block')
-rw-r--r--block/gluster.c4
-rw-r--r--block/iscsi.c1
-rw-r--r--block/qcow2-cluster.c87
-rw-r--r--block/qcow2-refcount.c1
-rw-r--r--block/qcow2.c2
-rw-r--r--block/qcow2.h2
-rw-r--r--block/qed.h2
-rw-r--r--block/raw-posix.c5
-rw-r--r--block/raw-win32.c2
-rw-r--r--block/rbd.c4
-rw-r--r--block/sheepdog.c3
-rw-r--r--block/stream.c5
-rw-r--r--block/vdi.c2
-rw-r--r--block/vmdk.c6
-rw-r--r--block/vpc.c28
15 files changed, 98 insertions, 56 deletions
diff --git a/block/gluster.c b/block/gluster.c
index 256de10ed3..877686a7fe 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -611,6 +611,7 @@ static BlockDriver bdrv_gluster = {
.format_name = "gluster",
.protocol_name = "gluster",
.instance_size = sizeof(BDRVGlusterState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open,
.bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create,
@@ -631,6 +632,7 @@ static BlockDriver bdrv_gluster_tcp = {
.format_name = "gluster",
.protocol_name = "gluster+tcp",
.instance_size = sizeof(BDRVGlusterState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open,
.bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create,
@@ -651,6 +653,7 @@ static BlockDriver bdrv_gluster_unix = {
.format_name = "gluster",
.protocol_name = "gluster+unix",
.instance_size = sizeof(BDRVGlusterState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open,
.bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create,
@@ -671,6 +674,7 @@ static BlockDriver bdrv_gluster_rdma = {
.format_name = "gluster",
.protocol_name = "gluster+rdma",
.instance_size = sizeof(BDRVGlusterState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = qemu_gluster_open,
.bdrv_close = qemu_gluster_close,
.bdrv_create = qemu_gluster_create,
diff --git a/block/iscsi.c b/block/iscsi.c
index 4460382811..6152ef1891 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1520,6 +1520,7 @@ static BlockDriver bdrv_iscsi = {
.protocol_name = "iscsi",
.instance_size = sizeof(IscsiLun),
+ .bdrv_needs_filename = true,
.bdrv_file_open = iscsi_open,
.bdrv_close = iscsi_close,
.bdrv_create = iscsi_create,
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 738ff73c1d..39323ace38 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -188,7 +188,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
{
BDRVQcowState *s = bs->opaque;
uint64_t old_l2_offset;
- uint64_t *l2_table;
+ uint64_t *l2_table = NULL;
int64_t l2_offset;
int ret;
@@ -200,7 +200,8 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
if (l2_offset < 0) {
- return l2_offset;
+ ret = l2_offset;
+ goto fail;
}
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
@@ -213,7 +214,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
trace_qcow2_l2_allocate_get_empty(bs, l1_index);
ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
if (ret < 0) {
- return ret;
+ goto fail;
}
l2_table = *table;
@@ -265,7 +266,9 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
fail:
trace_qcow2_l2_allocate_done(bs, l1_index, ret);
- qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
+ if (l2_table != NULL) {
+ qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
+ }
s->l1_table[l1_index] = old_l2_offset;
return ret;
}
@@ -278,23 +281,26 @@ fail:
* cluster which may require a different handling)
*/
static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
- uint64_t *l2_table, uint64_t start, uint64_t stop_flags)
+ uint64_t *l2_table, uint64_t stop_flags)
{
int i;
- uint64_t mask = stop_flags | L2E_OFFSET_MASK;
- uint64_t offset = be64_to_cpu(l2_table[0]) & mask;
+ uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW2_CLUSTER_COMPRESSED;
+ uint64_t first_entry = be64_to_cpu(l2_table[0]);
+ uint64_t offset = first_entry & mask;
if (!offset)
return 0;
- for (i = start; i < start + nb_clusters; i++) {
+ assert(qcow2_get_cluster_type(first_entry) != QCOW2_CLUSTER_COMPRESSED);
+
+ for (i = 0; i < nb_clusters; i++) {
uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask;
if (offset + (uint64_t) i * cluster_size != l2_entry) {
break;
}
}
- return (i - start);
+ return i;
}
static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table)
@@ -487,8 +493,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
return -EIO;
}
c = count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
- QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
+ &l2_table[l2_index], QCOW_OFLAG_ZERO);
*cluster_offset = 0;
break;
case QCOW2_CLUSTER_UNALLOCATED:
@@ -499,8 +504,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
case QCOW2_CLUSTER_NORMAL:
/* how many allocated clusters ? */
c = count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
- QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
+ &l2_table[l2_index], QCOW_OFLAG_ZERO);
*cluster_offset &= L2E_OFFSET_MASK;
break;
default:
@@ -716,6 +720,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
}
qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
+ assert(l2_index + m->nb_clusters <= s->l2_size);
for (i = 0; i < m->nb_clusters; i++) {
/* if two concurrent writes happen to the same unallocated cluster
* each write allocates separate cluster and writes data concurrently.
@@ -929,7 +934,7 @@ static int handle_copied(BlockDriverState *bs, uint64_t guest_offset,
/* We keep all QCOW_OFLAG_COPIED clusters */
keep_clusters =
count_contiguous_clusters(nb_clusters, s->cluster_size,
- &l2_table[l2_index], 0,
+ &l2_table[l2_index],
QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO);
assert(keep_clusters <= nb_clusters);
@@ -1509,8 +1514,8 @@ fail:
* i.e., the number of bits in expanded_clusters.
*/
static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
- int l1_size, uint8_t *expanded_clusters,
- uint64_t nb_clusters)
+ int l1_size, uint8_t **expanded_clusters,
+ uint64_t *nb_clusters)
{
BDRVQcowState *s = bs->opaque;
bool is_active_l1 = (l1_table == s->l1_table);
@@ -1550,11 +1555,12 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
uint64_t l2_entry = be64_to_cpu(l2_table[j]);
int64_t offset = l2_entry & L2E_OFFSET_MASK, cluster_index;
int cluster_type = qcow2_get_cluster_type(l2_entry);
+ bool preallocated = offset != 0;
if (cluster_type == QCOW2_CLUSTER_NORMAL) {
cluster_index = offset >> s->cluster_bits;
- assert((cluster_index >= 0) && (cluster_index < nb_clusters));
- if (expanded_clusters[cluster_index / 8] &
+ assert((cluster_index >= 0) && (cluster_index < *nb_clusters));
+ if ((*expanded_clusters)[cluster_index / 8] &
(1 << (cluster_index % 8))) {
/* Probably a shared L2 table; this cluster was a zero
* cluster which has been expanded, its refcount
@@ -1575,8 +1581,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
continue;
}
- if (!offset) {
- /* not preallocated */
+ if (!preallocated) {
if (!bs->backing_hd) {
/* not backed; therefore we can simply deallocate the
* cluster */
@@ -1595,16 +1600,20 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
offset, s->cluster_size);
if (ret < 0) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
+ if (!preallocated) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
goto fail;
}
ret = bdrv_write_zeroes(bs->file, offset / BDRV_SECTOR_SIZE,
s->cluster_sectors);
if (ret < 0) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
+ if (!preallocated) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
goto fail;
}
@@ -1612,8 +1621,25 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
l2_dirty = true;
cluster_index = offset >> s->cluster_bits;
- assert((cluster_index >= 0) && (cluster_index < nb_clusters));
- expanded_clusters[cluster_index / 8] |= 1 << (cluster_index % 8);
+
+ if (cluster_index >= *nb_clusters) {
+ uint64_t old_bitmap_size = (*nb_clusters + 7) / 8;
+ uint64_t new_bitmap_size;
+ /* The offset may lie beyond the old end of the underlying image
+ * file for growable files only */
+ assert(bs->file->growable);
+ *nb_clusters = size_to_clusters(s, bs->file->total_sectors *
+ BDRV_SECTOR_SIZE);
+ new_bitmap_size = (*nb_clusters + 7) / 8;
+ *expanded_clusters = g_realloc(*expanded_clusters,
+ new_bitmap_size);
+ /* clear the newly allocated space */
+ memset(&(*expanded_clusters)[old_bitmap_size], 0,
+ new_bitmap_size - old_bitmap_size);
+ }
+
+ assert((cluster_index >= 0) && (cluster_index < *nb_clusters));
+ (*expanded_clusters)[cluster_index / 8] |= 1 << (cluster_index % 8);
}
if (is_active_l1) {
@@ -1672,18 +1698,17 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs)
{
BDRVQcowState *s = bs->opaque;
uint64_t *l1_table = NULL;
- int cluster_to_sector_bits = s->cluster_bits - BDRV_SECTOR_BITS;
uint64_t nb_clusters;
uint8_t *expanded_clusters;
int ret;
int i, j;
- nb_clusters = (bs->total_sectors + (1 << cluster_to_sector_bits) - 1)
- >> cluster_to_sector_bits;
+ nb_clusters = size_to_clusters(s, bs->file->total_sectors *
+ BDRV_SECTOR_SIZE);
expanded_clusters = g_malloc0((nb_clusters + 7) / 8);
ret = expand_zero_clusters_in_l1(bs, s->l1_table, s->l1_size,
- expanded_clusters, nb_clusters);
+ &expanded_clusters, &nb_clusters);
if (ret < 0) {
goto fail;
}
@@ -1717,7 +1742,7 @@ int qcow2_expand_zero_clusters(BlockDriverState *bs)
}
ret = expand_zero_clusters_in_l1(bs, l1_table, s->snapshots[i].l1_size,
- expanded_clusters, nb_clusters);
+ &expanded_clusters, &nb_clusters);
if (ret < 0) {
goto fail;
}
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 4264148142..d2b7064a02 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -874,7 +874,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
nb_csectors = ((offset >> s->csize_shift) &
s->csize_mask) + 1;
if (addend != 0) {
- int ret;
ret = update_refcount(bs,
(offset & s->cluster_offset_mask) & ~511,
nb_csectors * 512, addend,
diff --git a/block/qcow2.c b/block/qcow2.c
index 318d95d972..4a9888cc7f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -52,7 +52,7 @@
typedef struct {
uint32_t magic;
uint32_t len;
-} QCowExtension;
+} QEMU_PACKED QCowExtension;
#define QCOW2_EXT_MAGIC_END 0
#define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
diff --git a/block/qcow2.h b/block/qcow2.h
index c90e5d6c6e..455e38de64 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -86,7 +86,7 @@ typedef struct QCowHeader {
uint32_t refcount_order;
uint32_t header_length;
-} QCowHeader;
+} QEMU_PACKED QCowHeader;
typedef struct QCowSnapshot {
uint64_t l1_table_offset;
diff --git a/block/qed.h b/block/qed.h
index 2b4ddedf31..5d65bea075 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -100,7 +100,7 @@ typedef struct {
/* if (features & QED_F_BACKING_FILE) */
uint32_t backing_filename_offset; /* in bytes from start of header */
uint32_t backing_filename_size; /* in bytes */
-} QEDHeader;
+} QEMU_PACKED QEDHeader;
typedef struct {
uint64_t offsets[0]; /* in bytes */
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 3ee5b62509..f7f102d2e2 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1200,6 +1200,7 @@ static BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe = NULL, /* no probe for protocols */
.bdrv_file_open = raw_open,
.bdrv_reopen_prepare = raw_reopen_prepare,
@@ -1542,6 +1543,7 @@ static BlockDriver bdrv_host_device = {
.format_name = "host_device",
.protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
@@ -1667,6 +1669,7 @@ static BlockDriver bdrv_host_floppy = {
.format_name = "host_floppy",
.protocol_name = "host_floppy",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe_device = floppy_probe_device,
.bdrv_file_open = floppy_open,
.bdrv_close = raw_close,
@@ -1769,6 +1772,7 @@ static BlockDriver bdrv_host_cdrom = {
.format_name = "host_cdrom",
.protocol_name = "host_cdrom",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe_device = cdrom_probe_device,
.bdrv_file_open = cdrom_open,
.bdrv_close = raw_close,
@@ -1890,6 +1894,7 @@ static BlockDriver bdrv_host_cdrom = {
.format_name = "host_cdrom",
.protocol_name = "host_cdrom",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe_device = cdrom_probe_device,
.bdrv_file_open = cdrom_open,
.bdrv_close = raw_close,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 1e7651be61..6ef320f16a 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -459,6 +459,7 @@ static BlockDriver bdrv_file = {
.format_name = "file",
.protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
@@ -601,6 +602,7 @@ static BlockDriver bdrv_host_device = {
.format_name = "host_device",
.protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
+ .bdrv_needs_filename = true,
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
diff --git a/block/rbd.c b/block/rbd.c
index 11086c35c4..4a1ea5b5ce 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -943,7 +943,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
do {
snaps = g_malloc(sizeof(*snaps) * max_snaps);
snap_count = rbd_snap_list(s->image, snaps, &max_snaps);
- if (snap_count < 0) {
+ if (snap_count <= 0) {
g_free(snaps);
}
} while (snap_count == -ERANGE);
@@ -967,6 +967,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
sn_info->vm_clock_nsec = 0;
}
rbd_snap_list_end(snaps);
+ g_free(snaps);
done:
*psn_tab = sn_tab;
@@ -1002,6 +1003,7 @@ static QEMUOptionParameter qemu_rbd_create_options[] = {
static BlockDriver bdrv_rbd = {
.format_name = "rbd",
.instance_size = sizeof(BDRVRBDState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = qemu_rbd_open,
.bdrv_close = qemu_rbd_close,
.bdrv_create = qemu_rbd_create,
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 38fb629650..5f81c93ee3 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2338,6 +2338,7 @@ static BlockDriver bdrv_sheepdog = {
.format_name = "sheepdog",
.protocol_name = "sheepdog",
.instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = sd_open,
.bdrv_close = sd_close,
.bdrv_create = sd_create,
@@ -2366,6 +2367,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
.format_name = "sheepdog",
.protocol_name = "sheepdog+tcp",
.instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = sd_open,
.bdrv_close = sd_close,
.bdrv_create = sd_create,
@@ -2394,6 +2396,7 @@ static BlockDriver bdrv_sheepdog_unix = {
.format_name = "sheepdog",
.protocol_name = "sheepdog+unix",
.instance_size = sizeof(BDRVSheepdogState),
+ .bdrv_needs_filename = true,
.bdrv_file_open = sd_open,
.bdrv_close = sd_close,
.bdrv_create = sd_create,
diff --git a/block/stream.c b/block/stream.c
index 078ce4aa6a..45837f4476 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -119,11 +119,12 @@ wait:
break;
}
+ copy = false;
+
ret = bdrv_is_allocated(bs, sector_num,
STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
if (ret == 1) {
/* Allocated in the top, no need to copy. */
- copy = false;
} else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [sector_num, sector_num+n). */
@@ -138,7 +139,7 @@ wait:
copy = (ret == 1);
}
trace_stream_one_iteration(s, sector_num, n, ret);
- if (ret >= 0 && copy) {
+ if (copy) {
if (s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
if (delay_ns > 0) {
diff --git a/block/vdi.c b/block/vdi.c
index dcbc27c9cb..b6ec0020dc 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -165,7 +165,7 @@ typedef struct {
uuid_t uuid_link;
uuid_t uuid_parent;
uint64_t unused2[7];
-} VdiHeader;
+} QEMU_PACKED VdiHeader;
typedef struct {
/* The block map entries are little endian (even in memory). */
diff --git a/block/vmdk.c b/block/vmdk.c
index 96ef1b534e..5d56e316f1 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -105,7 +105,7 @@ typedef struct VmdkExtent {
uint32_t l2_cache_offsets[L2_CACHE_SIZE];
uint32_t l2_cache_counts[L2_CACHE_SIZE];
- unsigned int cluster_sectors;
+ int64_t cluster_sectors;
} VmdkExtent;
typedef struct BDRVVmdkState {
@@ -424,7 +424,7 @@ static int vmdk_add_extent(BlockDriverState *bs,
extent->l1_size = l1_size;
extent->l1_entry_sectors = l2_size * cluster_sectors;
extent->l2_size = l2_size;
- extent->cluster_sectors = cluster_sectors;
+ extent->cluster_sectors = flat ? sectors : cluster_sectors;
if (s->num_extents > 1) {
extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
@@ -741,7 +741,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
VmdkExtent *extent;
ret = vmdk_add_extent(bs, extent_file, true, sectors,
- 0, 0, 0, 0, sectors, &extent);
+ 0, 0, 0, 0, 0, &extent);
if (ret < 0) {
return ret;
}
diff --git a/block/vpc.c b/block/vpc.c
index db61274332..b5dca3961e 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -46,7 +46,7 @@ enum vhd_type {
#define VHD_TIMESTAMP_BASE 946684800
// always big-endian
-struct vhd_footer {
+typedef struct vhd_footer {
char creator[8]; // "conectix"
uint32_t features;
uint32_t version;
@@ -79,9 +79,9 @@ struct vhd_footer {
uint8_t uuid[16];
uint8_t in_saved_state;
-};
+} QEMU_PACKED VHDFooter;
-struct vhd_dyndisk_header {
+typedef struct vhd_dyndisk_header {
char magic[8]; // "cxsparse"
// Offset of next header structure, 0xFFFFFFFF if none
@@ -111,7 +111,7 @@ struct vhd_dyndisk_header {
uint32_t reserved;
uint64_t data_offset;
} parent_locator[8];
-};
+} QEMU_PACKED VHDDynDiskHeader;
typedef struct BDRVVPCState {
CoMutex lock;
@@ -160,8 +160,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
{
BDRVVPCState *s = bs->opaque;
int i;
- struct vhd_footer* footer;
- struct vhd_dyndisk_header* dyndisk_header;
+ VHDFooter *footer;
+ VHDDynDiskHeader *dyndisk_header;
uint8_t buf[HEADER_SIZE];
uint32_t checksum;
int disk_type = VHD_DYNAMIC;
@@ -172,7 +172,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- footer = (struct vhd_footer*) s->footer_buf;
+ footer = (VHDFooter *) s->footer_buf;
if (strncmp(footer->creator, "conectix", 8)) {
int64_t offset = bdrv_getlength(bs->file);
if (offset < 0) {
@@ -224,7 +224,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
- dyndisk_header = (struct vhd_dyndisk_header *) buf;
+ dyndisk_header = (VHDDynDiskHeader *) buf;
if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
ret = -EINVAL;
@@ -446,7 +446,7 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
int ret;
int64_t offset;
int64_t sectors, sectors_per_block;
- struct vhd_footer *footer = (struct vhd_footer *) s->footer_buf;
+ VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) {
return bdrv_read(bs->file, sector_num, buf, nb_sectors);
@@ -495,7 +495,7 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
int64_t offset;
int64_t sectors, sectors_per_block;
int ret;
- struct vhd_footer *footer = (struct vhd_footer *) s->footer_buf;
+ VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) {
return bdrv_write(bs->file, sector_num, buf, nb_sectors);
@@ -597,8 +597,8 @@ static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)
{
- struct vhd_dyndisk_header* dyndisk_header =
- (struct vhd_dyndisk_header*) buf;
+ VHDDynDiskHeader *dyndisk_header =
+ (VHDDynDiskHeader *) buf;
size_t block_size, num_bat_entries;
int i;
int ret = -EIO;
@@ -688,7 +688,7 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
{
uint8_t buf[1024];
- struct vhd_footer *footer = (struct vhd_footer *) buf;
+ VHDFooter *footer = (VHDFooter *) buf;
QEMUOptionParameter *disk_type_param;
int fd, i;
uint16_t cyls = 0;
@@ -791,7 +791,7 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
static int vpc_has_zero_init(BlockDriverState *bs)
{
BDRVVPCState *s = bs->opaque;
- struct vhd_footer *footer = (struct vhd_footer *) s->footer_buf;
+ VHDFooter *footer = (VHDFooter *) s->footer_buf;
if (cpu_to_be32(footer->type) == VHD_FIXED) {
return bdrv_has_zero_init(bs->file);