Commit 0e7e1989f7fced8e39f140e1958f0557b60d4532
Committed by
Anthony Liguori
1 parent
d3f24367
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>
Showing
12 changed files
with
214 additions
and
55 deletions
block.c
| ... | ... | @@ -189,22 +189,44 @@ int bdrv_create2(BlockDriver *drv, |
| 189 | 189 | const char *backing_file, const char *backing_format, |
| 190 | 190 | int flags) |
| 191 | 191 | { |
| 192 | - if (drv->bdrv_create2) | |
| 193 | - return drv->bdrv_create2(filename, size_in_sectors, backing_file, | |
| 194 | - backing_format, flags); | |
| 195 | - if (drv->bdrv_create) | |
| 196 | - return drv->bdrv_create(filename, size_in_sectors, backing_file, | |
| 197 | - flags); | |
| 198 | - return -ENOTSUP; | |
| 192 | + QEMUOptionParameter *options; | |
| 193 | + | |
| 194 | + options = parse_option_parameters("", drv->create_options, NULL); | |
| 195 | + | |
| 196 | + // Process flags | |
| 197 | + if (flags & ~(BLOCK_FLAG_ENCRYPT | BLOCK_FLAG_COMPAT6 | BLOCK_FLAG_COMPRESS)) { | |
| 198 | + return -ENOTSUP; | |
| 199 | + } | |
| 200 | + | |
| 201 | + if (flags & BLOCK_FLAG_ENCRYPT) { | |
| 202 | + set_option_parameter_int(options, BLOCK_OPT_ENCRYPT, 1); | |
| 203 | + } | |
| 204 | + if (flags & BLOCK_FLAG_COMPAT6) { | |
| 205 | + set_option_parameter_int(options, BLOCK_OPT_COMPAT6, 1); | |
| 206 | + } | |
| 207 | + | |
| 208 | + // Add size to options | |
| 209 | + set_option_parameter_int(options, BLOCK_OPT_SIZE, size_in_sectors * 512); | |
| 210 | + | |
| 211 | + // Backing files | |
| 212 | + if ((backing_file != NULL && set_option_parameter(options, | |
| 213 | + BLOCK_OPT_BACKING_FILE, backing_file)) | |
| 214 | + || (backing_format != NULL && set_option_parameter(options, | |
| 215 | + BLOCK_OPT_BACKING_FMT, backing_format))) | |
| 216 | + { | |
| 217 | + return -ENOTSUP; | |
| 218 | + } | |
| 219 | + | |
| 220 | + return bdrv_create(drv, filename, options); | |
| 199 | 221 | } |
| 200 | 222 | |
| 201 | -int bdrv_create(BlockDriver *drv, | |
| 202 | - const char *filename, int64_t size_in_sectors, | |
| 203 | - const char *backing_file, int flags) | |
| 223 | +int bdrv_create(BlockDriver *drv, const char* filename, | |
| 224 | + QEMUOptionParameter *options) | |
| 204 | 225 | { |
| 205 | 226 | if (!drv->bdrv_create) |
| 206 | 227 | return -ENOTSUP; |
| 207 | - return drv->bdrv_create(filename, size_in_sectors, backing_file, flags); | |
| 228 | + | |
| 229 | + return drv->bdrv_create(filename, options); | |
| 208 | 230 | } |
| 209 | 231 | |
| 210 | 232 | #ifdef _WIN32 | ... | ... |
block.h
| ... | ... | @@ -3,6 +3,7 @@ |
| 3 | 3 | |
| 4 | 4 | #include "qemu-aio.h" |
| 5 | 5 | #include "qemu-common.h" |
| 6 | +#include "qemu-option.h" | |
| 6 | 7 | |
| 7 | 8 | /* block.c */ |
| 8 | 9 | typedef struct BlockDriver BlockDriver; |
| ... | ... | @@ -45,9 +46,8 @@ void bdrv_info_stats(Monitor *mon); |
| 45 | 46 | |
| 46 | 47 | void bdrv_init(void); |
| 47 | 48 | BlockDriver *bdrv_find_format(const char *format_name); |
| 48 | -int bdrv_create(BlockDriver *drv, | |
| 49 | - const char *filename, int64_t size_in_sectors, | |
| 50 | - const char *backing_file, int flags); | |
| 49 | +int bdrv_create(BlockDriver *drv, const char* filename, | |
| 50 | + QEMUOptionParameter *options); | |
| 51 | 51 | int bdrv_create2(BlockDriver *drv, |
| 52 | 52 | const char *filename, int64_t size_in_sectors, |
| 53 | 53 | const char *backing_file, const char *backing_format, | ... | ... |
block/cow.c
| ... | ... | @@ -202,15 +202,23 @@ static void cow_close(BlockDriverState *bs) |
| 202 | 202 | close(s->fd); |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | -static int cow_create(const char *filename, int64_t image_sectors, | |
| 206 | - const char *image_filename, int flags) | |
| 205 | +static int cow_create(const char *filename, QEMUOptionParameter *options) | |
| 207 | 206 | { |
| 208 | 207 | int fd, cow_fd; |
| 209 | 208 | struct cow_header_v2 cow_header; |
| 210 | 209 | struct stat st; |
| 211 | - | |
| 212 | - if (flags) | |
| 213 | - return -ENOTSUP; | |
| 210 | + int64_t image_sectors = 0; | |
| 211 | + const char *image_filename = NULL; | |
| 212 | + | |
| 213 | + /* Read out options */ | |
| 214 | + while (options && options->name) { | |
| 215 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 216 | + image_sectors = options->value.n / 512; | |
| 217 | + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { | |
| 218 | + image_filename = options->value.s; | |
| 219 | + } | |
| 220 | + options++; | |
| 221 | + } | |
| 214 | 222 | |
| 215 | 223 | cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, |
| 216 | 224 | 0644); |
| ... | ... | @@ -253,6 +261,12 @@ static void cow_flush(BlockDriverState *bs) |
| 253 | 261 | fsync(s->fd); |
| 254 | 262 | } |
| 255 | 263 | |
| 264 | +static QEMUOptionParameter cow_create_options[] = { | |
| 265 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 266 | + { BLOCK_OPT_BACKING_FILE, OPT_STRING }, | |
| 267 | + { NULL } | |
| 268 | +}; | |
| 269 | + | |
| 256 | 270 | static BlockDriver bdrv_cow = { |
| 257 | 271 | .format_name = "cow", |
| 258 | 272 | .instance_size = sizeof(BDRVCowState), |
| ... | ... | @@ -264,6 +278,8 @@ static BlockDriver bdrv_cow = { |
| 264 | 278 | .bdrv_create = cow_create, |
| 265 | 279 | .bdrv_flush = cow_flush, |
| 266 | 280 | .bdrv_is_allocated = cow_is_allocated, |
| 281 | + | |
| 282 | + .create_options = cow_create_options, | |
| 267 | 283 | }; |
| 268 | 284 | |
| 269 | 285 | static void bdrv_cow_init(void) | ... | ... |
block/qcow.c
| ... | ... | @@ -767,12 +767,26 @@ static void qcow_close(BlockDriverState *bs) |
| 767 | 767 | bdrv_delete(s->hd); |
| 768 | 768 | } |
| 769 | 769 | |
| 770 | -static int qcow_create(const char *filename, int64_t total_size, | |
| 771 | - const char *backing_file, int flags) | |
| 770 | +static int qcow_create(const char *filename, QEMUOptionParameter *options) | |
| 772 | 771 | { |
| 773 | 772 | int fd, header_size, backing_filename_len, l1_size, i, shift; |
| 774 | 773 | QCowHeader header; |
| 775 | 774 | uint64_t tmp; |
| 775 | + int64_t total_size = 0; | |
| 776 | + const char *backing_file = NULL; | |
| 777 | + int flags = 0; | |
| 778 | + | |
| 779 | + /* Read out options */ | |
| 780 | + while (options && options->name) { | |
| 781 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 782 | + total_size = options->value.n / 512; | |
| 783 | + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { | |
| 784 | + backing_file = options->value.s; | |
| 785 | + } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { | |
| 786 | + flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; | |
| 787 | + } | |
| 788 | + options++; | |
| 789 | + } | |
| 776 | 790 | |
| 777 | 791 | fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); |
| 778 | 792 | if (fd < 0) |
| ... | ... | @@ -918,6 +932,14 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) |
| 918 | 932 | return 0; |
| 919 | 933 | } |
| 920 | 934 | |
| 935 | + | |
| 936 | +static QEMUOptionParameter qcow_create_options[] = { | |
| 937 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 938 | + { BLOCK_OPT_BACKING_FILE, OPT_STRING }, | |
| 939 | + { BLOCK_OPT_ENCRYPT, OPT_FLAG }, | |
| 940 | + { NULL } | |
| 941 | +}; | |
| 942 | + | |
| 921 | 943 | static BlockDriver bdrv_qcow = { |
| 922 | 944 | .format_name = "qcow", |
| 923 | 945 | .instance_size = sizeof(BDRVQcowState), |
| ... | ... | @@ -935,6 +957,8 @@ static BlockDriver bdrv_qcow = { |
| 935 | 957 | .aiocb_size = sizeof(QCowAIOCB), |
| 936 | 958 | .bdrv_write_compressed = qcow_write_compressed, |
| 937 | 959 | .bdrv_get_info = qcow_get_info, |
| 960 | + | |
| 961 | + .create_options = qcow_create_options, | |
| 938 | 962 | }; |
| 939 | 963 | |
| 940 | 964 | static void bdrv_qcow_init(void) | ... | ... |
block/qcow2.c
| ... | ... | @@ -1696,10 +1696,28 @@ static int qcow_create2(const char *filename, int64_t total_size, |
| 1696 | 1696 | return 0; |
| 1697 | 1697 | } |
| 1698 | 1698 | |
| 1699 | -static int qcow_create(const char *filename, int64_t total_size, | |
| 1700 | - const char *backing_file, int flags) | |
| 1701 | -{ | |
| 1702 | - return qcow_create2(filename, total_size, backing_file, NULL, flags); | |
| 1699 | +static int qcow_create(const char *filename, QEMUOptionParameter *options) | |
| 1700 | +{ | |
| 1701 | + const char *backing_file = NULL; | |
| 1702 | + const char *backing_fmt = NULL; | |
| 1703 | + uint64_t sectors = 0; | |
| 1704 | + int flags = 0; | |
| 1705 | + | |
| 1706 | + /* Read out options */ | |
| 1707 | + while (options && options->name) { | |
| 1708 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 1709 | + sectors = options->value.n / 512; | |
| 1710 | + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { | |
| 1711 | + backing_file = options->value.s; | |
| 1712 | + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { | |
| 1713 | + backing_fmt = options->value.s; | |
| 1714 | + } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { | |
| 1715 | + flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; | |
| 1716 | + } | |
| 1717 | + options++; | |
| 1718 | + } | |
| 1719 | + | |
| 1720 | + return qcow_create2(filename, sectors, backing_file, backing_fmt, flags); | |
| 1703 | 1721 | } |
| 1704 | 1722 | |
| 1705 | 1723 | static int qcow_make_empty(BlockDriverState *bs) |
| ... | ... | @@ -2897,6 +2915,14 @@ static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf, |
| 2897 | 2915 | return ret; |
| 2898 | 2916 | } |
| 2899 | 2917 | |
| 2918 | +static QEMUOptionParameter qcow_create_options[] = { | |
| 2919 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 2920 | + { BLOCK_OPT_BACKING_FILE, OPT_STRING }, | |
| 2921 | + { BLOCK_OPT_BACKING_FMT, OPT_STRING }, | |
| 2922 | + { BLOCK_OPT_ENCRYPT, OPT_FLAG }, | |
| 2923 | + { NULL } | |
| 2924 | +}; | |
| 2925 | + | |
| 2900 | 2926 | static BlockDriver bdrv_qcow2 = { |
| 2901 | 2927 | .format_name = "qcow2", |
| 2902 | 2928 | .instance_size = sizeof(BDRVQcowState), |
| ... | ... | @@ -2924,7 +2950,7 @@ static BlockDriver bdrv_qcow2 = { |
| 2924 | 2950 | .bdrv_put_buffer = qcow_put_buffer, |
| 2925 | 2951 | .bdrv_get_buffer = qcow_get_buffer, |
| 2926 | 2952 | |
| 2927 | - .bdrv_create2 = qcow_create2, | |
| 2953 | + .create_options = qcow_create_options, | |
| 2928 | 2954 | .bdrv_check = qcow_check, |
| 2929 | 2955 | }; |
| 2930 | 2956 | ... | ... |
block/raw-posix.c
| ... | ... | @@ -823,13 +823,18 @@ again: |
| 823 | 823 | } |
| 824 | 824 | #endif |
| 825 | 825 | |
| 826 | -static int raw_create(const char *filename, int64_t total_size, | |
| 827 | - const char *backing_file, int flags) | |
| 826 | +static int raw_create(const char *filename, QEMUOptionParameter *options) | |
| 828 | 827 | { |
| 829 | 828 | int fd; |
| 829 | + int64_t total_size = 0; | |
| 830 | 830 | |
| 831 | - if (flags || backing_file) | |
| 832 | - return -ENOTSUP; | |
| 831 | + /* Read out options */ | |
| 832 | + while (options && options->name) { | |
| 833 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 834 | + total_size = options->value.n / 512; | |
| 835 | + } | |
| 836 | + options++; | |
| 837 | + } | |
| 833 | 838 | |
| 834 | 839 | fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, |
| 835 | 840 | 0644); |
| ... | ... | @@ -846,6 +851,12 @@ static void raw_flush(BlockDriverState *bs) |
| 846 | 851 | fsync(s->fd); |
| 847 | 852 | } |
| 848 | 853 | |
| 854 | + | |
| 855 | +static QEMUOptionParameter raw_create_options[] = { | |
| 856 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 857 | + { NULL } | |
| 858 | +}; | |
| 859 | + | |
| 849 | 860 | static BlockDriver bdrv_raw = { |
| 850 | 861 | .format_name = "raw", |
| 851 | 862 | .instance_size = sizeof(BDRVRawState), |
| ... | ... | @@ -866,6 +877,8 @@ static BlockDriver bdrv_raw = { |
| 866 | 877 | |
| 867 | 878 | .bdrv_truncate = raw_truncate, |
| 868 | 879 | .bdrv_getlength = raw_getlength, |
| 880 | + | |
| 881 | + .create_options = raw_create_options, | |
| 869 | 882 | }; |
| 870 | 883 | |
| 871 | 884 | /***********************************************/ |
| ... | ... | @@ -1364,15 +1377,20 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, |
| 1364 | 1377 | #endif /* !linux && !FreeBSD */ |
| 1365 | 1378 | |
| 1366 | 1379 | #if defined(__linux__) || defined(__FreeBSD__) |
| 1367 | -static int hdev_create(const char *filename, int64_t total_size, | |
| 1368 | - const char *backing_file, int flags) | |
| 1380 | +static int hdev_create(const char *filename, QEMUOptionParameter *options) | |
| 1369 | 1381 | { |
| 1370 | 1382 | int fd; |
| 1371 | 1383 | int ret = 0; |
| 1372 | 1384 | struct stat stat_buf; |
| 1385 | + int64_t total_size = 0; | |
| 1373 | 1386 | |
| 1374 | - if (flags || backing_file) | |
| 1375 | - return -ENOTSUP; | |
| 1387 | + /* Read out options */ | |
| 1388 | + while (options && options->name) { | |
| 1389 | + if (!strcmp(options->name, "size")) { | |
| 1390 | + total_size = options->value.n / 512; | |
| 1391 | + } | |
| 1392 | + options++; | |
| 1393 | + } | |
| 1376 | 1394 | |
| 1377 | 1395 | fd = open(filename, O_WRONLY | O_BINARY); |
| 1378 | 1396 | if (fd < 0) |
| ... | ... | @@ -1391,8 +1409,7 @@ static int hdev_create(const char *filename, int64_t total_size, |
| 1391 | 1409 | |
| 1392 | 1410 | #else /* !(linux || freebsd) */ |
| 1393 | 1411 | |
| 1394 | -static int hdev_create(const char *filename, int64_t total_size, | |
| 1395 | - const char *backing_file, int flags) | |
| 1412 | +static int hdev_create(const char *filename, QEMUOptionParameter *options) | |
| 1396 | 1413 | { |
| 1397 | 1414 | return -ENOTSUP; |
| 1398 | 1415 | } | ... | ... |
block/raw-win32.c
| ... | ... | @@ -210,13 +210,18 @@ static int64_t raw_getlength(BlockDriverState *bs) |
| 210 | 210 | return l.QuadPart; |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | -static int raw_create(const char *filename, int64_t total_size, | |
| 214 | - const char *backing_file, int flags) | |
| 213 | +static int raw_create(const char *filename, QEMUOptionParameter *options) | |
| 215 | 214 | { |
| 216 | 215 | int fd; |
| 216 | + int64_t total_size = 0; | |
| 217 | 217 | |
| 218 | - if (flags || backing_file) | |
| 219 | - return -ENOTSUP; | |
| 218 | + /* Read out options */ | |
| 219 | + while (options && options->name) { | |
| 220 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 221 | + total_size = options->value.n / 512; | |
| 222 | + } | |
| 223 | + options++; | |
| 224 | + } | |
| 220 | 225 | |
| 221 | 226 | fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, |
| 222 | 227 | 0644); |
| ... | ... | @@ -228,6 +233,11 @@ static int raw_create(const char *filename, int64_t total_size, |
| 228 | 233 | return 0; |
| 229 | 234 | } |
| 230 | 235 | |
| 236 | +static QEMUOptionParameter raw_create_options[] = { | |
| 237 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 238 | + { NULL } | |
| 239 | +}; | |
| 240 | + | |
| 231 | 241 | static BlockDriver bdrv_raw = { |
| 232 | 242 | .format_name = "raw", |
| 233 | 243 | .instance_size = sizeof(BDRVRawState), |
| ... | ... | @@ -239,6 +249,8 @@ static BlockDriver bdrv_raw = { |
| 239 | 249 | .bdrv_write = raw_write, |
| 240 | 250 | .bdrv_truncate = raw_truncate, |
| 241 | 251 | .bdrv_getlength = raw_getlength, |
| 252 | + | |
| 253 | + .create_options = raw_create_options, | |
| 242 | 254 | }; |
| 243 | 255 | |
| 244 | 256 | /***********************************************/ | ... | ... |
block/vmdk.c
| ... | ... | @@ -687,8 +687,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, |
| 687 | 687 | return 0; |
| 688 | 688 | } |
| 689 | 689 | |
| 690 | -static int vmdk_create(const char *filename, int64_t total_size, | |
| 691 | - const char *backing_file, int flags) | |
| 690 | +static int vmdk_create(const char *filename, QEMUOptionParameter *options) | |
| 692 | 691 | { |
| 693 | 692 | int fd, i; |
| 694 | 693 | VMDK4Header header; |
| ... | ... | @@ -713,6 +712,21 @@ static int vmdk_create(const char *filename, int64_t total_size, |
| 713 | 712 | "ddb.adapterType = \"ide\"\n"; |
| 714 | 713 | char desc[1024]; |
| 715 | 714 | const char *real_filename, *temp_str; |
| 715 | + int64_t total_size = 0; | |
| 716 | + const char *backing_file = NULL; | |
| 717 | + int flags = 0; | |
| 718 | + | |
| 719 | + // Read out options | |
| 720 | + while (options && options->name) { | |
| 721 | + if (!strcmp(options->name, BLOCK_OPT_SIZE)) { | |
| 722 | + total_size = options->value.n / 512; | |
| 723 | + } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { | |
| 724 | + backing_file = options->value.s; | |
| 725 | + } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { | |
| 726 | + flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0; | |
| 727 | + } | |
| 728 | + options++; | |
| 729 | + } | |
| 716 | 730 | |
| 717 | 731 | /* XXX: add support for backing file */ |
| 718 | 732 | if (backing_file) { |
| ... | ... | @@ -812,6 +826,14 @@ static void vmdk_flush(BlockDriverState *bs) |
| 812 | 826 | bdrv_flush(s->hd); |
| 813 | 827 | } |
| 814 | 828 | |
| 829 | + | |
| 830 | +static QEMUOptionParameter vmdk_create_options[] = { | |
| 831 | + { BLOCK_OPT_SIZE, OPT_SIZE }, | |
| 832 | + { BLOCK_OPT_BACKING_FILE, OPT_STRING }, | |
| 833 | + { BLOCK_OPT_COMPAT6, OPT_FLAG }, | |
| 834 | + { NULL } | |
| 835 | +}; | |
| 836 | + | |
| 815 | 837 | static BlockDriver bdrv_vmdk = { |
| 816 | 838 | .format_name = "vmdk", |
| 817 | 839 | .instance_size = sizeof(BDRVVmdkState), |
| ... | ... | @@ -823,6 +845,8 @@ static BlockDriver bdrv_vmdk = { |
| 823 | 845 | .bdrv_create = vmdk_create, |
| 824 | 846 | .bdrv_flush = vmdk_flush, |
| 825 | 847 | .bdrv_is_allocated = vmdk_is_allocated, |
| 848 | + | |
| 849 | + .create_options = vmdk_create_options, | |
| 826 | 850 | }; |
| 827 | 851 | |
| 828 | 852 | static void bdrv_vmdk_init(void) | ... | ... |
block/vpc.c
| ... | ... | @@ -477,8 +477,7 @@ static int calculate_geometry(int64_t total_sectors, uint16_t* cyls, |
| 477 | 477 | return 0; |
| 478 | 478 | } |
| 479 | 479 | |
| 480 | -static int vpc_create(const char *filename, int64_t total_sectors, | |
| 481 | - const char *backing_file, int flags) | |
| 480 | +static int vpc_create(const char *filename, QEMUOptionParameter *options) | |
| 482 | 481 | { |
| 483 | 482 | uint8_t buf[1024]; |
| 484 | 483 | struct vhd_footer* footer = (struct vhd_footer*) buf; |
| ... | ... | @@ -489,10 +488,17 @@ static int vpc_create(const char *filename, int64_t total_sectors, |
| 489 | 488 | uint8_t heads; |
| 490 | 489 | uint8_t secs_per_cyl; |
| 491 | 490 | size_t block_size, num_bat_entries; |
| 491 | + int64_t total_sectors = 0; | |
| 492 | 492 | |
| 493 | - if (backing_file != NULL) | |
| 494 | - return -ENOTSUP; | |
| 493 | + // Read out options | |
| 494 | + while (options && options->name) { | |
| 495 | + if (!strcmp(options->name, "size")) { | |
| 496 | + total_sectors = options->value.n / 512; | |
| 497 | + } | |
| 498 | + options++; | |
| 499 | + } | |
| 495 | 500 | |
| 501 | + // Create the file | |
| 496 | 502 | fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); |
| 497 | 503 | if (fd < 0) |
| 498 | 504 | return -EIO; |
| ... | ... | @@ -587,6 +593,11 @@ static void vpc_close(BlockDriverState *bs) |
| 587 | 593 | bdrv_delete(s->hd); |
| 588 | 594 | } |
| 589 | 595 | |
| 596 | +static QEMUOptionParameter vpc_create_options[] = { | |
| 597 | + { "size", OPT_SIZE }, | |
| 598 | + { NULL } | |
| 599 | +}; | |
| 600 | + | |
| 590 | 601 | static BlockDriver bdrv_vpc = { |
| 591 | 602 | .format_name = "vpc", |
| 592 | 603 | .instance_size = sizeof(BDRVVPCState), |
| ... | ... | @@ -596,6 +607,8 @@ static BlockDriver bdrv_vpc = { |
| 596 | 607 | .bdrv_write = vpc_write, |
| 597 | 608 | .bdrv_close = vpc_close, |
| 598 | 609 | .bdrv_create = vpc_create, |
| 610 | + | |
| 611 | + .create_options = vpc_create_options, | |
| 599 | 612 | }; |
| 600 | 613 | |
| 601 | 614 | static void bdrv_vpc_init(void) | ... | ... |
block/vvfat.c
| ... | ... | @@ -2777,8 +2777,8 @@ static int enable_write_target(BDRVVVFATState *s) |
| 2777 | 2777 | |
| 2778 | 2778 | s->qcow_filename = qemu_malloc(1024); |
| 2779 | 2779 | get_tmp_filename(s->qcow_filename, 1024); |
| 2780 | - if (bdrv_create(bdrv_find_format("qcow"), | |
| 2781 | - s->qcow_filename, s->sector_count, "fat:", 0) < 0) | |
| 2780 | + if (bdrv_create2(bdrv_find_format("qcow"), | |
| 2781 | + s->qcow_filename, s->sector_count, "fat:", NULL, 0) < 0) | |
| 2782 | 2782 | return -1; |
| 2783 | 2783 | s->qcow = bdrv_new(""); |
| 2784 | 2784 | if (s->qcow == NULL || bdrv_open(s->qcow, s->qcow_filename, 0) < 0) | ... | ... |
block_int.h
| ... | ... | @@ -25,11 +25,18 @@ |
| 25 | 25 | #define BLOCK_INT_H |
| 26 | 26 | |
| 27 | 27 | #include "block.h" |
| 28 | +#include "qemu-option.h" | |
| 28 | 29 | |
| 29 | 30 | #define BLOCK_FLAG_ENCRYPT 1 |
| 30 | 31 | #define BLOCK_FLAG_COMPRESS 2 |
| 31 | 32 | #define BLOCK_FLAG_COMPAT6 4 |
| 32 | 33 | |
| 34 | +#define BLOCK_OPT_SIZE "size" | |
| 35 | +#define BLOCK_OPT_ENCRYPT "encryption" | |
| 36 | +#define BLOCK_OPT_COMPAT6 "compat6" | |
| 37 | +#define BLOCK_OPT_BACKING_FILE "backing_file" | |
| 38 | +#define BLOCK_OPT_BACKING_FMT "backing_fmt" | |
| 39 | + | |
| 33 | 40 | typedef struct AIOPool { |
| 34 | 41 | void (*cancel)(BlockDriverAIOCB *acb); |
| 35 | 42 | int aiocb_size; |
| ... | ... | @@ -46,8 +53,7 @@ struct BlockDriver { |
| 46 | 53 | int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, |
| 47 | 54 | const uint8_t *buf, int nb_sectors); |
| 48 | 55 | void (*bdrv_close)(BlockDriverState *bs); |
| 49 | - int (*bdrv_create)(const char *filename, int64_t total_sectors, | |
| 50 | - const char *backing_file, int flags); | |
| 56 | + int (*bdrv_create)(const char *filename, QEMUOptionParameter *options); | |
| 51 | 57 | void (*bdrv_flush)(BlockDriverState *bs); |
| 52 | 58 | int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, |
| 53 | 59 | int nb_sectors, int *pnum); |
| ... | ... | @@ -97,10 +103,9 @@ struct BlockDriver { |
| 97 | 103 | |
| 98 | 104 | AIOPool aio_pool; |
| 99 | 105 | |
| 100 | - /* new create with backing file format */ | |
| 101 | - int (*bdrv_create2)(const char *filename, int64_t total_sectors, | |
| 102 | - const char *backing_file, const char *backing_format, | |
| 103 | - int flags); | |
| 106 | + /* List of options for creating images, terminated by name == NULL */ | |
| 107 | + QEMUOptionParameter *create_options; | |
| 108 | + | |
| 104 | 109 | |
| 105 | 110 | /* Returns number of errors in image, -errno for internal errors */ |
| 106 | 111 | int (*bdrv_check)(BlockDriverState* bs); | ... | ... |
qemu-img.c
| ... | ... | @@ -551,7 +551,7 @@ static int img_convert(int argc, char **argv) |
| 551 | 551 | if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS) |
| 552 | 552 | error("Compression and encryption not supported at the same time"); |
| 553 | 553 | |
| 554 | - ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags); | |
| 554 | + ret = bdrv_create2(drv, out_filename, total_sectors, out_baseimg, NULL, flags); | |
| 555 | 555 | if (ret < 0) { |
| 556 | 556 | if (ret == -ENOTSUP) { |
| 557 | 557 | error("Formatting not supported for file format '%s'", out_fmt); | ... | ... |