diff -urNX /home/volker/exclude-qemu /home/volker/qemu/block-bochs.c ./block-bochs.c --- /home/volker/qemu/block-bochs.c 2006-08-01 19:04:41.000000000 +0200 +++ ./block-bochs.c 2006-12-30 09:58:56.908199376 +0100 @@ -28,7 +28,8 @@ /**************************************************************/ #define HEADER_MAGIC "Bochs Virtual HD Image" -#define HEADER_VERSION 0x00010000 +#define HEADER_VERSION 0x00020000 +#define HEADER_V1 0x00010000 #define HEADER_SIZE 512 #define REDOLOG_TYPE "Redolog" @@ -37,7 +38,7 @@ // not allocated: 0xffffffff // always little-endian -struct bochs_header { +struct bochs_header_v1 { char magic[32]; // "Bochs Virtual HD Image" char type[16]; // "Redolog" char subtype[16]; // "Undoable" / "Volatile" / "Growing" @@ -56,6 +57,27 @@ } extra; }; +// always little-endian +struct bochs_header { + char magic[32]; // "Bochs Virtual HD Image" + char type[16]; // "Redolog" + char subtype[16]; // "Undoable" / "Volatile" / "Growing" + uint32_t version; + uint32_t header; // size of header + + union { + struct { + uint32_t catalog; // num of entries + uint32_t bitmap; // bitmap size + uint32_t extent; // extent size + uint32_t reserved; // for ??? + uint64_t disk; // disk size + char padding[HEADER_SIZE - 64 - 8 - 24]; + } redolog; + char padding[HEADER_SIZE - 64 - 8]; + } extra; +}; + typedef struct BDRVBochsState { int fd; @@ -79,7 +101,8 @@ if (!strcmp(bochs->magic, HEADER_MAGIC) && !strcmp(bochs->type, REDOLOG_TYPE) && !strcmp(bochs->subtype, GROWING_TYPE) && - (le32_to_cpu(bochs->version) == HEADER_VERSION)) + ((le32_to_cpu(bochs->version) == HEADER_VERSION) || + (le32_to_cpu(bochs->version) == HEADER_V1))) return 100; return 0; @@ -90,6 +113,7 @@ BDRVBochsState *s = bs->opaque; int fd, i; struct bochs_header bochs; + struct bochs_header_v1 header_v1; fd = open(filename, O_RDWR | O_BINARY); if (fd < 0) { @@ -109,11 +133,17 @@ if (strcmp(bochs.magic, HEADER_MAGIC) || strcmp(bochs.type, REDOLOG_TYPE) || strcmp(bochs.subtype, GROWING_TYPE) || - (le32_to_cpu(bochs.version) != HEADER_VERSION)) { + ((le32_to_cpu(bochs.version) != HEADER_VERSION) && + (le32_to_cpu(bochs.version) != HEADER_V1))) { goto fail; } - bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512; + if (le32_to_cpu(bochs.version) == HEADER_V1) { + memcpy(&header_v1, &bochs, sizeof(bochs)); + bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512; + } else { + bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512; + } lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);