qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/4] Convert all block drivers to new bdrv_create


From: Kevin Wolf
Subject: [Qemu-devel] [PATCH 2/4] Convert all block drivers to new bdrv_create
Date: Mon, 18 May 2009 16:42:10 +0200

Now we can make use of the newly introduced option structures. Instead of
having bdrv_create carry more and more parameters (which are format specific in
most cases), just pass a option structure as defined by the driver itself.

bdrv_create2() contains an emulation of the old interface to simplify the
transition.

Signed-off-by: Kevin Wolf <address@hidden>
---
 block.c           |   44 +++++++++++++++++++++++++++++++++-----------
 block.h           |    6 +++---
 block/cow.c       |   26 +++++++++++++++++++++-----
 block/qcow.c      |   28 ++++++++++++++++++++++++++--
 block/qcow2.c     |   36 +++++++++++++++++++++++++++++++-----
 block/raw-posix.c |   37 +++++++++++++++++++++++++++----------
 block/raw-win32.c |   20 ++++++++++++++++----
 block/vmdk.c      |   28 ++++++++++++++++++++++++++--
 block/vpc.c       |   21 +++++++++++++++++----
 block/vvfat.c     |    4 ++--
 block_int.h       |   17 +++++++++++------
 qemu-img.c        |    2 +-
 12 files changed, 214 insertions(+), 55 deletions(-)

diff --git a/block.c b/block.c
index 980fbec..7f4cf9e 100644
--- a/block.c
+++ b/block.c
@@ -189,22 +189,44 @@ int bdrv_create2(BlockDriver *drv,
                 const char *backing_file, const char *backing_format,
                 int flags)
 {
-    if (drv->bdrv_create2)
-        return drv->bdrv_create2(filename, size_in_sectors, backing_file,
-                                 backing_format, flags);
-    if (drv->bdrv_create)
-        return drv->bdrv_create(filename, size_in_sectors, backing_file,
-                                flags);
-    return -ENOTSUP;
+    QEMUOptionParameter *options;
+
+    options = parse_option_parameters("", drv->create_options, NULL);
+
+    // Process flags
+    if (flags & ~(BLOCK_FLAG_ENCRYPT | BLOCK_FLAG_COMPAT6 | 
BLOCK_FLAG_COMPRESS)) {
+        return -ENOTSUP;
+    }
+
+    if (flags & BLOCK_FLAG_ENCRYPT) {
+        set_option_parameter_int(options, BLOCK_OPT_ENCRYPT, 1);
+    }
+    if (flags & BLOCK_FLAG_COMPAT6) {
+        set_option_parameter_int(options, BLOCK_OPT_COMPAT6, 1);
+    }
+
+    // Add size to options
+    set_option_parameter_int(options, BLOCK_OPT_SIZE, size_in_sectors * 512);
+
+    // Backing files
+    if ((backing_file != NULL && set_option_parameter(options,
+            BLOCK_OPT_BACKING_FILE, backing_file))
+        || (backing_format != NULL && set_option_parameter(options,
+            BLOCK_OPT_BACKING_FMT, backing_format)))
+    {
+        return -ENOTSUP;
+    }
+
+    return bdrv_create(drv, filename, options);
 }
 
-int bdrv_create(BlockDriver *drv,
-                const char *filename, int64_t size_in_sectors,
-                const char *backing_file, int flags)
+int bdrv_create(BlockDriver *drv, const char* filename,
+    QEMUOptionParameter *options)
 {
     if (!drv->bdrv_create)
         return -ENOTSUP;
-    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
+
+    return drv->bdrv_create(filename, options);
 }
 
 #ifdef _WIN32
diff --git a/block.h b/block.h
index 22df8ca..0acac63 100644
--- a/block.h
+++ b/block.h
@@ -3,6 +3,7 @@
 
 #include "qemu-aio.h"
 #include "qemu-common.h"
+#include "qemu-option.h"
 
 /* block.c */
 typedef struct BlockDriver BlockDriver;
@@ -45,9 +46,8 @@ void bdrv_info_stats(Monitor *mon);
 
 void bdrv_init(void);
 BlockDriver *bdrv_find_format(const char *format_name);
-int bdrv_create(BlockDriver *drv,
-                const char *filename, int64_t size_in_sectors,
-                const char *backing_file, int flags);
+int bdrv_create(BlockDriver *drv, const char* filename,
+    QEMUOptionParameter *options);
 int bdrv_create2(BlockDriver *drv,
                  const char *filename, int64_t size_in_sectors,
                  const char *backing_file, const char *backing_format,
diff --git a/block/cow.c b/block/cow.c
index 94b3549..41d292a 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -202,15 +202,23 @@ static void cow_close(BlockDriverState *bs)
     close(s->fd);
 }
 
-static int cow_create(const char *filename, int64_t image_sectors,
-                      const char *image_filename, int flags)
+static int cow_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd, cow_fd;
     struct cow_header_v2 cow_header;
     struct stat st;
-
-    if (flags)
-        return -ENOTSUP;
+    int64_t image_sectors = 0;
+    const char *image_filename = NULL;
+
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            image_sectors = options->value.n / 512;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+            image_filename = options->value.s;
+        }
+        options++;
+    }
 
     cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);
@@ -253,6 +261,12 @@ static void cow_flush(BlockDriverState *bs)
     fsync(s->fd);
 }
 
+static QEMUOptionParameter cow_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { BLOCK_OPT_BACKING_FILE,   OPT_STRING },
+    { NULL }
+};
+
 static BlockDriver bdrv_cow = {
     .format_name       = "cow",
     .instance_size     = sizeof(BDRVCowState),
@@ -264,6 +278,8 @@ static BlockDriver bdrv_cow = {
     .bdrv_create       = cow_create,
     .bdrv_flush                = cow_flush,
     .bdrv_is_allocated = cow_is_allocated,
+
+    .create_options = cow_create_options,
 };
 
 static void bdrv_cow_init(void)
diff --git a/block/qcow.c b/block/qcow.c
index 1cf7c3b..6ecf2e8 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -767,12 +767,26 @@ static void qcow_close(BlockDriverState *bs)
     bdrv_delete(s->hd);
 }
 
-static int qcow_create(const char *filename, int64_t total_size,
-                      const char *backing_file, int flags)
+static int qcow_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd, header_size, backing_filename_len, l1_size, i, shift;
     QCowHeader header;
     uint64_t tmp;
+    int64_t total_size = 0;
+    const char *backing_file = NULL;
+    int flags = 0;
+
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            total_size = options->value.n / 512;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+            backing_file = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
+            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
+        }
+        options++;
+    }
 
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
     if (fd < 0)
@@ -918,6 +932,14 @@ static int qcow_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
     return 0;
 }
 
+
+static QEMUOptionParameter qcow_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { BLOCK_OPT_BACKING_FILE,   OPT_STRING },
+    { BLOCK_OPT_ENCRYPT,        OPT_FLAG },
+    { NULL }
+};
+
 static BlockDriver bdrv_qcow = {
     .format_name       = "qcow",
     .instance_size     = sizeof(BDRVQcowState),
@@ -935,6 +957,8 @@ static BlockDriver bdrv_qcow = {
     .aiocb_size                = sizeof(QCowAIOCB),
     .bdrv_write_compressed = qcow_write_compressed,
     .bdrv_get_info     = qcow_get_info,
+
+    .create_options = qcow_create_options,
 };
 
 static void bdrv_qcow_init(void)
diff --git a/block/qcow2.c b/block/qcow2.c
index a6de9b6..b6171d2 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1696,10 +1696,28 @@ static int qcow_create2(const char *filename, int64_t 
total_size,
     return 0;
 }
 
-static int qcow_create(const char *filename, int64_t total_size,
-                       const char *backing_file, int flags)
-{
-    return qcow_create2(filename, total_size, backing_file, NULL, flags);
+static int qcow_create(const char *filename, QEMUOptionParameter *options)
+{
+    const char *backing_file = NULL;
+    const char *backing_fmt = NULL;
+    uint64_t sectors = 0;
+    int flags = 0;
+
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            sectors = options->value.n / 512;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+            backing_file = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
+            backing_fmt = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
+            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
+        }
+        options++;
+    }
+
+    return qcow_create2(filename, sectors, backing_file, backing_fmt, flags);
 }
 
 static int qcow_make_empty(BlockDriverState *bs)
@@ -2892,6 +2910,14 @@ static int qcow_get_buffer(BlockDriverState *bs, uint8_t 
*buf,
     return ret;
 }
 
+static QEMUOptionParameter qcow_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { BLOCK_OPT_BACKING_FILE,   OPT_STRING },
+    { BLOCK_OPT_BACKING_FMT,    OPT_STRING },
+    { BLOCK_OPT_ENCRYPT,        OPT_FLAG },
+    { NULL }
+};
+
 static BlockDriver bdrv_qcow2 = {
     .format_name       = "qcow2",
     .instance_size     = sizeof(BDRVQcowState),
@@ -2919,7 +2945,7 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_put_buffer    = qcow_put_buffer,
     .bdrv_get_buffer    = qcow_get_buffer,
 
-    .bdrv_create2 = qcow_create2,
+    .create_options = qcow_create_options,
     .bdrv_check = qcow_check,
 };
 
diff --git a/block/raw-posix.c b/block/raw-posix.c
index f3a9476..86e3067 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -823,13 +823,18 @@ again:
 }
 #endif
 
-static int raw_create(const char *filename, int64_t total_size,
-                      const char *backing_file, int flags)
+static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
+    int64_t total_size = 0;
 
-    if (flags || backing_file)
-        return -ENOTSUP;
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            total_size = options->value.n / 512;
+        }
+        options++;
+    }
 
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);
@@ -846,6 +851,12 @@ static void raw_flush(BlockDriverState *bs)
     fsync(s->fd);
 }
 
+
+static QEMUOptionParameter raw_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { NULL }
+};
+
 static BlockDriver bdrv_raw = {
     .format_name = "raw",
     .instance_size = sizeof(BDRVRawState),
@@ -866,6 +877,8 @@ static BlockDriver bdrv_raw = {
 
     .bdrv_truncate = raw_truncate,
     .bdrv_getlength = raw_getlength,
+
+    .create_options = raw_create_options,
 };
 
 /***********************************************/
@@ -1364,15 +1377,20 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState 
*bs,
 #endif /* !linux && !FreeBSD */
 
 #if defined(__linux__) || defined(__FreeBSD__)
-static int hdev_create(const char *filename, int64_t total_size,
-                       const char *backing_file, int flags)
+static int hdev_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
     int ret = 0;
     struct stat stat_buf;
+    int64_t total_size = 0;
 
-    if (flags || backing_file)
-        return -ENOTSUP;
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, "size")) {
+            total_size = options->value.n / 512;
+        }
+        options++;
+    }
 
     fd = open(filename, O_WRONLY | O_BINARY);
     if (fd < 0)
@@ -1391,8 +1409,7 @@ static int hdev_create(const char *filename, int64_t 
total_size,
 
 #else  /* !(linux || freebsd) */
 
-static int hdev_create(const char *filename, int64_t total_size,
-                       const char *backing_file, int flags)
+static int hdev_create(const char *filename, QEMUOptionParameter *options)
 {
     return -ENOTSUP;
 }
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 15f3ec4..6e5c09b 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -210,13 +210,18 @@ static int64_t raw_getlength(BlockDriverState *bs)
     return l.QuadPart;
 }
 
-static int raw_create(const char *filename, int64_t total_size,
-                      const char *backing_file, int flags)
+static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
+    int64_t total_size = 0;
 
-    if (flags || backing_file)
-        return -ENOTSUP;
+    /* Read out options */
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            total_size = options->value.n / 512;
+        }
+        options++;
+    }
 
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);
@@ -228,6 +233,11 @@ static int raw_create(const char *filename, int64_t 
total_size,
     return 0;
 }
 
+static QEMUOptionParameter raw_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { NULL }
+};
+
 static BlockDriver bdrv_raw = {
     .format_name       = "raw",
     .instance_size     = sizeof(BDRVRawState),
@@ -239,6 +249,8 @@ static BlockDriver bdrv_raw = {
     .bdrv_write                = raw_write,
     .bdrv_truncate     = raw_truncate,
     .bdrv_getlength    = raw_getlength,
+
+    .create_options = raw_create_options,
 };
 
 /***********************************************/
diff --git a/block/vmdk.c b/block/vmdk.c
index 13866e9..b3ea686 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -687,8 +687,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t 
sector_num,
     return 0;
 }
 
-static int vmdk_create(const char *filename, int64_t total_size,
-                       const char *backing_file, int flags)
+static int vmdk_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd, i;
     VMDK4Header header;
@@ -713,6 +712,21 @@ static int vmdk_create(const char *filename, int64_t 
total_size,
         "ddb.adapterType = \"ide\"\n";
     char desc[1024];
     const char *real_filename, *temp_str;
+    int64_t total_size = 0;
+    const char *backing_file = NULL;
+    int flags = 0;
+
+    // Read out options
+    while (options && options->name) {
+        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+            total_size = options->value.n / 512;
+        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
+            backing_file = options->value.s;
+        } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
+            flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0;
+        }
+        options++;
+    }
 
     /* XXX: add support for backing file */
     if (backing_file) {
@@ -812,6 +826,14 @@ static void vmdk_flush(BlockDriverState *bs)
     bdrv_flush(s->hd);
 }
 
+
+static QEMUOptionParameter vmdk_create_options[] = {
+    { BLOCK_OPT_SIZE,           OPT_SIZE },
+    { BLOCK_OPT_BACKING_FILE,   OPT_STRING },
+    { BLOCK_OPT_COMPAT6,        OPT_FLAG },
+    { NULL }
+};
+
 static BlockDriver bdrv_vmdk = {
     .format_name       = "vmdk",
     .instance_size     = sizeof(BDRVVmdkState),
@@ -823,6 +845,8 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_create       = vmdk_create,
     .bdrv_flush                = vmdk_flush,
     .bdrv_is_allocated = vmdk_is_allocated,
+
+    .create_options = vmdk_create_options,
 };
 
 static void bdrv_vmdk_init(void)
diff --git a/block/vpc.c b/block/vpc.c
index 211ae5c..662a6f6 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -477,8 +477,7 @@ static int calculate_geometry(int64_t total_sectors, 
uint16_t* cyls,
     return 0;
 }
 
-static int vpc_create(const char *filename, int64_t total_sectors,
-    const char *backing_file, int flags)
+static int vpc_create(const char *filename, QEMUOptionParameter *options)
 {
     uint8_t buf[1024];
     struct vhd_footer* footer = (struct vhd_footer*) buf;
@@ -489,10 +488,17 @@ static int vpc_create(const char *filename, int64_t 
total_sectors,
     uint8_t heads;
     uint8_t secs_per_cyl;
     size_t block_size, num_bat_entries;
+    int64_t total_sectors = 0;
 
-    if (backing_file != NULL)
-        return -ENOTSUP;
+    // Read out options
+    while (options && options->name) {
+        if (!strcmp(options->name, "size")) {
+            total_sectors = options->value.n / 512;
+        }
+        options++;
+    }
 
+    // Create the file
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
     if (fd < 0)
         return -EIO;
@@ -587,6 +593,11 @@ static void vpc_close(BlockDriverState *bs)
     bdrv_delete(s->hd);
 }
 
+static QEMUOptionParameter vpc_create_options[] = {
+    { "size", OPT_SIZE },
+    { NULL }
+};
+
 static BlockDriver bdrv_vpc = {
     .format_name       = "vpc",
     .instance_size     = sizeof(BDRVVPCState),
@@ -596,6 +607,8 @@ static BlockDriver bdrv_vpc = {
     .bdrv_write                = vpc_write,
     .bdrv_close                = vpc_close,
     .bdrv_create       = vpc_create,
+
+    .create_options = vpc_create_options,
 };
 
 static void bdrv_vpc_init(void)
diff --git a/block/vvfat.c b/block/vvfat.c
index 2a8feb3..13960e9 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2777,8 +2777,8 @@ static int enable_write_target(BDRVVVFATState *s)
 
     s->qcow_filename = qemu_malloc(1024);
     get_tmp_filename(s->qcow_filename, 1024);
-    if (bdrv_create(bdrv_find_format("qcow"),
-               s->qcow_filename, s->sector_count, "fat:", 0) < 0)
+    if (bdrv_create2(bdrv_find_format("qcow"),
+               s->qcow_filename, s->sector_count, "fat:", NULL, 0) < 0)
        return -1;
     s->qcow = bdrv_new("");
     if (s->qcow == NULL || bdrv_open(s->qcow, s->qcow_filename, 0) < 0)
diff --git a/block_int.h b/block_int.h
index 9d11940..782de6c 100644
--- a/block_int.h
+++ b/block_int.h
@@ -25,11 +25,18 @@
 #define BLOCK_INT_H
 
 #include "block.h"
+#include "qemu-option.h"
 
 #define BLOCK_FLAG_ENCRYPT     1
 #define BLOCK_FLAG_COMPRESS    2
 #define BLOCK_FLAG_COMPAT6     4
 
+#define BLOCK_OPT_SIZE          "size"
+#define BLOCK_OPT_ENCRYPT       "encryption"
+#define BLOCK_OPT_COMPAT6       "compat6"
+#define BLOCK_OPT_BACKING_FILE  "backing_file"
+#define BLOCK_OPT_BACKING_FMT   "backing_fmt"
+
 typedef struct AIOPool {
     void (*cancel)(BlockDriverAIOCB *acb);
     int aiocb_size;
@@ -46,8 +53,7 @@ struct BlockDriver {
     int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num,
                       const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
-    int (*bdrv_create)(const char *filename, int64_t total_sectors,
-                       const char *backing_file, int flags);
+    int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
     void (*bdrv_flush)(BlockDriverState *bs);
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum);
@@ -97,10 +103,9 @@ struct BlockDriver {
 
     AIOPool aio_pool;
 
-    /* new create with backing file format */
-    int (*bdrv_create2)(const char *filename, int64_t total_sectors,
-                        const char *backing_file, const char *backing_format,
-                        int flags);
+    /* List of options for creating images, terminated by name == NULL */
+    QEMUOptionParameter *create_options;
+
 
     /* Returns number of errors in image, -errno for internal errors */
     int (*bdrv_check)(BlockDriverState* bs);
diff --git a/qemu-img.c b/qemu-img.c
index a3d15e7..190153f 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -551,7 +551,7 @@ static int img_convert(int argc, char **argv)
     if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS)
         error("Compression and encryption not supported at the same time");
 
-    ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags);
+    ret = bdrv_create2(drv, out_filename, total_sectors, out_baseimg, NULL, 
flags);
     if (ret < 0) {
         if (ret == -ENOTSUP) {
             error("Formatting not supported for file format '%s'", out_fmt);
-- 
1.6.0.6





reply via email to

[Prev in Thread] Current Thread [Next in Thread]