[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH for-2.8] dmg: Move the driver to block-obj-y
From: |
Fam Zheng |
Subject: |
[Qemu-devel] [PATCH for-2.8] dmg: Move the driver to block-obj-y |
Date: |
Wed, 3 Aug 2016 16:01:18 +0800 |
dmg.o was moved to block-obj-m in 5505e8b76 to become a separate module,
so that its reference to libbz2, since 6b383c08c, doesn't add an extra
library to the main executable.
We are working on on-demand loading of block drivers which will be
easier if all format drivers are always built-in (so that the format
probing is not a egg-and-chicken problem).
dmg is the only modularized format driver for now. For above reason, we
want to move it back to block-obj-y, as is done in this patch.
The bz2 uncompressing code that requires bzip2 library is kept in a
separate function in the added dmg-bz2.o, which will be loaded at
program start in bdrv_init() as usual. It fills in the function pointer
inside dmg.o, so that bz2 uncompress can be done in reading path.
Signed-off-by: Fam Zheng <address@hidden>
---
block/Makefile.objs | 6 ++---
block/dmg-bz2.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
block/dmg.c | 68 +++++++++++++----------------------------------------
block/dmg.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 140 insertions(+), 55 deletions(-)
create mode 100644 block/dmg-bz2.c
create mode 100644 block/dmg.h
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 2593a2f..8a8a48e 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -1,4 +1,4 @@
-block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o
+block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o
dmg.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
qcow2-cache.o
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
@@ -39,7 +39,7 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS)
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
-block-obj-m += dmg.o
-dmg.o-libs := $(BZIP2_LIBS)
+block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
+dmg-bz2.o-libs := $(BZIP2_LIBS)
qcow.o-libs := -lz
linux-aio.o-libs := -laio
diff --git a/block/dmg-bz2.c b/block/dmg-bz2.c
new file mode 100644
index 0000000..a60e398
--- /dev/null
+++ b/block/dmg-bz2.c
@@ -0,0 +1,62 @@
+/*
+ * DMG bzip2 uncompression
+ *
+ * Copyright (c) 2004 Johannes E. Schindelin
+ * Copyright (c) 2016 Red Hat, Int.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "dmg.h"
+#include <bzlib.h>
+
+static int dmg_uncompress_bz2_do(char *next_in, unsigned int avail_in,
+ char *next_out, unsigned int avail_out)
+{
+ int ret;
+ uint64_t total_out;
+ bz_stream bzstream = {};
+
+ ret = BZ2_bzDecompressInit(&bzstream, 0, 0);
+ if (ret != BZ_OK) {
+ return -1;
+ }
+ bzstream.next_in = next_in;
+ bzstream.avail_in = avail_in;
+ bzstream.next_out = next_out;
+ bzstream.avail_out = avail_out;
+ ret = BZ2_bzDecompress(&bzstream);
+ total_out = ((uint64_t)bzstream.total_out_hi32 << 32) +
+ bzstream.total_out_lo32;
+ BZ2_bzDecompressEnd(&bzstream);
+ if (ret != BZ_STREAM_END ||
+ total_out != avail_out) {
+ return -1;
+ }
+ return 0;
+}
+
+__attribute__((constructor))
+static void dmg_bz2_init(void)
+{
+ assert(!dmg_uncompress_bz2);
+ dmg_uncompress_bz2 = dmg_uncompress_bz2_do;
+}
+
diff --git a/block/dmg.c b/block/dmg.c
index b0ed89b..861d3aa 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -28,10 +28,10 @@
#include "qemu/bswap.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
-#include <zlib.h>
-#ifdef CONFIG_BZIP2
-#include <bzlib.h>
-#endif
+#include "dmg.h"
+
+int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
+ char *next_out, unsigned int avail_out);
enum {
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
@@ -41,31 +41,6 @@ enum {
DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
};
-typedef struct BDRVDMGState {
- CoMutex lock;
- /* each chunk contains a certain number of sectors,
- * offsets[i] is the offset in the .dmg file,
- * lengths[i] is the length of the compressed chunk,
- * sectors[i] is the sector beginning at offsets[i],
- * sectorcounts[i] is the number of sectors in that chunk,
- * the sectors array is ordered
- * 0<=i<n_chunks */
-
- uint32_t n_chunks;
- uint32_t* types;
- uint64_t* offsets;
- uint64_t* lengths;
- uint64_t* sectors;
- uint64_t* sectorcounts;
- uint32_t current_chunk;
- uint8_t *compressed_chunk;
- uint8_t *uncompressed_chunk;
- z_stream zstream;
-#ifdef CONFIG_BZIP2
- bz_stream bzstream;
-#endif
-} BDRVDMGState;
-
static int dmg_probe(const uint8_t *buf, int buf_size, const char *filename)
{
int len;
@@ -210,10 +185,9 @@ static bool dmg_is_known_block_type(uint32_t entry_type)
case 0x00000001: /* uncompressed */
case 0x00000002: /* zeroes */
case 0x80000005: /* zlib */
-#ifdef CONFIG_BZIP2
- case 0x80000006: /* bzip2 */
-#endif
return true;
+ case 0x80000006: /* bzip2 */
+ return !!dmg_uncompress_bz2;
default:
return false;
}
@@ -587,9 +561,6 @@ static inline int dmg_read_chunk(BlockDriverState *bs,
uint64_t sector_num)
if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
int ret;
uint32_t chunk = search_chunk(s, sector_num);
-#ifdef CONFIG_BZIP2
- uint64_t total_out;
-#endif
if (chunk >= s->n_chunks) {
return -1;
@@ -620,8 +591,10 @@ static inline int dmg_read_chunk(BlockDriverState *bs,
uint64_t sector_num)
return -1;
}
break; }
-#ifdef CONFIG_BZIP2
case 0x80000006: /* bzip2 compressed */
+ if (!dmg_uncompress_bz2) {
+ break;
+ }
/* we need to buffer, because only the chunk as whole can be
* inflated. */
ret = bdrv_pread(bs->file, s->offsets[chunk],
@@ -630,24 +603,15 @@ static inline int dmg_read_chunk(BlockDriverState *bs,
uint64_t sector_num)
return -1;
}
- ret = BZ2_bzDecompressInit(&s->bzstream, 0, 0);
- if (ret != BZ_OK) {
- return -1;
- }
- s->bzstream.next_in = (char *)s->compressed_chunk;
- s->bzstream.avail_in = (unsigned int) s->lengths[chunk];
- s->bzstream.next_out = (char *)s->uncompressed_chunk;
- s->bzstream.avail_out = (unsigned int) 512 *
s->sectorcounts[chunk];
- ret = BZ2_bzDecompress(&s->bzstream);
- total_out = ((uint64_t)s->bzstream.total_out_hi32 << 32) +
- s->bzstream.total_out_lo32;
- BZ2_bzDecompressEnd(&s->bzstream);
- if (ret != BZ_STREAM_END ||
- total_out != 512 * s->sectorcounts[chunk]) {
- return -1;
+ ret = dmg_uncompress_bz2((char *)s->compressed_chunk,
+ (unsigned int) s->lengths[chunk],
+ (char *)s->uncompressed_chunk,
+ (unsigned int)
+ 512 * s->sectorcounts[chunk]);
+ if (ret < 0) {
+ return ret;
}
break;
-#endif /* CONFIG_BZIP2 */
case 1: /* copy */
ret = bdrv_pread(bs->file, s->offsets[chunk],
s->uncompressed_chunk, s->lengths[chunk]);
diff --git a/block/dmg.h b/block/dmg.h
new file mode 100644
index 0000000..b592d6f
--- /dev/null
+++ b/block/dmg.h
@@ -0,0 +1,59 @@
+/*
+ * Header for DMG driver
+ *
+ * Copyright (c) 2004-2006 Fabrice Bellard
+ * Copyright (c) 2016 Red hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef BLOCK_DMG_H
+#define BLOCK_DMG_H
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "block/block_int.h"
+#include <zlib.h>
+
+typedef struct BDRVDMGState {
+ CoMutex lock;
+ /* each chunk contains a certain number of sectors,
+ * offsets[i] is the offset in the .dmg file,
+ * lengths[i] is the length of the compressed chunk,
+ * sectors[i] is the sector beginning at offsets[i],
+ * sectorcounts[i] is the number of sectors in that chunk,
+ * the sectors array is ordered
+ * 0<=i<n_chunks */
+
+ uint32_t n_chunks;
+ uint32_t *types;
+ uint64_t *offsets;
+ uint64_t *lengths;
+ uint64_t *sectors;
+ uint64_t *sectorcounts;
+ uint32_t current_chunk;
+ uint8_t *compressed_chunk;
+ uint8_t *uncompressed_chunk;
+ z_stream zstream;
+} BDRVDMGState;
+
+extern int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
+ char *next_out, unsigned int avail_out);
+
+#endif
--
2.7.4
- [Qemu-devel] [PATCH for-2.8] dmg: Move the driver to block-obj-y,
Fam Zheng <=