Convert all block drivers to new bdrv_create

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 <kwolf@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Kevin Wolf 2009-05-18 16:42:10 +02:00 committed by Anthony Liguori
parent d3f243676a
commit 0e7e1989f7
12 changed files with 212 additions and 53 deletions

44
block.c
View File

@ -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

View File

@ -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,

View File

@ -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;
int64_t image_sectors = 0;
const char *image_filename = NULL;
if (flags)
return -ENOTSUP;
/* 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)

View File

@ -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)

View File

@ -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)
static int qcow_create(const char *filename, QEMUOptionParameter *options)
{
return qcow_create2(filename, total_size, backing_file, NULL, flags);
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)
@ -2897,6 +2915,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),
@ -2924,7 +2950,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,
};

View File

@ -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;
}

View File

@ -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,
};
/***********************************************/

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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);