|
|
0a122b |
From 30e78b5a6fc16e3669f83b27e02c8eb53e646b48 Mon Sep 17 00:00:00 2001
|
|
|
0a122b |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
Date: Tue, 25 Mar 2014 14:23:17 +0100
|
|
|
0a122b |
Subject: [PATCH 10/49] bochs: Unify header structs and make them QEMU_PACKED
|
|
|
0a122b |
|
|
|
0a122b |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
Message-id: <1395753835-7591-11-git-send-email-kwolf@redhat.com>
|
|
|
0a122b |
Patchwork-id: n/a
|
|
|
0a122b |
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 10/48] bochs: Unify header structs and make them QEMU_PACKED
|
|
|
0a122b |
Bugzilla: 1066691
|
|
|
0a122b |
RH-Acked-by: Jeff Cody <jcody@redhat.com>
|
|
|
0a122b |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
0a122b |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
0a122b |
|
|
|
0a122b |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1066691
|
|
|
0a122b |
Upstream status: Series embargoed
|
|
|
0a122b |
|
|
|
0a122b |
This is an on-disk structure, so offsets must be accurate.
|
|
|
0a122b |
|
|
|
0a122b |
Before this patch, sizeof(bochs) != sizeof(header_v1), which makes the
|
|
|
0a122b |
memcpy() between both invalid. We're lucky enough that the destination
|
|
|
0a122b |
buffer happened to be the larger one, and the memcpy size to be taken
|
|
|
0a122b |
from the smaller one, so we didn't get a buffer overflow in practice.
|
|
|
0a122b |
|
|
|
0a122b |
This patch unifies the both structures, eliminating the need to do a
|
|
|
0a122b |
memcpy in the first place. The common fields are extracted to the top
|
|
|
0a122b |
level of the struct and the actually differing part gets a union of the
|
|
|
0a122b |
two versions.
|
|
|
0a122b |
|
|
|
0a122b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
0a122b |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
0a122b |
---
|
|
|
0a122b |
block/bochs.c | 67 +++++++++++++++++++++-----------------------------------
|
|
|
0a122b |
1 files changed, 25 insertions(+), 42 deletions(-)
|
|
|
0a122b |
|
|
|
0a122b |
diff --git a/block/bochs.c b/block/bochs.c
|
|
|
0a122b |
index 51d9a90..708780d 100644
|
|
|
0a122b |
--- a/block/bochs.c
|
|
|
0a122b |
+++ b/block/bochs.c
|
|
|
0a122b |
@@ -39,45 +39,30 @@
|
|
|
0a122b |
// not allocated: 0xffffffff
|
|
|
0a122b |
|
|
|
0a122b |
// always little-endian
|
|
|
0a122b |
-struct bochs_header_v1 {
|
|
|
0a122b |
- char magic[32]; // "Bochs Virtual HD Image"
|
|
|
0a122b |
- char type[16]; // "Redolog"
|
|
|
0a122b |
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
|
|
|
0a122b |
- uint32_t version;
|
|
|
0a122b |
- uint32_t header; // size of header
|
|
|
0a122b |
-
|
|
|
0a122b |
- union {
|
|
|
0a122b |
- struct {
|
|
|
0a122b |
- uint32_t catalog; // num of entries
|
|
|
0a122b |
- uint32_t bitmap; // bitmap size
|
|
|
0a122b |
- uint32_t extent; // extent size
|
|
|
0a122b |
- uint64_t disk; // disk size
|
|
|
0a122b |
- char padding[HEADER_SIZE - 64 - 8 - 20];
|
|
|
0a122b |
- } redolog;
|
|
|
0a122b |
- char padding[HEADER_SIZE - 64 - 8];
|
|
|
0a122b |
- } extra;
|
|
|
0a122b |
-};
|
|
|
0a122b |
-
|
|
|
0a122b |
-// always little-endian
|
|
|
0a122b |
struct bochs_header {
|
|
|
0a122b |
- char magic[32]; // "Bochs Virtual HD Image"
|
|
|
0a122b |
- char type[16]; // "Redolog"
|
|
|
0a122b |
- char subtype[16]; // "Undoable" / "Volatile" / "Growing"
|
|
|
0a122b |
+ char magic[32]; /* "Bochs Virtual HD Image" */
|
|
|
0a122b |
+ char type[16]; /* "Redolog" */
|
|
|
0a122b |
+ char subtype[16]; /* "Undoable" / "Volatile" / "Growing" */
|
|
|
0a122b |
uint32_t version;
|
|
|
0a122b |
- uint32_t header; // size of header
|
|
|
0a122b |
+ uint32_t header; /* size of header */
|
|
|
0a122b |
+
|
|
|
0a122b |
+ uint32_t catalog; /* num of entries */
|
|
|
0a122b |
+ uint32_t bitmap; /* bitmap size */
|
|
|
0a122b |
+ uint32_t extent; /* extent size */
|
|
|
0a122b |
|
|
|
0a122b |
union {
|
|
|
0a122b |
- struct {
|
|
|
0a122b |
- uint32_t catalog; // num of entries
|
|
|
0a122b |
- uint32_t bitmap; // bitmap size
|
|
|
0a122b |
- uint32_t extent; // extent size
|
|
|
0a122b |
- uint32_t reserved; // for ???
|
|
|
0a122b |
- uint64_t disk; // disk size
|
|
|
0a122b |
- char padding[HEADER_SIZE - 64 - 8 - 24];
|
|
|
0a122b |
- } redolog;
|
|
|
0a122b |
- char padding[HEADER_SIZE - 64 - 8];
|
|
|
0a122b |
+ struct {
|
|
|
0a122b |
+ uint32_t reserved; /* for ??? */
|
|
|
0a122b |
+ uint64_t disk; /* disk size */
|
|
|
0a122b |
+ char padding[HEADER_SIZE - 64 - 20 - 12];
|
|
|
0a122b |
+ } QEMU_PACKED redolog;
|
|
|
0a122b |
+ struct {
|
|
|
0a122b |
+ uint64_t disk; /* disk size */
|
|
|
0a122b |
+ char padding[HEADER_SIZE - 64 - 20 - 8];
|
|
|
0a122b |
+ } QEMU_PACKED redolog_v1;
|
|
|
0a122b |
+ char padding[HEADER_SIZE - 64 - 20];
|
|
|
0a122b |
} extra;
|
|
|
0a122b |
-};
|
|
|
0a122b |
+} QEMU_PACKED;
|
|
|
0a122b |
|
|
|
0a122b |
typedef struct BDRVBochsState {
|
|
|
0a122b |
CoMutex lock;
|
|
|
0a122b |
@@ -114,7 +99,6 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
0a122b |
BDRVBochsState *s = bs->opaque;
|
|
|
0a122b |
int i;
|
|
|
0a122b |
struct bochs_header bochs;
|
|
|
0a122b |
- struct bochs_header_v1 header_v1;
|
|
|
0a122b |
int ret;
|
|
|
0a122b |
|
|
|
0a122b |
bs->read_only = 1; // no write support yet
|
|
|
0a122b |
@@ -133,13 +117,12 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
if (le32_to_cpu(bochs.version) == HEADER_V1) {
|
|
|
0a122b |
- memcpy(&header_v1, &bochs, sizeof(bochs));
|
|
|
0a122b |
- bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
|
|
|
0a122b |
+ bs->total_sectors = le64_to_cpu(bochs.extra.redolog_v1.disk) / 512;
|
|
|
0a122b |
} else {
|
|
|
0a122b |
- bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
|
|
|
0a122b |
+ bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
|
|
|
0a122b |
}
|
|
|
0a122b |
|
|
|
0a122b |
- s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
|
|
|
0a122b |
+ s->catalog_size = le32_to_cpu(bochs.catalog);
|
|
|
0a122b |
s->catalog_bitmap = g_malloc(s->catalog_size * 4);
|
|
|
0a122b |
|
|
|
0a122b |
ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
|
|
|
0a122b |
@@ -153,10 +136,10 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
0a122b |
|
|
|
0a122b |
s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
|
|
|
0a122b |
|
|
|
0a122b |
- s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;
|
|
|
0a122b |
- s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;
|
|
|
0a122b |
+ s->bitmap_blocks = 1 + (le32_to_cpu(bochs.bitmap) - 1) / 512;
|
|
|
0a122b |
+ s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
|
|
|
0a122b |
|
|
|
0a122b |
- s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
|
|
|
0a122b |
+ s->extent_size = le32_to_cpu(bochs.extent);
|
|
|
0a122b |
|
|
|
0a122b |
qemu_co_mutex_init(&s->lock);
|
|
|
0a122b |
return 0;
|
|
|
0a122b |
--
|
|
|
0a122b |
1.7.1
|
|
|
0a122b |
|