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