Commit 5eb456396d20554a6b9637b23519579f083aa992
1 parent
9b80ddf3
block: support known backing format for image create and open (Uri Lublin)
Added a backing_format field to BlockDriverState. Added bdrv_create2 and drv->bdrv_create2 to create an image with a known backing file format. Upon bdrv_open2 if backing format is known use it, instead of probing the (backing) image. Signed-off-by: Uri Lublin <uril@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6908 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
35 additions
and
4 deletions
block.c
... | ... | @@ -181,6 +181,20 @@ BlockDriver *bdrv_find_format(const char *format_name) |
181 | 181 | return NULL; |
182 | 182 | } |
183 | 183 | |
184 | +int bdrv_create2(BlockDriver *drv, | |
185 | + const char *filename, int64_t size_in_sectors, | |
186 | + const char *backing_file, const char *backing_format, | |
187 | + int flags) | |
188 | +{ | |
189 | + if (drv->bdrv_create2) | |
190 | + return drv->bdrv_create2(filename, size_in_sectors, backing_file, | |
191 | + backing_format, flags); | |
192 | + if (drv->bdrv_create) | |
193 | + return drv->bdrv_create(filename, size_in_sectors, backing_file, | |
194 | + flags); | |
195 | + return -ENOTSUP; | |
196 | +} | |
197 | + | |
184 | 198 | int bdrv_create(BlockDriver *drv, |
185 | 199 | const char *filename, int64_t size_in_sectors, |
186 | 200 | const char *backing_file, int flags) |
... | ... | @@ -357,7 +371,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, |
357 | 371 | |
358 | 372 | /* if there is a backing file, use it */ |
359 | 373 | bs1 = bdrv_new(""); |
360 | - ret = bdrv_open(bs1, filename, 0); | |
374 | + ret = bdrv_open2(bs1, filename, 0, drv); | |
361 | 375 | if (ret < 0) { |
362 | 376 | bdrv_delete(bs1); |
363 | 377 | return ret; |
... | ... | @@ -378,12 +392,14 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, |
378 | 392 | else |
379 | 393 | realpath(filename, backing_filename); |
380 | 394 | |
381 | - ret = bdrv_create(&bdrv_qcow2, tmp_filename, | |
382 | - total_size, backing_filename, 0); | |
395 | + ret = bdrv_create2(&bdrv_qcow2, tmp_filename, | |
396 | + total_size, backing_filename, | |
397 | + (drv ? drv->format_name : NULL), 0); | |
383 | 398 | if (ret < 0) { |
384 | 399 | return ret; |
385 | 400 | } |
386 | 401 | filename = tmp_filename; |
402 | + drv = &bdrv_qcow2; | |
387 | 403 | bs->is_temporary = 1; |
388 | 404 | } |
389 | 405 | |
... | ... | @@ -429,10 +445,14 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, |
429 | 445 | #endif |
430 | 446 | if (bs->backing_file[0] != '\0') { |
431 | 447 | /* if there is a backing file, use it */ |
448 | + BlockDriver *back_drv = NULL; | |
432 | 449 | bs->backing_hd = bdrv_new(""); |
433 | 450 | path_combine(backing_filename, sizeof(backing_filename), |
434 | 451 | filename, bs->backing_file); |
435 | - ret = bdrv_open(bs->backing_hd, backing_filename, open_flags); | |
452 | + if (bs->backing_format[0] != '\0') | |
453 | + back_drv = bdrv_find_format(bs->backing_format); | |
454 | + ret = bdrv_open2(bs->backing_hd, backing_filename, open_flags, | |
455 | + back_drv); | |
436 | 456 | if (ret < 0) { |
437 | 457 | bdrv_close(bs); |
438 | 458 | return ret; | ... | ... |
block.h
... | ... | @@ -62,6 +62,10 @@ BlockDriver *bdrv_find_format(const char *format_name); |
62 | 62 | int bdrv_create(BlockDriver *drv, |
63 | 63 | const char *filename, int64_t size_in_sectors, |
64 | 64 | const char *backing_file, int flags); |
65 | +int bdrv_create2(BlockDriver *drv, | |
66 | + const char *filename, int64_t size_in_sectors, | |
67 | + const char *backing_file, const char *backing_format, | |
68 | + int flags); | |
65 | 69 | BlockDriverState *bdrv_new(const char *device_name); |
66 | 70 | void bdrv_delete(BlockDriverState *bs); |
67 | 71 | int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); | ... | ... |
block_int.h
... | ... | @@ -91,6 +91,12 @@ struct BlockDriver { |
91 | 91 | BlockDriverCompletionFunc *cb, void *opaque); |
92 | 92 | |
93 | 93 | AIOPool aio_pool; |
94 | + | |
95 | + /* new create with backing file format */ | |
96 | + int (*bdrv_create2)(const char *filename, int64_t total_sectors, | |
97 | + const char *backing_file, const char *backing_format, | |
98 | + int flags); | |
99 | + | |
94 | 100 | struct BlockDriver *next; |
95 | 101 | }; |
96 | 102 | |
... | ... | @@ -113,6 +119,7 @@ struct BlockDriverState { |
113 | 119 | char filename[1024]; |
114 | 120 | char backing_file[1024]; /* if non zero, the image is a diff of |
115 | 121 | this file image */ |
122 | + char backing_format[16]; /* if non-zero and backing_file exists */ | |
116 | 123 | int is_temporary; |
117 | 124 | int media_changed; |
118 | 125 | ... | ... |