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
This commit is contained in:
Anthony Liguori
2013-09-30 17:14:49 -05:00
75 changed files with 574 additions and 424 deletions
+12 -27
View File
@@ -792,7 +792,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
/* Open the image, either directly or using a protocol */
if (drv->bdrv_file_open) {
assert(file == NULL);
assert(drv->bdrv_parse_filename || filename != NULL);
assert(!drv->bdrv_needs_filename || filename != NULL);
ret = drv->bdrv_file_open(bs, options, open_flags, &local_err);
} else {
if (file == NULL) {
@@ -911,7 +911,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename,
goto fail;
}
qdict_del(options, "filename");
} else if (!drv->bdrv_parse_filename && !filename) {
} else if (drv->bdrv_needs_filename && !filename) {
error_setg(errp, "The '%s' block driver requires a file name",
drv->format_name);
ret = -EINVAL;
@@ -978,11 +978,12 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
} else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) {
QDECREF(options);
return 0;
} else {
bdrv_get_full_backing_filename(bs, backing_filename,
sizeof(backing_filename));
}
bs->backing_hd = bdrv_new("");
bdrv_get_full_backing_filename(bs, backing_filename,
sizeof(backing_filename));
if (bs->backing_format[0] != '\0') {
back_drv = bdrv_find_format(bs->backing_format);
@@ -994,6 +995,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
ret = bdrv_open(bs->backing_hd,
*backing_filename ? backing_filename : NULL, options,
back_flags, back_drv, &local_err);
pstrcpy(bs->backing_file, sizeof(bs->backing_file),
bs->backing_hd->file->filename);
if (ret < 0) {
bdrv_unref(bs->backing_hd);
bs->backing_hd = NULL;
@@ -1004,25 +1007,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
return 0;
}
static void extract_subqdict(QDict *src, QDict **dst, const char *start)
{
const QDictEntry *entry, *next;
const char *p;
*dst = qdict_new();
entry = qdict_first(src);
while (entry != NULL) {
next = qdict_next(src, entry);
if (strstart(entry->key, start, &p)) {
qobject_incref(entry->value);
qdict_put_obj(*dst, p, entry->value);
qdict_del(src, entry->key);
}
entry = next;
}
}
/*
* Opens a disk image (raw, qcow2, vmdk, ...)
*
@@ -1128,7 +1112,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
flags |= BDRV_O_ALLOW_RDWR;
}
extract_subqdict(options, &file_options, "file.");
qdict_extract_subqdict(options, &file_options, "file.");
ret = bdrv_file_open(&file, filename, file_options,
bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);
@@ -1166,7 +1150,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
if ((flags & BDRV_O_NO_BACKING) == 0) {
QDict *backing_options;
extract_subqdict(options, &backing_options, "backing.");
qdict_extract_subqdict(options, &backing_options, "backing.");
ret = bdrv_open_backing_file(bs, backing_options, &local_err);
if (ret < 0) {
goto close_and_fail;
@@ -2669,7 +2653,7 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
goto out;
}
total_sectors = (len + BDRV_SECTOR_SIZE - 1) >> BDRV_SECTOR_BITS;
total_sectors = DIV_ROUND_UP(len, BDRV_SECTOR_SIZE);
max_nb_sectors = MAX(0, total_sectors - sector_num);
if (max_nb_sectors > 0) {
ret = drv->bdrv_co_readv(bs, sector_num,
@@ -3159,13 +3143,14 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum);
if (ret < 0) {
*pnum = 0;
return ret;
}
if (!(ret & BDRV_BLOCK_DATA)) {
if (bdrv_has_zero_init(bs)) {
ret |= BDRV_BLOCK_ZERO;
} else {
} else if (bs->backing_hd) {
BlockDriverState *bs2 = bs->backing_hd;
int64_t length2 = bdrv_getlength(bs2);
if (length2 >= 0 && sector_num >= (length2 >> BDRV_SECTOR_BITS)) {
+4
View File
@@ -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,
+1
View File
@@ -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,
+56 -31
View File
@@ -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;
}
-1
View File
@@ -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,
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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 */
+5
View File
@@ -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,
+2
View File
@@ -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,
+3 -1
View File
@@ -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,
+3
View File
@@ -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,
+3 -2
View File
@@ -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) {
+1 -1
View File
@@ -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). */
+3 -3
View File
@@ -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;
}
+14 -14
View File
@@ -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);
+6
View File
@@ -73,6 +73,12 @@ struct BlockDriver {
/* Any driver implementing this callback is expected to be able to handle
* NULL file names in its .bdrv_open() implementation */
void (*bdrv_parse_filename)(const char *filename, QDict *options, Error **errp);
/* Drivers not implementing bdrv_parse_filename nor bdrv_open should have
* this field set to true, except ones that are defined only by their
* child's bs.
* An example of the last type will be the quorum block driver.
*/
bool bdrv_needs_filename;
/* For handling image reopen for split or non-split files */
int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
+2
View File
@@ -67,4 +67,6 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key);
QDict *qdict_clone_shallow(const QDict *src);
void qdict_flatten(QDict *qdict);
void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
#endif /* QDICT_H */
+21
View File
@@ -527,3 +527,24 @@ void qdict_flatten(QDict *qdict)
{
qdict_do_flatten(qdict, qdict, NULL);
}
/* extract all the src QDict entries starting by start into dst */
void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
{
const QDictEntry *entry, *next;
const char *p;
*dst = qdict_new();
entry = qdict_first(src);
while (entry != NULL) {
next = qdict_next(src, entry);
if (strstart(entry->key, start, &p)) {
qobject_incref(entry->value);
qdict_put_obj(*dst, p, entry->value);
qdict_del(src, entry->key);
}
entry = next;
}
}
+3 -3
View File
@@ -48,15 +48,15 @@ _make_test_img $size
echo
echo "== reading whole image =="
$QEMU_IO -c "read 0 $size" $TEST_IMG | _filter_qemu_io
$QEMU_IO -c "read 0 $size" "$TEST_IMG" | _filter_qemu_io
echo
echo "== rewriting whole image =="
$QEMU_IO -c "write -P 0xa 0 $size" $TEST_IMG | _filter_qemu_io
$QEMU_IO -c "write -P 0xa 0 $size" "$TEST_IMG" | _filter_qemu_io
echo
echo "== verify pattern =="
$QEMU_IO -c "read -P 0xa 0 $size" $TEST_IMG | _filter_qemu_io
$QEMU_IO -c "read -P 0xa 0 $size" "$TEST_IMG" | _filter_qemu_io
# success, all done

Some files were not shown because too many files have changed in this diff Show More