Block patches
Subsystems (2)
Hi Anthony,
this is the first part of the block patches that accumulated in my block branch during your absence. I consider these patches ready to be merged into master. I've not included another 13 patches that might still need discussion/review or depend on such patches. I'm going to send another pull request for them some time next week.
Kevin
The following changes since commit 6c557ab975fc8e5edb4167a241266c7c4657054a:
Serge Ziryukin (1):
audio/sdlaudio: remove unused variable
are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-anthony
Bruce Rogers (1):
Remove un-needed code
Christoph Hellwig (3):
block: get rid of the BDRV_O_FILE flag
block: split raw_getlength
cleanup block driver option handling in vl.c
Kevin Wolf (14):
qemu-config: qemu_read_config_file() reads the normal config file
qemu-config: Make qemu_config_parse more generic
blkdebug: Basic request passthrough
blkdebug: Inject errors
Make qemu-config available for tools
blkdebug: Add events and rules
qcow2: Trigger blkdebug events
qcow2: Fix creation of large images
Replace calls of old bdrv_open
qcow2: Return 0/-errno in write_l2_entries
qcow2: Fix error return code in qcow2_alloc_cluster_link_l2
qcow2: Return 0/-errno in write_l1_entry
qcow2: Return 0/-errno in l2_allocate
block.h: bdrv_create2 doesn't exist any more
Stefan Hajnoczi (8):
block: Do not export bdrv_first
block: Convert bdrv_first to QTAILQ
block: Convert first_drv to QLIST
qemu-img: Eliminate bdrv_new_open() code duplication
qemu-img: Fix BRDV_O_FLAGS typo
linux-aio: Fix typo in read() EINTR check
qcow2: Use QLIST_FOREACH_SAFE macro
block: Free iovec arrays allocated by multiwrite_merge()
Makefile.objs | 6 +- block-migration.c | 63 ++++--- block.c | 119 +++++++------ block.h | 66 ++++++- block/blkdebug.c | 475 ++++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2-cluster.c | 78 +++++--- block/qcow2-refcount.c | 18 ++ block/qcow2.c | 63 +++++-- block/raw-posix.c | 65 +++++--- block/vmdk.c | 2 +- block/vvfat.c | 5 +- block_int.h | 9 +- hw/qdev-properties.c | 19 ++- hw/qdev.h | 1 - hw/virtio-blk.c | 1 - hw/xen_disk.c | 2 +- linux-aio.c | 2 +- monitor.c | 2 +- qemu-config.c | 48 +++--- qemu-config.h | 4 +- qemu-img.c | 93 ++-------- qemu-io.c | 28 ++-- qemu-nbd.c | 2 +- vl.c | 82 +++------ 24 files changed, 902 insertions(+), 351 deletions(-) create mode 100644 block/blkdebug.c
PATCH 1/26 qemu-config: qemu_read_config_file() reads the normal config file
Introduce a new function qemu_read_config_file which reads the VM configuration from a config file. Unlike qemu_config_parse it doesn't take a open file but a filename and reduces code duplication as a side effect.
--- qemu-config.c | 15 +++++++++++++++ qemu-config.h | 2 ++ vl.c | 35 +++++++++++------------------------ 3 files changed, 28 insertions(+), 24 deletions(-)
qemu-config.c +15 -0
@@ -488,3 +488,18 @@ out:loc_pop (&loc);return res; } + +int qemu_read_config_file (const char *filename) +{ +FILE *f =fopen (filename,"r" ); +if (f ==NULL ) { +return -errno; + } + +if (qemu_config_parse (f, filename) !=0 ) { +return -EINVAL ; + } +fclose (f); + +return 0 ; +}
qemu-config.h +2 -0
@@ -19,4 +19,6 @@ void qemu_add_globals(void);void qemu_config_write (FILE *fp);int qemu_config_parse (FILE *fp,const char *fname); +int qemu_read_config_file (const char *filename); +#endif /* QEMU_CONFIG_H */
vl.c +11 -24
@@ -2653,25 +2653,16 @@ int main(int argc, char **argv, char **envp) }if (defconfig) { -const char *fname; -FILE *fp; +int ret; - fname =CONFIG_QEMU_CONFDIR "/qemu.conf" ; - fp =fopen (fname,"r" ); -if (fp) { -if (qemu_config_parse (fp, fname) !=0 ) { -exit (1 ); - } -fclose (fp); + ret =qemu_read_config_file (CONFIG_QEMU_CONFDIR "/qemu.conf" ); +if (ret == -EINVAL ) { +exit (1 ); } - fname = arch_config_name; - fp =fopen (fname,"r" ); -if (fp) { -if (qemu_config_parse (fp, fname) !=0 ) { -exit (1 ); - } -fclose (fp); + ret =qemu_read_config_file (arch_config_name); +if (ret == -EINVAL ) { +exit (1 ); } }cpudef_init ();
@@ -3327,16 +3318,12 @@ int main(int argc, char **argv, char **envp)break ;case QEMU_OPTION_readconfig: { -FILE *fp; - fp =fopen (optarg,"r" ); -if (fp ==NULL ) { -fprintf (stderr,"open %s: %s\n" , optarg,strerror (errno)); +int ret =qemu_read_config_file (optarg); +if (ret <0 ) { +fprintf (stderr,"read config %s: %s\n" , optarg, +strerror (-ret));exit (1 ); } -if (qemu_config_parse (fp, optarg) !=0 ) { -exit (1 ); - } -fclose (fp);break ; }case QEMU_OPTION_writeconfig:
Signature · 1 line
1.6.6.1
PATCH 2/26 qemu-config: Make qemu_config_parse more generic
In reply to Kevin Wolfqemu_config_parse gets the option groups as a parameter now instead of hardcoding the VM configuration groups. This way it can be used for other configurations, too.
--- qemu-config.c | 18 ++++++++++++------ qemu-config.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-)
qemu-config.c +12 -6
@@ -296,7 +296,7 @@ QemuOptsList qemu_cpudef_opts = { }, }; -static QemuOptsList *lists[] = { +static QemuOptsList *vm_config_groups[] = { &qemu_drive_opts, &qemu_chardev_opts, &qemu_device_opts,
@@ -309,7 +309,7 @@ static QemuOptsList *lists[] = { NULL, }; -QemuOptsList *qemu_find_opts (const char *group) +static QemuOptsList *find_list (QemuOptsList **lists,const char *group) {int i;
@@ -323,6 +323,11 @@ QemuOptsList *qemu_find_opts(const char *group)return lists[i]; } +QemuOptsList *qemu_find_opts (const char *group) +{ +return find_list (vm_config_groups, group); +} +int qemu_set_option (const char *str) {char group[64 ], id[64 ], arg[64 ];
@@ -421,6 +426,7 @@ static int config_write_opts(QemuOpts *opts, void *opaque)void qemu_config_write (FILE *fp) {struct ConfigWriteData data = { .fp = fp }; +QemuOptsList **lists = vm_config_groups;int i;fprintf (fp,"# qemu config file\n\n" );
@@ -430,7 +436,7 @@ void qemu_config_write(FILE *fp) } } -int qemu_config_parse (FILE *fp,const char *fname) +int qemu_config_parse (FILE *fp,QemuOptsList **lists,const char *fname) {char line[1024 ], group[64 ], id[64 ], arg[64 ], value[1024 ];Location loc;
@@ -451,7 +457,7 @@ int qemu_config_parse(FILE *fp, const char *fname) }if (sscanf (line,"[%63s \"%63[^\"]\"]" , group, id) ==2 ) {/* group with id */ - list =qemu_find_opts (group); + list =find_list (lists, group);if (list ==NULL ) goto out; opts =qemu_opts_create (list, id,1 );
@@ -459,7 +465,7 @@ int qemu_config_parse(FILE *fp, const char *fname) }if (sscanf (line,"[%63[^]]]" , group) ==1 ) {/* group without id */ - list =qemu_find_opts (group); + list =find_list (lists, group);if (list ==NULL ) goto out; opts =qemu_opts_create (list,NULL ,0 );
@@ -496,7 +502,7 @@ int qemu_read_config_file(const char *filename)return -errno; } -if (qemu_config_parse (f, filename) !=0 ) { +if (qemu_config_parse (f, vm_config_groups, filename) !=0 ) {return -EINVAL ; }fclose (f);
qemu-config.h +1 -1
@@ -17,7 +17,7 @@ int qemu_global_option(const char *str);void qemu_add_globals (void );void qemu_config_write (FILE *fp); -int qemu_config_parse (FILE *fp,const char *fname); +int qemu_config_parse (FILE *fp,QemuOptsList **lists,const char *fname);int qemu_read_config_file (const char *filename);
Signature · 1 line
1.6.6.1
PATCH 3/26 blkdebug: Basic request passthrough
In reply to Kevin WolfThis isn't doing anything interesting. It creates the blkdebug block driver as a protocol which just passes everything through to raw.
--- Makefile.objs | 2 +- block/blkdebug.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletions(-) create mode 100644 block/blkdebug.c
Makefile.objs +1 -1
@@ -14,7 +14,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o block-nested-y += cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o -block-nested-y += parallels.o nbd.o +block-nested-y += parallels.o nbd.o blkdebug.o block-nested-$(CONFIG_WIN32) += raw-win32.o block-nested-$(CONFIG_POSIX) += raw-posix.o block-nested-$(CONFIG_CURL) += curl.o
block/blkdebug.c new file +104 -0
104 lines not on this page · raw message
Signature · 1 line
1.6.6.1
PATCH 4/26 blkdebug: Inject errors
In reply to Kevin WolfAdd a mechanism to inject errors instead of passing requests on. With no further patches applied, you can use it by setting inject_errno in gdb.
--- block/blkdebug.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 81 insertions(+), 0 deletions(-)
block/blkdebug.c +81 -0
@@ -26,10 +26,41 @@#include "block_int.h" #include "module.h" +#include <stdbool.h> + +typedef struct BlkdebugVars { +int state; + +/* If inject_errno != 0, an error is injected for requests */ +int inject_errno; + +/* Decides if all future requests fail (false) or only the next one and +* after the next request inject_errno is reset to 0 (true) */ +bool inject_once; + +/* Decides if aio_readv/writev fails right away (true) or returns an error +* return value only in the callback (false) */ +bool inject_immediately; +}BlkdebugVars ; +typedef struct BDRVBlkdebugState {BlockDriverState *hd; +BlkdebugVars vars; }BDRVBlkdebugState ; +typedef struct BlkdebugAIOCB { +BlockDriverAIOCB common; +QEMUBH *bh; +int ret; +}BlkdebugAIOCB ; + +static void blkdebug_aio_cancel (BlockDriverAIOCB *blockacb); + +static AIOPool blkdebug_aio_pool = { + .aiocb_size =sizeof (BlkdebugAIOCB), + .cancel = blkdebug_aio_cancel, +}; +static int blkdebug_open (BlockDriverState *bs,const char *filename,int flags) {BDRVBlkdebugState *s = bs->opaque;
@@ -42,11 +73,56 @@ static int blkdebug_open(BlockDriverState *bs, const char *filename, int flags)return bdrv_file_open (&s->hd, filename, flags); } +static void error_callback_bh (void *opaque) +{ +struct BlkdebugAIOCB *acb = opaque; +qemu_bh_delete (acb->bh); + acb->common.cb (acb->common.opaque, acb->ret); +qemu_aio_release (acb); +} + +static void blkdebug_aio_cancel (BlockDriverAIOCB *blockacb) +{ +BlkdebugAIOCB *acb = (BlkdebugAIOCB *) blockacb; +qemu_aio_release (acb); +} + +static BlockDriverAIOCB *inject_error (BlockDriverState *bs, +BlockDriverCompletionFunc *cb,void *opaque) +{ +BDRVBlkdebugState *s = bs->opaque; +int error = s->vars.inject_errno; +struct BlkdebugAIOCB *acb; +QEMUBH *bh; + +if (s->vars.inject_once) { + s->vars.inject_errno =0 ; + } + +if (s->vars.inject_immediately) { +return NULL ; + } + + acb =qemu_aio_get (&blkdebug_aio_pool, bs, cb, opaque); + acb->ret = -error; + + bh =qemu_bh_new (error_callback_bh, acb); + acb->bh = bh; +qemu_bh_schedule (bh); + +return (BlockDriverAIOCB *) acb; +} +static BlockDriverAIOCB *blkdebug_aio_readv (BlockDriverState *bs,int64_t sector_num,QEMUIOVector *qiov,int nb_sectors,BlockDriverCompletionFunc *cb,void *opaque) {BDRVBlkdebugState *s = bs->opaque; + +if (s->vars.inject_errno) { +return inject_error (bs, cb, opaque); + } +BlockDriverAIOCB *acb =bdrv_aio_readv (s->hd, sector_num, qiov, nb_sectors, cb, opaque);return acb;
@@ -57,6 +133,11 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque) {BDRVBlkdebugState *s = bs->opaque; + +if (s->vars.inject_errno) { +return inject_error (bs, cb, opaque); + } +BlockDriverAIOCB *acb =bdrv_aio_writev (s->hd, sector_num, qiov, nb_sectors, cb, opaque);return acb;
Signature · 1 line
1.6.6.1
PATCH 5/26 Make qemu-config available for tools
In reply to Kevin WolfTo be able to use config files for blkdebug, we need to make these functions available in the tools. This involves moving two functions that can only be built in the context of the emulator.
--- Makefile.objs | 4 ++-- hw/qdev-properties.c | 19 ++++++++++++++++++- hw/qdev.h | 1 - qemu-config.c | 17 ----------------- 4 files changed, 20 insertions(+), 21 deletions(-)
Makefile.objs +2 -2
@@ -8,7 +8,7 @@ qobject-obj-y += qerror.o # block-obj-y is code used by both qemu system emulation and qemu-img block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o -block-obj-y += nbd.o block.o aio.o aes.o osdep.o +block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
@@ -76,7 +76,7 @@ common-obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o common-obj-y += qemu-char.o savevm.o #aio.o common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o -common-obj-y += qemu-config.o block-migration.o +common-obj-y += block-migration.o common-obj-$(CONFIG_BRLAPI) += baum.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
hw/qdev-properties.c +18 -1
@@ -661,7 +661,7 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props) static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); -void qdev_prop_register_global (GlobalProperty *prop) +static void qdev_prop_register_global (GlobalProperty *prop) {QTAILQ_INSERT_TAIL (&global_props, prop, next); }
@@ -689,3 +689,20 @@ void qdev_prop_set_globals(DeviceState *dev) } } } + +static int qdev_add_one_global (QemuOpts *opts,void *opaque) +{ +GlobalProperty *g; + + g =qemu_mallocz (sizeof (*g)); + g->driver =qemu_opt_get (opts,"driver" ); + g->property =qemu_opt_get (opts,"property" ); + g->value =qemu_opt_get (opts,"value" ); +qdev_prop_register_global (g); +return 0 ; +} + +void qemu_add_globals (void ) +{ +qemu_opts_foreach (&qemu_global_opts, qdev_add_one_global,NULL ,0 ); +}
hw/qdev.h +0 -1
@@ -273,7 +273,6 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);void qdev_prop_set_ptr (DeviceState *dev,const char *name,void *value);void qdev_prop_set_defaults (DeviceState *dev,Property *props); -void qdev_prop_register_global (GlobalProperty *prop);void qdev_prop_register_global_list (GlobalProperty *props);void qdev_prop_set_globals (DeviceState *dev);
qemu-config.c +0 -17
@@ -378,23 +378,6 @@ int qemu_global_option(const char *str)return 0 ; } -static int qemu_add_one_global (QemuOpts *opts,void *opaque) -{ -GlobalProperty *g; - - g =qemu_mallocz (sizeof (*g)); - g->driver =qemu_opt_get (opts,"driver" ); - g->property =qemu_opt_get (opts,"property" ); - g->value =qemu_opt_get (opts,"value" ); -qdev_prop_register_global (g); -return 0 ; -} - -void qemu_add_globals (void ) -{ -qemu_opts_foreach (&qemu_global_opts, qemu_add_one_global,NULL ,0 ); -} -struct ConfigWriteData {QemuOptsList *list;FILE *fp;
Signature · 1 line
1.6.6.1
PATCH 6/26 blkdebug: Add events and rules
In reply to Kevin WolfBlock drivers can trigger a blkdebug event whenever they reach a place where it could be useful to inject an error for testing/debugging purposes.
Rules are read from a blkdebug config file and describe which action is taken when an event is triggered. For now this is only injecting an error (with a few options) or changing the state (which is an integer). Rules can be declared to be active only in a specific state; this way later rules can distiguish on which path we came to trigger their event.
--- block.c | 12 +++ block.h | 9 ++ block/blkdebug.c | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++- block_int.h | 2 + 4 files changed, 272 insertions(+), 1 deletions(-)
block.c +12 -0
@@ -1535,6 +1535,18 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,return drv->bdrv_load_vmstate (bs, buf, pos, size); } +void bdrv_debug_event (BlockDriverState *bs,BlkDebugEvent event) +{ +BlockDriver *drv = bs->drv; + +if (!drv || !drv->bdrv_debug_event) { +return ; + } + +return drv->bdrv_debug_event (bs, event); + +} +/**************************************************************/ /* handling of snapshots */
block.h +9 -0
@@ -207,4 +207,13 @@ int bdrv_get_dirty(BlockDriverState *bs, int64_t sector);void bdrv_reset_dirty (BlockDriverState *bs,int64_t cur_sector,int nr_sectors);int64_t bdrv_get_dirty_count (BlockDriverState *bs); + + +typedef enum { +BLKDBG_EVENT_MAX , +}BlkDebugEvent ; + +#define BLKDBG_EVENT (bs, evt) bdrv_debug_event(bs, evt) +void bdrv_debug_event (BlockDriverState *bs,BlkDebugEvent event); +#endif
block/blkdebug.c +249 -1
289 lines not on this page · raw message
block_int.h +2 -0
@@ -120,6 +120,8 @@ struct BlockDriver {/* Returns number of errors in image, -errno for internal errors */ int (*bdrv_check)(BlockDriverState * bs); +void (*bdrv_debug_event)(BlockDriverState *bs,BlkDebugEvent event); +/* Set if newly created images are not guaranteed to contain only zeros */ int no_zero_init;
Signature · 1 line
1.6.6.1
PATCH 7/26 qcow2: Trigger blkdebug events
In reply to Kevin WolfThis adds blkdebug events to qcow2 to allow injecting I/O errors in specific places.
--- block.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ block/blkdebug.c | 42 ++++++++++++++++++++++++++++++++++++++++++ block/qcow2-cluster.c | 15 +++++++++++++++ block/qcow2-refcount.c | 18 ++++++++++++++++++ block/qcow2.c | 6 ++++++ 5 files changed, 125 insertions(+), 0 deletions(-)
block.h +44 -0
@@ -210,6 +210,50 @@ int64_t bdrv_get_dirty_count(BlockDriverState *bs);typedef enum { +BLKDBG_L1_UPDATE , + +BLKDBG_L1_GROW_ALLOC_TABLE , +BLKDBG_L1_GROW_WRITE_TABLE , +BLKDBG_L1_GROW_ACTIVATE_TABLE , + +BLKDBG_L2_LOAD , +BLKDBG_L2_UPDATE , +BLKDBG_L2_UPDATE_COMPRESSED , +BLKDBG_L2_ALLOC_COW_READ , +BLKDBG_L2_ALLOC_WRITE , + +BLKDBG_READ , +BLKDBG_READ_AIO , +BLKDBG_READ_BACKING , +BLKDBG_READ_BACKING_AIO , +BLKDBG_READ_COMPRESSED , + +BLKDBG_WRITE_AIO , +BLKDBG_WRITE_COMPRESSED , + +BLKDBG_VMSTATE_LOAD , +BLKDBG_VMSTATE_SAVE , + +BLKDBG_COW_READ , +BLKDBG_COW_WRITE , + +BLKDBG_REFTABLE_LOAD , +BLKDBG_REFTABLE_GROW , + +BLKDBG_REFBLOCK_LOAD , +BLKDBG_REFBLOCK_UPDATE , +BLKDBG_REFBLOCK_UPDATE_PART , +BLKDBG_REFBLOCK_ALLOC , +BLKDBG_REFBLOCK_ALLOC_HOOKUP , +BLKDBG_REFBLOCK_ALLOC_WRITE , +BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS , +BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE , +BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE , + +BLKDBG_CLUSTER_ALLOC , +BLKDBG_CLUSTER_ALLOC_BYTES , +BLKDBG_CLUSTER_FREE , +BLKDBG_EVENT_MAX , }BlkDebugEvent ;
block/blkdebug.c +42 -0
48 lines not on this page · raw message
block/qcow2-cluster.c +15 -0
@@ -54,12 +54,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)memcpy (new_l1_table, s->l1_table, s->l1_size *sizeof (uint64_t ));/* write new table (align to cluster) */ +BLKDBG_EVENT (s->hd,BLKDBG_L1_GROW_ALLOC_TABLE ); new_l1_table_offset =qcow2_alloc_clusters (bs, new_l1_size2);if (new_l1_table_offset <0 ) {qemu_free (new_l1_table);return new_l1_table_offset; } +BLKDBG_EVENT (s->hd,BLKDBG_L1_GROW_WRITE_TABLE );for (i =0 ; i < s->l1_size; i++) new_l1_table[i] =cpu_to_be64 (new_l1_table[i]); ret =bdrv_pwrite (s->hd, new_l1_table_offset, new_l1_table, new_l1_size2);
@@ -69,6 +71,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size) new_l1_table[i] =be64_to_cpu (new_l1_table[i]);/* set new table */ +BLKDBG_EVENT (s->hd,BLKDBG_L1_GROW_ACTIVATE_TABLE );cpu_to_be32w ((uint32_t *)data, new_l1_size);cpu_to_be64w ((uint64_t *)(data +4 ), new_l1_table_offset); ret =bdrv_pwrite (s->hd, offsetof(QCowHeader , l1_size), data,sizeof (data));
@@ -170,6 +173,8 @@ static uint64_t *l2_load(BlockDriverState *bs, uint64_t l2_offset) min_index =l2_cache_new_entry (bs); l2_table = s->l2_cache + (min_index << s->l2_bits); + +BLKDBG_EVENT (s->hd,BLKDBG_L2_LOAD );if (bdrv_pread (s->hd, l2_offset, l2_table, s->l2_size *sizeof (uint64_t )) != s->l2_size *sizeof (uint64_t ))return NULL ;
@@ -195,6 +200,7 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index) buf[i] =cpu_to_be64 (s->l1_table[l1_start_index + i]); } +BLKDBG_EVENT (s->hd,BLKDBG_L1_UPDATE );if (bdrv_pwrite (s->hd, s->l1_table_offset +8 * l1_start_index, buf,sizeof (buf)) !=sizeof (buf)) {
@@ -248,12 +254,14 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index)memset (l2_table,0 , s->l2_size *sizeof (uint64_t )); }else {/* if there was an old l2 table, read it from the disk */ +BLKDBG_EVENT (s->hd,BLKDBG_L2_ALLOC_COW_READ );if (bdrv_pread (s->hd, old_l2_offset, l2_table, s->l2_size *sizeof (uint64_t )) != s->l2_size *sizeof (uint64_t ))return NULL ; }/* write the l2 table to the file */ +BLKDBG_EVENT (s->hd,BLKDBG_L2_ALLOC_WRITE );if (bdrv_pwrite (s->hd, l2_offset, l2_table, s->l2_size *sizeof (uint64_t )) != s->l2_size *sizeof (uint64_t ))
@@ -335,6 +343,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,/* read from the base image */ n1 =qcow2_backing_read1 (bs->backing_hd, sector_num, buf, n);if (n1 >0 ) { +BLKDBG_EVENT (s->hd,BLKDBG_READ_BACKING ); ret =bdrv_read (bs->backing_hd, sector_num, buf, n1);if (ret <0 )return -1 ;
@@ -347,6 +356,7 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,return -1 ;memcpy (buf, s->cluster_cache + index_in_cluster *512 ,512 * n); }else { +BLKDBG_EVENT (s->hd,BLKDBG_READ ); ret =bdrv_pread (s->hd, cluster_offset + index_in_cluster *512 , buf, n *512 );if (ret != n *512 )return -1 ;
@@ -371,6 +381,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, n = n_end - n_start;if (n <=0 )return 0 ; +BLKDBG_EVENT (s->hd,BLKDBG_COW_READ ); ret =qcow_read (bs, start_sect + n_start, s->cluster_data, n);if (ret <0 )return ret;
@@ -380,6 +391,7 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect, s->cluster_data, n,1 , &s->aes_encrypt_key); } +BLKDBG_EVENT (s->hd,BLKDBG_COW_WRITE ); ret =bdrv_write (s->hd, (cluster_offset >>9 ) + n_start, s->cluster_data, n);if (ret <0 )
@@ -592,6 +604,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,/* compressed clusters never have the copied flag */ +BLKDBG_EVENT (s->hd,BLKDBG_L2_UPDATE_COMPRESSED ); l2_table[l2_index] =cpu_to_be64 (cluster_offset); if (bdrv_pwrite(s->hd, l2_offset + l2_index * sizeof(uint64_t),
@@ -615,6 +628,7 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,int end_offset = (8 * (l2_index + num) +511 ) & ~511 ;size_t len = end_offset - start_offset; +BLKDBG_EVENT (s->hd,BLKDBG_L2_UPDATE );if (bdrv_pwrite (s->hd, l2_offset + start_offset, &l2_table[l2_start_index], len) != len) {
@@ -866,6 +880,7 @@ int qcow2_decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset) nb_csectors = ((cluster_offset >> s->csize_shift) & s->csize_mask) +1 ; sector_offset = coffset &511 ; csize = nb_csectors *512 - sector_offset; +BLKDBG_EVENT (s->hd,BLKDBG_READ_COMPRESSED ); ret =bdrv_read (s->hd, coffset >>9 , s->cluster_data, nb_csectors);if (ret <0 ) {return -1 ;
block/qcow2-refcount.c +18 -0
@@ -42,6 +42,7 @@ static int write_refcount_block(BDRVQcowState *s)return 0 ; } +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_UPDATE );if (bdrv_pwrite (s->hd, s->refcount_block_cache_offset, s->refcount_block_cache, size) != size) {
@@ -63,6 +64,7 @@ int qcow2_refcount_init(BlockDriverState *bs) refcount_table_size2 = s->refcount_table_size *sizeof (uint64_t ); s->refcount_table =qemu_malloc (refcount_table_size2);if (s->refcount_table_size >0 ) { +BLKDBG_EVENT (s->hd,BLKDBG_REFTABLE_LOAD ); ret =bdrv_pread (s->hd, s->refcount_table_offset, s->refcount_table, refcount_table_size2);if (ret != refcount_table_size2)
@@ -93,6 +95,7 @@ static int load_refcount_block(BlockDriverState *bs,write_refcount_block (s); } +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_LOAD ); ret =bdrv_pread (s->hd, refcount_block_offset, s->refcount_block_cache, s->cluster_size);if (ret != s->cluster_size)
@@ -164,6 +167,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)unsigned int refcount_table_index;int ret; +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC ); +/* Find the refcount block for the given cluster */ refcount_table_index = cluster_index >> (s->cluster_bits -REFCOUNT_SHIFT );
@@ -239,6 +244,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index) }/* Now the new refcount block needs to be written to disk */ +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC_WRITE ); ret =bdrv_pwrite (s->hd, new_block, s->refcount_block_cache, s->cluster_size);if (ret <0 ) {
@@ -248,6 +254,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)/* If the refcount table is big enough, just hook the block up there */ if (refcount_table_index < s->refcount_table_size) {uint64_t data64 =cpu_to_be64 (new_block); +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC_HOOKUP ); ret =bdrv_pwrite (s->hd, s->refcount_table_offset + refcount_table_index *sizeof (uint64_t ), &data64,sizeof (data64));
@@ -270,6 +277,8 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)* refcount table at once without producing an inconsistent state in * between. */ +BLKDBG_EVENT (s->hd,BLKDBG_REFTABLE_GROW ); +/* Calculate the number of refcount blocks needed so far */ uint64_t refcount_block_clusters =1 << (s->cluster_bits -REFCOUNT_SHIFT ); uint64_t blocks_used = (s->free_cluster_index +
@@ -325,6 +334,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index) }/* Write refcount blocks to disk */ +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS ); ret =bdrv_pwrite (s->hd, meta_offset, new_blocks, blocks_clusters * s->cluster_size);qemu_free (new_blocks);
@@ -337,6 +347,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)cpu_to_be64s (&new_table[i]); } +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE ); ret =bdrv_pwrite (s->hd, table_offset, new_table, table_size *sizeof (uint64_t ));if (ret <0 ) {
@@ -351,6 +362,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)uint8_t data[12 ];cpu_to_be64w ((uint64_t *)data, table_offset);cpu_to_be32w ((uint32_t *)(data +8 ), table_clusters); +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE ); ret =bdrv_pwrite (s->hd, offsetof(QCowHeader , refcount_table_offset), data,sizeof (data));if (ret <0 ) {
@@ -400,6 +412,7 @@ static int write_refcount_block_entries(BDRVQcowState *s, & ~(REFCOUNTS_PER_SECTOR -1 ); size = (last_index - first_index) <<REFCOUNT_SHIFT ; +BLKDBG_EVENT (s->hd,BLKDBG_REFBLOCK_UPDATE_PART );if (bdrv_pwrite (s->hd, refcount_block_offset + (first_index <<REFCOUNT_SHIFT ), &s->refcount_block_cache[first_index], size) != size)
@@ -555,9 +568,11 @@ retry:int64_t qcow2_alloc_clusters (BlockDriverState *bs,int64_t size) { +BDRVQcowState *s = bs->opaque;int64_t offset;int ret; +BLKDBG_EVENT (s->hd,BLKDBG_CLUSTER_ALLOC ); offset =alloc_clusters_noref (bs, size); ret =update_refcount (bs, offset, size,1 );if (ret <0 ) {
@@ -574,6 +589,7 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)int64_t offset, cluster_offset;int free_in_cluster; +BLKDBG_EVENT (s->hd,BLKDBG_CLUSTER_ALLOC_BYTES );assert (size >0 && size <= s->cluster_size);if (s->free_byte_offset ==0 ) { s->free_byte_offset =qcow2_alloc_clusters (bs, s->cluster_size);
@@ -615,8 +631,10 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)void qcow2_free_clusters (BlockDriverState *bs,int64_t offset,int64_t size) { +BDRVQcowState *s = bs->opaque;int ret; +BLKDBG_EVENT (s->hd,BLKDBG_CLUSTER_FREE ); ret =update_refcount (bs, offset, size,-1 );if (ret <0 ) {fprintf (stderr,"qcow2_free_clusters failed: %s\n" ,strerror (-ret));
block/qcow2.c +6 -0
@@ -429,6 +429,7 @@ static void qcow_aio_read_cb(void *opaque, int ret) acb->hd_iov.iov_base = (void *)acb->buf; acb->hd_iov.iov_len = acb->cur_nr_sectors *512 ;qemu_iovec_init_external (&acb->hd_qiov, &acb->hd_iov,1 ); +BLKDBG_EVENT (s->hd,BLKDBG_READ_BACKING_AIO ); acb->hd_aiocb =bdrv_aio_readv (bs->backing_hd, acb->sector_num, &acb->hd_qiov, acb->cur_nr_sectors, qcow_aio_read_cb, acb);
@@ -464,6 +465,7 @@ static void qcow_aio_read_cb(void *opaque, int ret) acb->hd_iov.iov_base = (void *)acb->buf; acb->hd_iov.iov_len = acb->cur_nr_sectors *512 ;qemu_iovec_init_external (&acb->hd_qiov, &acb->hd_iov,1 ); +BLKDBG_EVENT (s->hd,BLKDBG_READ_AIO ); acb->hd_aiocb = bdrv_aio_readv(s->hd, (acb->cluster_offset >> 9) + index_in_cluster, &acb->hd_qiov, acb->cur_nr_sectors,
@@ -619,6 +621,7 @@ static void qcow_aio_write_cb(void *opaque, int ret) acb->hd_iov.iov_base = (void *)src_buf; acb->hd_iov.iov_len = acb->cur_nr_sectors *512 ;qemu_iovec_init_external (&acb->hd_qiov, &acb->hd_iov,1 ); +BLKDBG_EVENT (s->hd,BLKDBG_WRITE_AIO ); acb->hd_aiocb = bdrv_aio_writev(s->hd, (acb->cluster_offset >> 9) + index_in_cluster, &acb->hd_qiov, acb->cur_nr_sectors,
@@ -1141,6 +1144,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,if (!cluster_offset)return -1 ; cluster_offset &= s->cluster_offset_mask; +BLKDBG_EVENT (s->hd,BLKDBG_WRITE_COMPRESSED );if (bdrv_pwrite (s->hd, cluster_offset, out_buf, out_len) != out_len) {qemu_free (out_buf);return -1 ;
@@ -1211,6 +1215,7 @@ static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,int growable = bs->growable;int ret; +BLKDBG_EVENT (s->hd,BLKDBG_VMSTATE_SAVE ); bs->growable =1 ; ret =bdrv_pwrite (bs,qcow_vm_state_offset (s) + pos, buf, size); bs->growable = growable;
@@ -1225,6 +1230,7 @@ static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,int growable = bs->growable;int ret; +BLKDBG_EVENT (s->hd,BLKDBG_VMSTATE_LOAD ); bs->growable =1 ; ret =bdrv_pread (bs,qcow_vm_state_offset (s) + pos, buf, size); bs->growable = growable;
Signature · 1 line
1.6.6.1
PATCH 8/26 qcow2: Fix creation of large images
In reply to Kevin Wolfqcow_create2 assumes that the new image will only need one cluster for its refcount table initially. Obviously that's not true any more when the image is big enough (exact value depends on the cluster size).
This patch calculates the refcount table size dynamically.
--- block/qcow2.c | 43 +++++++++++++++++++++++++++++++++---------- 1 files changed, 33 insertions(+), 10 deletions(-)
block/qcow2.c +33 -10
@@ -850,10 +850,11 @@ static int qcow_create2(const char *filename, int64_t total_size, {int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits; -int ref_clusters, backing_format_len =0 ; +int ref_clusters, reftable_clusters, backing_format_len =0 ;int rounded_ext_bf_len =0 ;QCowHeader header;uint64_t tmp, offset; +uint64_t old_ref_clusters;QCowCreateState s1, *s = &s1;QCowExtension ext_bf = {0 ,0 };int ret;
@@ -912,17 +913,37 @@ static int qcow_create2(const char *filename, int64_t total_size, header.l1_size =cpu_to_be32 (l1_size); offset +=align_offset (l1_size *sizeof (uint64_t ), s->cluster_size); - s->refcount_table =qemu_mallocz (s->cluster_size); +/* count how many refcount blocks needed */ + +#define NUM_CLUSTERS (bytes) \ + (((bytes) + (s->cluster_size) - 1) / (s->cluster_size)) + + ref_clusters =NUM_CLUSTERS (NUM_CLUSTERS (offset) *sizeof (uint16_t )); + +do { +uint64_t image_clusters; + old_ref_clusters = ref_clusters; + +/* Number of clusters used for the refcount table */ + reftable_clusters =NUM_CLUSTERS (ref_clusters *sizeof (uint64_t )); + +/* Number of clusters that the whole image will have */ + image_clusters =NUM_CLUSTERS (offset) + ref_clusters + + reftable_clusters; + +/* Number of refcount blocks needed for the image */ + ref_clusters =NUM_CLUSTERS (image_clusters *sizeof (uint16_t )); + + }while (ref_clusters != old_ref_clusters); + + s->refcount_table =qemu_mallocz (reftable_clusters * s->cluster_size); s->refcount_table_offset = offset; header.refcount_table_offset =cpu_to_be64 (offset); - header.refcount_table_clusters =cpu_to_be32 (1 ); - offset += s->cluster_size; + header.refcount_table_clusters =cpu_to_be32 (reftable_clusters); + offset += (reftable_clusters * s->cluster_size); s->refcount_block_offset = offset; -/* count how many refcount blocks needed */ - tmp = offset >> s->cluster_bits; - ref_clusters = (tmp >> (s->cluster_bits -REFCOUNT_SHIFT )) +1 ;for (i=0 ; i < ref_clusters; i++) { s->refcount_table[i] =cpu_to_be64 (offset); offset += s->cluster_size;
@@ -934,7 +955,8 @@ static int qcow_create2(const char *filename, int64_t total_size,qcow2_create_refcount_update (s,0 , header_size);qcow2_create_refcount_update (s, s->l1_table_offset, l1_size *sizeof (uint64_t )); -qcow2_create_refcount_update (s, s->refcount_table_offset, s->cluster_size); +qcow2_create_refcount_update (s, s->refcount_table_offset, + reftable_clusters * s->cluster_size);qcow2_create_refcount_update (s, s->refcount_block_offset, ref_clusters * s->cluster_size);
@@ -986,8 +1008,9 @@ static int qcow_create2(const char *filename, int64_t total_size, } }lseek (fd, s->refcount_table_offset,SEEK_SET ); - ret =qemu_write_full (fd, s->refcount_table, s->cluster_size); -if (ret != s->cluster_size) { + ret =qemu_write_full (fd, s->refcount_table, + reftable_clusters * s->cluster_size); +if (ret != reftable_clusters * s->cluster_size) { ret = -errno; goto exit; }
Signature · 1 line
1.6.6.1
PATCH 9/26 Replace calls of old bdrv_open
In reply to Kevin WolfWhat is known today as bdrv_open2 becomes the new bdrv_open. All remaining callers of the old function are converted to the new one. In some places they even know the right format, so they should have used bdrv_open2 from the beginning.
--- block.c | 24 +++++++++--------------- block.h | 5 ++--- block/qcow2.c | 4 ++-- block/vmdk.c | 2 +- block/vvfat.c | 5 ++++- hw/xen_disk.c | 2 +- monitor.c | 2 +- qemu-img.c | 16 ++++++++-------- qemu-io.c | 2 +- qemu-nbd.c | 2 +- vl.c | 2 +- 11 files changed, 31 insertions(+), 35 deletions(-)
block.c +9 -15
@@ -338,7 +338,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)int ret; bs =bdrv_new ("" ); - ret =bdrv_open2 (bs, filename, flags |BDRV_O_FILE ,NULL ); + ret =bdrv_open (bs, filename, flags |BDRV_O_FILE ,NULL );if (ret <0 ) {bdrv_delete (bs);return ret;
@@ -348,13 +348,8 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)return 0 ; } -int bdrv_open (BlockDriverState *bs,const char *filename,int flags) -{ -return bdrv_open2 (bs, filename, flags,NULL ); -} - -int bdrv_open2 (BlockDriverState *bs,const char *filename,int flags, -BlockDriver *drv) +int bdrv_open (BlockDriverState *bs,const char *filename,int flags, +BlockDriver *drv) {int ret, open_flags;char tmp_filename[PATH_MAX ];
@@ -379,7 +374,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,/* if there is a backing file, use it */ bs1 =bdrv_new ("" ); - ret =bdrv_open2 (bs1, filename,0 , drv); + ret =bdrv_open (bs1, filename,0 , drv);if (ret <0 ) {bdrv_delete (bs1);return ret;
@@ -491,9 +486,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,/* backing files always opened read-only */ open_flags &= ~BDRV_O_RDWR ; - - ret =bdrv_open2 (bs->backing_hd, backing_filename, open_flags, - back_drv); + + ret =bdrv_open (bs->backing_hd, backing_filename, open_flags, back_drv);if (ret <0 ) {bdrv_close (bs);return ret;
@@ -605,12 +599,12 @@ int bdrv_commit(BlockDriverState *bs)bdrv_delete (bs->backing_hd); bs->backing_hd =NULL ; bs_rw =bdrv_new ("" ); - rw_ret =bdrv_open2 (bs_rw, filename, open_flags |BDRV_O_RDWR ,NULL ); + rw_ret =bdrv_open (bs_rw, filename, open_flags |BDRV_O_RDWR ,NULL );if (rw_ret <0 ) {bdrv_delete (bs_rw);/* try to re-open read-only */ bs_ro =bdrv_new ("" ); - ret =bdrv_open2 (bs_ro, filename, open_flags & ~BDRV_O_RDWR ,NULL ); + ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR ,NULL );if (ret <0 ) {bdrv_delete (bs_ro);/* drive not functional anymore */
@@ -662,7 +656,7 @@ ro_cleanup:bdrv_delete (bs->backing_hd); bs->backing_hd =NULL ; bs_ro =bdrv_new ("" ); - ret =bdrv_open2 (bs_ro, filename, open_flags & ~BDRV_O_RDWR ,NULL ); + ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR ,NULL );if (ret <0 ) {bdrv_delete (bs_ro);/* drive not functional anymore */
block.h +2 -3
@@ -68,9 +68,8 @@ int bdrv_create2(BlockDriver *drv,BlockDriverState *bdrv_new (const char *device_name);void bdrv_delete (BlockDriverState *bs);int bdrv_file_open (BlockDriverState **pbs,const char *filename,int flags); -int bdrv_open (BlockDriverState *bs,const char *filename,int flags); -int bdrv_open2 (BlockDriverState *bs,const char *filename,int flags, -BlockDriver *drv); +int bdrv_open (BlockDriverState *bs,const char *filename,int flags, +BlockDriver *drv);void bdrv_close (BlockDriverState *bs);int bdrv_check (BlockDriverState *bs); int bdrv_read(BlockDriverState *bs, int64_t sector_num,
block/qcow2.c +2 -2
@@ -52,7 +52,7 @@ typedef struct {#define QCOW_EXT_MAGIC_END 0#define QCOW_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA - +static BlockDriver bdrv_qcow2;static int qcow_probe (const uint8_t *buf,int buf_size,const char *filename) {
@@ -1033,7 +1033,7 @@ exit:if (ret ==0 && prealloc) {BlockDriverState *bs; bs =bdrv_new ("" ); -bdrv_open (bs, filename,BDRV_O_CACHE_WB |BDRV_O_RDWR ); +bdrv_open (bs, filename,BDRV_O_CACHE_WB |BDRV_O_RDWR , &bdrv_qcow2);preallocate (bs);bdrv_close (bs); }
block/vmdk.c +1 -1
@@ -390,7 +390,7 @@ static int vmdk_parent_open(BlockDriverState *bs, const char * filename)return -1 ; } parent_open =1 ; -if (bdrv_open (bs->backing_hd, parent_img_name,0 ) <0 ) +if (bdrv_open (bs->backing_hd, parent_img_name,0 ,NULL ) <0 ) goto failure; parent_open =0 ; }
block/vvfat.c +4 -1
@@ -2795,8 +2795,11 @@ static int enable_write_target(BDRVVVFATState *s)if (bdrv_create (bdrv_qcow, s->qcow_filename, options) <0 )return -1 ; s->qcow =bdrv_new ("" ); -if (s->qcow ==NULL ||bdrv_open (s->qcow, s->qcow_filename,BDRV_O_RDWR ) <0 ) +if (s->qcow ==NULL || +bdrv_open (s->qcow, s->qcow_filename,BDRV_O_RDWR , bdrv_qcow) <0 ) + {return -1 ; + }#ifndef _WIN32unlink (s->qcow_filename);
hw/xen_disk.c +1 -1
@@ -629,7 +629,7 @@ static int blk_init(struct XenDevice *xendev)xen_be_printf (&blkdev->xendev,2 ,"create new bdrv (xenbus setup)\n" ); blkdev->bs =bdrv_new (blkdev->dev);if (blkdev->bs) { -if (bdrv_open2 (blkdev->bs, blkdev->filename, qflags, +if (bdrv_open (blkdev->bs, blkdev->filename, qflags,bdrv_find_whitelisted_format (blkdev->fileproto)) !=0 ) {bdrv_delete (blkdev->bs);
monitor.c +1 -1
@@ -1099,7 +1099,7 @@ static int do_change_block(Monitor *mon, const char *device,if (eject_device (mon, bs,0 ) <0 ) {return -1 ; } -if (bdrv_open2 (bs, filename,BDRV_O_RDWR , drv) <0 ) { +if (bdrv_open (bs, filename,BDRV_O_RDWR , drv) <0 ) {qerror_report (QERR_OPEN_FILE_FAILED , filename);return -1 ; }
qemu-img.c +8 -8
@@ -210,7 +210,7 @@ static BlockDriverState *bdrv_new_open(const char *filename,if (!readonly) { flags |=BDRV_O_RDWR ; } -if (bdrv_open2 (bs, filename, flags, drv) <0 ) { +if (bdrv_open (bs, filename, flags, drv) <0 ) {error ("Could not open '%s'" , filename); }if (bdrv_is_encrypted (bs)) {
@@ -415,7 +415,7 @@ static int img_check(int argc, char **argv) }else { drv =NULL ; } -if (bdrv_open2 (bs, filename,BRDV_O_FLAGS , drv) <0 ) { +if (bdrv_open (bs, filename,BRDV_O_FLAGS , drv) <0 ) {error ("Could not open '%s'" , filename); } ret =bdrv_check (bs);
@@ -474,7 +474,7 @@ static int img_commit(int argc, char **argv) }else { drv =NULL ; } -if (bdrv_open2 (bs, filename,BRDV_O_FLAGS |BDRV_O_RDWR , drv) <0 ) { +if (bdrv_open (bs, filename,BRDV_O_FLAGS |BDRV_O_RDWR , drv) <0 ) {error ("Could not open '%s'" , filename); } ret =bdrv_commit (bs);
@@ -926,7 +926,7 @@ static int img_info(int argc, char **argv) }else { drv =NULL ; } -if (bdrv_open2 (bs, filename,BRDV_O_FLAGS |BDRV_O_NO_BACKING , drv) <0 ) { +if (bdrv_open (bs, filename,BRDV_O_FLAGS |BDRV_O_NO_BACKING , drv) <0 ) {error ("Could not open '%s'" , filename); }bdrv_get_format (bs, fmt_name,sizeof (fmt_name));
@@ -1032,7 +1032,7 @@ static int img_snapshot(int argc, char **argv)if (!bs)error ("Not enough memory" ); -if (bdrv_open2 (bs, filename, bdrv_oflags,NULL ) <0 ) { +if (bdrv_open (bs, filename, bdrv_oflags,NULL ) <0 ) {error ("Could not open '%s'" , filename); }
@@ -1137,7 +1137,7 @@ static int img_rebase(int argc, char **argv) } flags =BRDV_O_FLAGS |BDRV_O_RDWR | (unsafe ?BDRV_O_NO_BACKING :0 ); -if (bdrv_open2 (bs, filename, flags, drv) <0 ) { +if (bdrv_open (bs, filename, flags, drv) <0 ) {error ("Could not open '%s'" , filename); }
@@ -1169,7 +1169,7 @@ static int img_rebase(int argc, char **argv) bs_old_backing =bdrv_new ("old_backing" );bdrv_get_backing_filename (bs, backing_name,sizeof (backing_name)); -if (bdrv_open2 (bs_old_backing, backing_name,BRDV_O_FLAGS , +if (bdrv_open (bs_old_backing, backing_name,BRDV_O_FLAGS , old_backing_drv)) {error ("Could not open old backing file '%s'" , backing_name);
@@ -1177,7 +1177,7 @@ static int img_rebase(int argc, char **argv) } bs_new_backing =bdrv_new ("new_backing" ); -if (bdrv_open2 (bs_new_backing, out_baseimg,BRDV_O_FLAGS |BDRV_O_RDWR , +if (bdrv_open (bs_new_backing, out_baseimg,BRDV_O_FLAGS |BDRV_O_RDWR , new_backing_drv)) {error ("Could not open new backing file '%s'" , out_baseimg);
qemu-io.c +1 -1
@@ -1284,7 +1284,7 @@ static int openfile(char *name, int flags, int growable) flags |=BDRV_O_FILE ; } -if (bdrv_open (bs, name, flags) <0 ) { +if (bdrv_open (bs, name, flags,NULL ) <0 ) {fprintf (stderr,"%s: can't open device %s\n" , progname, name); bs =NULL ;return 1 ;
qemu-nbd.c +1 -1
@@ -333,7 +333,7 @@ int main(int argc, char **argv)if (bs ==NULL )return 1 ; -if (bdrv_open (bs, argv[optind], flags) <0 ) +if (bdrv_open (bs, argv[optind], flags,NULL ) <0 )return 1 ; fd_size = bs->total_sectors *512 ;
vl.c +1 -1
@@ -1129,7 +1129,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, bdrv_flags |= ro ?0 :BDRV_O_RDWR ; -if (bdrv_open2 (dinfo->bdrv, file, bdrv_flags, drv) <0 ) { +if (bdrv_open (dinfo->bdrv, file, bdrv_flags, drv) <0 ) {fprintf (stderr,"qemu: could not open disk image %s: %s\n" , file,strerror (errno));return NULL ;
Signature · 1 line
1.6.6.1
PATCH 10/26 block: get rid of the BDRV_O_FILE flag
In reply to Kevin WolfFrom: Christoph Hellwig <[email protected]>
BDRV_O_FILE is only used to communicate between bdrv_file_open and bdrv_open. It affects two things: first bdrv_open only searches for protocols using find_protocol instead of all image formats and host drivers. We can easily move that to the caller and pass the found driver to bdrv_open. Second it is used to not force a read-write open of a snapshot file. But we never use bdrv_file_open to open snapshots and this behaviour doesn't make sense to start with.
qemu-io abused the BDRV_O_FILE for it's growable option, switch it to using bdrv_file_open to make sure we only open files as growable were we can actually support that.
This patch requires Kevin's "[PATCH] Replace calls of old bdrv_open" to be applied first.
--- block.c | 19 +++++++++++-------- block.h | 4 ---- qemu-io.c | 28 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 26 deletions(-)
block.c +11 -8
@@ -335,10 +335,16 @@ static BlockDriver *find_image_format(const char *filename)int bdrv_file_open (BlockDriverState **pbs,const char *filename,int flags) {BlockDriverState *bs; +BlockDriver *drv;int ret; + drv =find_protocol (filename); +if (!drv) { +return -ENOENT ; + } + bs =bdrv_new ("" ); - ret =bdrv_open (bs, filename, flags |BDRV_O_FILE ,NULL ); + ret =bdrv_open (bs, filename, flags, drv);if (ret <0 ) {bdrv_delete (bs);return ret;
@@ -416,9 +422,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, }pstrcpy (bs->filename,sizeof (bs->filename), filename); -if (flags &BDRV_O_FILE ) { - drv =find_protocol (filename); - }else if (!drv) { + +if (!drv) { drv =find_hdev_driver (filename);if (!drv) { drv =find_image_format (filename);
@@ -450,14 +455,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,* Clear flags that are internal to the block layer before opening the * image. */ - open_flags = flags & ~(BDRV_O_FILE |BDRV_O_SNAPSHOT |BDRV_O_NO_BACKING ); + open_flags = flags & ~(BDRV_O_SNAPSHOT |BDRV_O_NO_BACKING );/* * Snapshots should be writeable. -* -* XXX(hch): and what is the point of a snapshot during a read-only open? */ -if (!(flags &BDRV_O_FILE ) && bs->is_temporary) { +if (bs->is_temporary) { open_flags |=BDRV_O_RDWR ; }
block.h +0 -4
@@ -29,10 +29,6 @@ typedef struct QEMUSnapshotInfo {#define BDRV_O_RDWR 0x0002#define BDRV_O_SNAPSHOT 0x0008/* open the file read only and save writes in a snapshot */ -#define BDRV_O_FILE 0x0010/* open as a raw file (do not try to -use a disk image format on top of -it (default for -bdrv_file_open()) */ #define BDRV_O_NOCACHE 0x0020/* do not use the host page cache */ #define BDRV_O_CACHE_WB 0x0040/* use write-back caching */ #define BDRV_O_NATIVE_AIO 0x0080/* use native AIO instead of the thread pool */
qemu-io.c +14 -14
@@ -1276,23 +1276,23 @@ static int openfile(char *name, int flags, int growable)return 1 ; } - bs =bdrv_new ("hda" ); -if (!bs) -return 1 ; -if (growable) { - flags |=BDRV_O_FILE ; - } - -if (bdrv_open (bs, name, flags,NULL ) <0 ) { -fprintf (stderr,"%s: can't open device %s\n" , progname, name); - bs =NULL ; -return 1 ; +if (bdrv_file_open (&bs, name, flags)) { +fprintf (stderr,"%s: can't open device %s\n" , progname, name); +return 1 ; + } + }else { + bs =bdrv_new ("hda" ); +if (!bs) +return 1 ; + +if (bdrv_open (bs, name, flags,NULL ) <0 ) { +fprintf (stderr,"%s: can't open device %s\n" , progname, name); + bs =NULL ; +return 1 ; + } } -if (growable) { - bs->growable =1 ; - }return 0 ; }
Signature · 1 line
1.6.6.1
PATCH 11/26 block: split raw_getlength
In reply to Kevin WolfFrom: Christoph Hellwig <[email protected]>
Split up the raw_getlength into separate generic, solaris and BSD versions to reduce the ifdef maze a bit. The BSD variant still is a complete maze, but to clean it up properly we'd need some people using the BSD variants to figure out what code is used for what variant.
--- block/raw-posix.c | 65 ++++++++++++++++++++++++++++++++++------------------ 1 files changed, 42 insertions(+), 23 deletions(-)
block/raw-posix.c +42 -23
@@ -627,29 +627,48 @@ static int64_t raw_getlength(BlockDriverState *bs) } elsereturn st.st_size; } -#else /* !__OpenBSD__ */ -static int64_t raw_getlength (BlockDriverState *bs) +#elif defined(__sun__) +static int64_t raw_getlength (BlockDriverState *bs) +{ +BDRVRawState *s = bs->opaque; +struct dk_minfo minfo; +int ret; + + ret =fd_open (bs); +if (ret <0 ) { +return ret; + } + +/* +* Use the DKIOCGMEDIAINFO ioctl to read the size. +*/ + ret =ioctl (s->fd,DKIOCGMEDIAINFO , &minfo); +if (ret !=-1 ) { +return minfo.dki_lbsize * minfo.dki_capacity; + } + +/* +* There are reports that lseek on some devices fails, but +* irc discussion said that contingency on contingency was overkill. +*/ +return lseek (s->fd,0 ,SEEK_END ); +} +#elif defined(CONFIG_BSD) +static int64_t raw_getlength (BlockDriverState *bs) {BDRVRawState *s = bs->opaque;int fd = s->fd;int64_t size; -#ifdef CONFIG_BSD struct stat sb;#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)int reopened =0 ;#endif -#endif -#ifdef __sun__ -struct dk_minfo minfo; -int rv; -#endif int ret; ret =fd_open (bs);if (ret <0 )return ret; -#ifdef CONFIG_BSD #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) again: #endif
@@ -684,24 +703,24 @@ again: } } #endif - } else -#endif -#ifdef __sun__ -/* -* use the DKIOCGMEDIAINFO ioctl to read the size. -*/ - rv =ioctl ( fd,DKIOCGMEDIAINFO , &minfo ); -if ( rv !=-1 ) { - size = minfo.dki_lbsize * minfo.dki_capacity; - } else /* there are reports that lseek on some devices -fails, but irc discussion said that contingency -on contingency was overkill */ -#endif - { + } else { size =lseek (fd,0 ,SEEK_END ); }return size; } +#else +static int64_t raw_getlength (BlockDriverState *bs) +{ +BDRVRawState *s = bs->opaque; +int ret; + + ret =fd_open (bs); +if (ret <0 ) { +return ret; + } + +return lseek (s->fd,0 ,SEEK_END ); +}#endif static int raw_create (const char *filename,QEMUOptionParameter *options)
Signature · 1 line
1.6.6.1
PATCH 12/26 qcow2: Return 0/-errno in write_l2_entries
In reply to Kevin WolfChange write_l2_entries to return the real error code instead of -1.
--- block/qcow2-cluster.c | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-)
block/qcow2-cluster.c +5 -4
@@ -627,12 +627,13 @@ static int write_l2_entries(BDRVQcowState *s, uint64_t *l2_table,int start_offset = (8 * l2_index) & ~511 ;int end_offset = (8 * (l2_index + num) +511 ) & ~511 ;size_t len = end_offset - start_offset; +int ret;BLKDBG_EVENT (s->hd,BLKDBG_L2_UPDATE ); -if (bdrv_pwrite (s->hd, l2_offset + start_offset, &l2_table[l2_start_index], - len) != len) - { -return -1 ; + ret =bdrv_pwrite (s->hd, l2_offset + start_offset, + &l2_table[l2_start_index], len); +if (ret <0 ) { +return ret; }return 0 ;
Signature · 1 line
1.6.6.1
PATCH 13/26 qcow2: Fix error return code in qcow2_alloc_cluster_link_l2
In reply to Kevin WolfFix qcow2_alloc_cluster_link_l2 to return the real error code like it does in all other error cases.
--- block/qcow2-cluster.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
block/qcow2-cluster.c +2 -2
@@ -687,8 +687,8 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) (i << s->cluster_bits)) | QCOW_OFLAG_COPIED); } -if (write_l2_entries (s, l2_table, l2_offset, l2_index, m->nb_clusters) <0 ) { - ret =-1 ; + ret =write_l2_entries (s, l2_table, l2_offset, l2_index, m->nb_clusters); +if (ret <0 ) { goto err; }
Signature · 1 line
1.6.6.1
PATCH 14/26 qcow2: Return 0/-errno in write_l1_entry
In reply to Kevin WolfChange write_l1_entry to return the real error code instead of -1.
--- block/qcow2-cluster.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-)
block/qcow2-cluster.c +5 -5
@@ -193,7 +193,7 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index) {uint64_t buf[L1_ENTRIES_PER_SECTOR ];int l1_start_index; -int i; +int i, ret; l1_start_index = l1_index & ~(L1_ENTRIES_PER_SECTOR -1 );for (i =0 ; i <L1_ENTRIES_PER_SECTOR ; i++) {
@@ -201,10 +201,10 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index) }BLKDBG_EVENT (s->hd,BLKDBG_L1_UPDATE ); -if (bdrv_pwrite (s->hd, s->l1_table_offset +8 * l1_start_index, - buf,sizeof (buf)) !=sizeof (buf)) - { -return -1 ; + ret =bdrv_pwrite (s->hd, s->l1_table_offset +8 * l1_start_index, + buf,sizeof (buf)); +if (ret <0 ) { +return ret; }return 0 ;
Signature · 1 line
1.6.6.1
PATCH 15/26 qcow2: Return 0/-errno in l2_allocate
In reply to Kevin WolfReturning NULL on error doesn't allow distinguishing between different errors. Change the interface to return an integer for -errno.
--- block/qcow2-cluster.c | 40 +++++++++++++++++++++++----------------- 1 files changed, 23 insertions(+), 17 deletions(-)
block/qcow2-cluster.c +23 -17
@@ -220,13 +220,14 @@ static int write_l1_entry(BDRVQcowState *s, int l1_index)* */ -static uint64_t *l2_allocate (BlockDriverState *bs,int l1_index) +static int l2_allocate (BlockDriverState *bs,int l1_index,uint64_t **table) {BDRVQcowState *s = bs->opaque;int min_index;uint64_t old_l2_offset;uint64_t *l2_table;int64_t l2_offset; +int ret; old_l2_offset = s->l1_table[l1_index];
@@ -234,14 +235,15 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index) l2_offset =qcow2_alloc_clusters (bs, s->l2_size *sizeof (uint64_t ));if (l2_offset <0 ) { -return NULL ; +return l2_offset; }/* update the L1 entry */ s->l1_table[l1_index] = l2_offset |QCOW_OFLAG_COPIED ; -if (write_l1_entry (s, l1_index) <0 ) { -return NULL ; + ret =write_l1_entry (s, l1_index); +if (ret <0 ) { +return ret; }/* allocate a new entry in the l2 cache */
@@ -255,24 +257,27 @@ static uint64_t *l2_allocate(BlockDriverState *bs, int l1_index) }else {/* if there was an old l2 table, read it from the disk */ BLKDBG_EVENT (s->hd,BLKDBG_L2_ALLOC_COW_READ ); -if (bdrv_pread (s->hd, old_l2_offset, - l2_table, s->l2_size *sizeof (uint64_t )) != - s->l2_size *sizeof (uint64_t )) -return NULL ; + ret =bdrv_pread (s->hd, old_l2_offset, l2_table, + s->l2_size *sizeof (uint64_t )); +if (ret <0 ) { +return ret; + } }/* write the l2 table to the file */ BLKDBG_EVENT (s->hd,BLKDBG_L2_ALLOC_WRITE ); -if (bdrv_pwrite (s->hd, l2_offset, - l2_table, s->l2_size *sizeof (uint64_t )) != - s->l2_size *sizeof (uint64_t )) -return NULL ; + ret =bdrv_pwrite (s->hd, l2_offset, l2_table, + s->l2_size *sizeof (uint64_t )); +if (ret <0 ) { +return ret; + }/* update the l2 cache entry */ s->l2_cache_offsets[min_index] = l2_offset; s->l2_cache_counts[min_index] =1 ; -return l2_table; + *table = l2_table; +return 0 ; } static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
@@ -510,7 +515,8 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset, {BDRVQcowState *s = bs->opaque;unsigned int l1_index, l2_index; -uint64_t l2_offset, *l2_table; +uint64_t l2_offset; +uint64_t *l2_table =NULL ;int ret;/* seek the the l2 offset in the l1 table */
@@ -536,9 +542,9 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset, }else {if (l2_offset)qcow2_free_clusters (bs, l2_offset, s->l2_size *sizeof (uint64_t )); - l2_table =l2_allocate (bs, l1_index); -if (l2_table ==NULL ) { -return -EIO ; + ret =l2_allocate (bs, l1_index, &l2_table); +if (ret <0 ) { +return ret; } l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED ; }
Signature · 1 line
1.6.6.1
PATCH 16/26 cleanup block driver option handling in vl.c
In reply to Kevin WolfFrom: Christoph Hellwig <[email protected]>
Assign directly to the bdrv_flags variable instead of using magic numbers before translating to the BDRV_O_* options.
--- vl.c | 45 ++++++++++++++++----------------------------- 1 files changed, 16 insertions(+), 29 deletions(-)
vl.c +16 -29
@@ -783,10 +783,8 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,QEMUMachine *machine = opaque;int max_devs;int index; -int cache; -int aio =0 ;int ro =0 ; -int bdrv_flags; +int bdrv_flags =0 ;int on_read_error, on_write_error;const char *devaddr;DriveInfo *dinfo;
@@ -795,7 +793,6 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, *fatal_error =1 ; translation =BIOS_ATA_TRANSLATION_AUTO ; - cache =1 ;if (machine && machine->use_scsi) { type =IF_SCSI ;
@@ -909,13 +906,13 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, }if ((buf =qemu_opt_get (opts,"cache" )) !=NULL ) { -if (!strcmp (buf,"off" ) || !strcmp (buf,"none" )) - cache =0 ; -else if (!strcmp (buf,"writethrough" )) - cache =1 ; -else if (!strcmp (buf,"writeback" )) - cache =2 ; -else { +if (!strcmp (buf,"off" ) || !strcmp (buf,"none" )) { + bdrv_flags |=BDRV_O_NOCACHE ; + }else if (!strcmp (buf,"writeback" )) { + bdrv_flags |=BDRV_O_CACHE_WB ; + }else if (!strcmp (buf,"writethrough" )) { +/* this is the default */ + }else {fprintf (stderr,"qemu: invalid cache option\n" );return NULL ; }
@@ -923,11 +920,11 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,#ifdef CONFIG_LINUX_AIO if ((buf =qemu_opt_get (opts,"aio" )) !=NULL ) { -if (!strcmp (buf,"threads" )) - aio =0 ; -else if (!strcmp (buf,"native" )) - aio =1 ; -else { +if (!strcmp (buf,"native" )) { + bdrv_flags |=BDRV_O_NATIVE_AIO ; + }else if (!strcmp (buf,"threads" )) { +/* this is the default */ + }else {fprintf (stderr,"qemu: invalid aio option\n" );return NULL ; }
@@ -1101,20 +1098,10 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque, *fatal_error =0 ;return NULL ; } - bdrv_flags =0 ;if (snapshot) { - bdrv_flags |=BDRV_O_SNAPSHOT ; - cache =2 ;/* always use write-back with snapshot */ - } -if (cache ==0 )/* no caching */ - bdrv_flags |=BDRV_O_NOCACHE ; -else if (cache ==2 )/* write-back */ - bdrv_flags |=BDRV_O_CACHE_WB ; - -if (aio ==1 ) { - bdrv_flags |=BDRV_O_NATIVE_AIO ; - }else { - bdrv_flags &= ~BDRV_O_NATIVE_AIO ; +/* always use write-back with snapshot */ + bdrv_flags &= ~BDRV_O_CACHE_MASK ; + bdrv_flags |= (BDRV_O_SNAPSHOT |BDRV_O_CACHE_WB ); }if (media ==MEDIA_CDROM ) {
Signature · 1 line
1.6.6.1
PATCH 17/26 block: Do not export bdrv_first
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
The bdrv_first linked list of BlockDriverStates is currently extern so that block migration can iterate the list. However, since there is already a bdrv_iterate() function there is no need to expose bdrv_first.
--- block-migration.c | 63 +++++++++++++++++++++++++++------------------------- block.c | 2 +- block_int.h | 2 - 3 files changed, 34 insertions(+), 33 deletions(-)
block-migration.c +33 -30
@@ -230,12 +230,42 @@ static void set_dirty_tracking(int enable) } } -static void init_blk_migration (Monitor *mon,QEMUFile *f) +static void init_blk_migration_it (void *opaque,BlockDriverState *bs) { +Monitor *mon = opaque;BlkMigDevState *bmds; -BlockDriverState *bs;int64_t sectors; +if (bs->type ==BDRV_TYPE_HD ) { + sectors =bdrv_getlength (bs) >>BDRV_SECTOR_BITS ; +if (sectors ==0 ) { +return ; + } + + bmds =qemu_mallocz (sizeof (BlkMigDevState)); + bmds->bs = bs; + bmds->bulk_completed =0 ; + bmds->total_sectors = sectors; + bmds->completed_sectors =0 ; + bmds->shared_base = block_mig_state.shared_base; + + block_mig_state.total_sector_sum += sectors; + +if (bmds->shared_base) { +monitor_printf (mon,"Start migration for %s with shared base " +"image\n" , + bs->device_name); + }else { +monitor_printf (mon,"Start full migration for %s\n" , + bs->device_name); + } + +QSIMPLEQ_INSERT_TAIL (&block_mig_state.bmds_list, bmds, entry); + } +} + +static void init_blk_migration (Monitor *mon,QEMUFile *f) +{ block_mig_state.submitted =0 ; block_mig_state.read_done =0 ; block_mig_state.transferred =0 ;
@@ -245,34 +275,7 @@ static void init_blk_migration(Monitor *mon, QEMUFile *f) block_mig_state.total_time =0 ; block_mig_state.reads =0 ; -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { -if (bs->type ==BDRV_TYPE_HD ) { - sectors =bdrv_getlength (bs) >>BDRV_SECTOR_BITS ; -if (sectors ==0 ) { -continue ; - } - - bmds =qemu_mallocz (sizeof (BlkMigDevState)); - bmds->bs = bs; - bmds->bulk_completed =0 ; - bmds->total_sectors = sectors; - bmds->completed_sectors =0 ; - bmds->shared_base = block_mig_state.shared_base; - - block_mig_state.total_sector_sum += sectors; - -if (bmds->shared_base) { -monitor_printf (mon,"Start migration for %s with shared base " -"image\n" , - bs->device_name); - }else { -monitor_printf (mon,"Start full migration for %s\n" , - bs->device_name); - } - -QSIMPLEQ_INSERT_TAIL (&block_mig_state.bmds_list, bmds, entry); - } - } +bdrv_iterate (init_blk_migration_it, mon); }static int blk_mig_save_bulked_block (Monitor *mon,QEMUFile *f)
block.c +1 -1
@@ -55,7 +55,7 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,static int bdrv_write_em (BlockDriverState *bs,int64_t sector_num,const uint8_t *buf,int nb_sectors); -BlockDriverState *bdrv_first; +static BlockDriverState *bdrv_first;static BlockDriver *first_drv;
block_int.h +0 -2
@@ -200,8 +200,6 @@ void qemu_aio_release(void *p);void *qemu_blockalign (BlockDriverState *bs,size_t size); -extern BlockDriverState *bdrv_first; -#ifdef _WIN32int is_windows_drive (const char *filename);#endif
Signature · 1 line
1.6.6.1
PATCH 18/26 block: Convert bdrv_first to QTAILQ
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
--- block.c | 41 +++++++++++++++++++---------------------- block_int.h | 3 ++- 2 files changed, 21 insertions(+), 23 deletions(-)
block.c +19 -22
@@ -55,7 +55,8 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,static int bdrv_write_em (BlockDriverState *bs,int64_t sector_num,const uint8_t *buf,int nb_sectors); -static BlockDriverState *bdrv_first; +static QTAILQ_HEAD(, BlockDriverState) bdrv_states = +QTAILQ_HEAD_INITIALIZER (bdrv_states);static BlockDriver *first_drv;
@@ -148,16 +149,12 @@ void bdrv_register(BlockDriver *bdrv)/* create a new block device (by default it is empty) */ BlockDriverState *bdrv_new (const char *device_name) { -BlockDriverState **pbs, *bs; +BlockDriverState *bs; bs =qemu_mallocz (sizeof (BlockDriverState));pstrcpy (bs->device_name,sizeof (bs->device_name), device_name);if (device_name[0 ] !='\0' ) { -/* insert at the end */ - pbs = &bdrv_first; -while (*pbs !=NULL ) - pbs = &(*pbs)->next; - *pbs = bs; +QTAILQ_INSERT_TAIL (&bdrv_states, bs, list); }return bs; }
@@ -545,13 +542,10 @@ void bdrv_close(BlockDriverState *bs)void bdrv_delete (BlockDriverState *bs) { -BlockDriverState **pbs; - - pbs = &bdrv_first; -while (*pbs != bs && *pbs !=NULL ) - pbs = &(*pbs)->next; -if (*pbs == bs) - *pbs = bs->next; +/* remove from list, if necessary */ +if (bs->device_name[0 ] !='\0' ) { +QTAILQ_REMOVE (&bdrv_states, bs, list); + }bdrv_close (bs);qemu_free (bs);
@@ -1172,9 +1166,10 @@ BlockDriverState *bdrv_find(const char *name) {BlockDriverState *bs; -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { -if (!strcmp (name, bs->device_name)) + QTAILQ_FOREACH(bs, &bdrv_states, list) { +if (!strcmp (name, bs->device_name)) {return bs; + } }return NULL ; }
@@ -1183,7 +1178,7 @@ void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque) {BlockDriverState *bs; -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { + QTAILQ_FOREACH(bs, &bdrv_states, list) {it (opaque, bs); } }
@@ -1203,10 +1198,12 @@ void bdrv_flush_all(void) {BlockDriverState *bs; -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) -if (bs->drv && !bdrv_is_read_only (bs) && - (!bdrv_is_removable (bs) ||bdrv_is_inserted (bs))) + QTAILQ_FOREACH(bs, &bdrv_states, list) { +if (bs->drv && !bdrv_is_read_only (bs) && + (!bdrv_is_removable (bs) ||bdrv_is_inserted (bs))) {bdrv_flush (bs); + } + } }/*
@@ -1340,7 +1337,7 @@ void bdrv_info(Monitor *mon, QObject **ret_data) bs_list =qlist_new (); -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { + QTAILQ_FOREACH(bs, &bdrv_states, list) {QObject *bs_obj;const char *type ="unknown" ;
@@ -1445,7 +1442,7 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data) devices =qlist_new (); -for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { + QTAILQ_FOREACH(bs, &bdrv_states, list) { obj =qobject_from_jsonf ("{ 'device': %s, 'stats': {" "'rd_bytes': %" PRId64"," "'wr_bytes': %" PRId64 ","
block_int.h +2 -1
@@ -26,6 +26,7 @@#include "block.h" #include "qemu-option.h" +#include "qemu-queue.h" #define BLOCK_FLAG_ENCRYPT 1#define BLOCK_FLAG_COMPRESS 2
@@ -180,7 +181,7 @@ struct BlockDriverState {char device_name[32 ];unsigned long *dirty_bitmap;int64_t dirty_count; -BlockDriverState *next; +QTAILQ_ENTRY (BlockDriverState) list;void *private; };
Signature · 1 line
1.6.6.1
PATCH 19/26 Remove un-needed code
In reply to Kevin WolfFrom: Bruce Rogers <[email protected]>
The bdrv_set_geometry_hint call below is not needed - it's just setting what was just read.
--- hw/virtio-blk.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
hw/virtio-blk.c +0 -1
@@ -494,7 +494,6 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf) s->rq =NULL ; s->sector_mask = (s->conf->logical_block_size /512 ) -1 ;bdrv_guess_geometry (s->bs, &cylinders, &heads, &secs); -bdrv_set_geometry_hint (s->bs, cylinders, heads, secs); s->vq =virtio_add_queue (&s->vdev,128 , virtio_blk_handle_output);
Signature · 1 line
1.6.6.1
PATCH 20/26 block.h: bdrv_create2 doesn't exist any more
In reply to Kevin WolfThe bdrv_create2 implementation has disappeared long ago. Remove its prototype from the header file, too.
--- block.h | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
block.h +0 -4
@@ -57,10 +57,6 @@ BlockDriver *bdrv_find_format(const char *format_name);BlockDriver *bdrv_find_whitelisted_format (const char *format_name);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, -int flags);BlockDriverState *bdrv_new (const char *device_name);void bdrv_delete (BlockDriverState *bs);int bdrv_file_open (BlockDriverState **pbs,const char *filename,int flags);
Signature · 1 line
1.6.6.1
PATCH 21/26 block: Convert first_drv to QLIST
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
--- block.c | 22 ++++++++++++---------- block_int.h | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-)
block.c +12 -10
@@ -58,7 +58,8 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num, static QTAILQ_HEAD(, BlockDriverState) bdrv_states =QTAILQ_HEAD_INITIALIZER (bdrv_states); -static BlockDriver *first_drv; +static QLIST_HEAD(, BlockDriver) bdrv_drivers = +QLIST_HEAD_INITIALIZER (bdrv_drivers);/* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist;
@@ -142,8 +143,7 @@ void bdrv_register(BlockDriver *bdrv)if (!bdrv->bdrv_aio_flush) bdrv->bdrv_aio_flush = bdrv_aio_flush_em; - bdrv->next = first_drv; - first_drv = bdrv; +QLIST_INSERT_HEAD (&bdrv_drivers, bdrv, list); }/* create a new block device (by default it is empty) */
@@ -162,9 +162,10 @@ BlockDriverState *bdrv_new(const char *device_name)BlockDriver *bdrv_find_format (const char *format_name) {BlockDriver *drv1; -for (drv1 = first_drv; drv1 !=NULL ; drv1 = drv1->next) { -if (!strcmp (drv1->format_name, format_name)) + QLIST_FOREACH(drv1, &bdrv_drivers, list) { +if (!strcmp (drv1->format_name, format_name)) {return drv1; + } }return NULL ; }
@@ -265,10 +266,11 @@ static BlockDriver *find_protocol(const char *filename) len =sizeof (protocol) -1 ;memcpy (protocol, filename, len); protocol[len] ='\0' ; -for (drv1 = first_drv; drv1 !=NULL ; drv1 = drv1->next) { + QLIST_FOREACH(drv1, &bdrv_drivers, list) {if (drv1->protocol_name && - !strcmp (drv1->protocol_name, protocol)) + !strcmp (drv1->protocol_name, protocol)) {return drv1; + } }return NULL ; }
@@ -282,7 +284,7 @@ static BlockDriver *find_hdev_driver(const char *filename)int score_max =0 , score;BlockDriver *drv =NULL , *d; -for (d = first_drv; d; d = d->next) { + QLIST_FOREACH(d, &bdrv_drivers, list) {if (d->bdrv_probe_device) { score = d->bdrv_probe_device (filename);if (score > score_max) {
@@ -317,7 +319,7 @@ static BlockDriver *find_image_format(const char *filename) } score_max =0 ; -for (drv1 = first_drv; drv1 !=NULL ; drv1 = drv1->next) { + QLIST_FOREACH(drv1, &bdrv_drivers, list) {if (drv1->bdrv_probe) { score = drv1->bdrv_probe (buf, ret, filename);if (score > score_max) {
@@ -1157,7 +1159,7 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name), {BlockDriver *drv; -for (drv = first_drv; drv !=NULL ; drv = drv->next) { + QLIST_FOREACH(drv, &bdrv_drivers, list) {it (opaque, drv->format_name); } }
block_int.h +1 -1
@@ -126,7 +126,7 @@ struct BlockDriver {/* Set if newly created images are not guaranteed to contain only zeros */ int no_zero_init; -struct BlockDriver *next; +QLIST_ENTRY (BlockDriver) list; };struct BlockDriverState {
Signature · 1 line
1.6.6.1
PATCH 22/26 qemu-img: Eliminate bdrv_new_open() code duplication
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
Several commands have code to create a BlockDriverState and open a file. The bdrv_new_open() function can be used to perform these steps. This patch converts the qemu-img commands to actually use bdrv_new_open().
Replaced the bdrv_new_open() 'readonly' argument with bdrv_open()-style flags to support generic flags like BDRV_O_NO_BACKING.
--- qemu-img.c | 83 +++++++---------------------------------------------------- 1 files changed, 10 insertions(+), 73 deletions(-)
qemu-img.c +10 -73
@@ -190,12 +190,11 @@ static int read_password(char *buf, int buf_size)static BlockDriverState *bdrv_new_open (const char *filename,const char *fmt, -int readonly) +int flags) {BlockDriverState *bs;BlockDriver *drv;char password[256 ]; -int flags =BRDV_O_FLAGS ; bs =bdrv_new ("" );if (!bs)
@@ -207,9 +206,6 @@ static BlockDriverState *bdrv_new_open(const char *filename, }else { drv =NULL ; } -if (!readonly) { - flags |=BDRV_O_RDWR ; - }if (bdrv_open (bs, filename, flags, drv) <0 ) {error ("Could not open '%s'" , filename); }
@@ -349,7 +345,7 @@ static int img_create(int argc, char **argv) } } - bs =bdrv_new_open (backing_file->value.s, fmt,1 ); + bs =bdrv_new_open (backing_file->value.s, fmt,BRDV_O_FLAGS );bdrv_get_geometry (bs, &size); size *=512 ;bdrv_delete (bs);
@@ -384,7 +380,6 @@ static int img_check(int argc, char **argv) {int c, ret;const char *filename, *fmt; -BlockDriver *drv;BlockDriverState *bs; fmt =NULL ;
@@ -405,19 +400,7 @@ static int img_check(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new ("" ); -if (!bs) -error ("Not enough memory" ); -if (fmt) { - drv =bdrv_find_format (fmt); -if (!drv) -error ("Unknown file format '%s'" , fmt); - }else { - drv =NULL ; - } -if (bdrv_open (bs, filename,BRDV_O_FLAGS , drv) <0 ) { -error ("Could not open '%s'" , filename); - } + bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS ); ret =bdrv_check (bs);switch (ret) {case 0 :
@@ -443,7 +426,6 @@ static int img_commit(int argc, char **argv) {int c, ret;const char *filename, *fmt; -BlockDriver *drv;BlockDriverState *bs; fmt =NULL ;
@@ -464,19 +446,7 @@ static int img_commit(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new ("" ); -if (!bs) -error ("Not enough memory" ); -if (fmt) { - drv =bdrv_find_format (fmt); -if (!drv) -error ("Unknown file format '%s'" , fmt); - }else { - drv =NULL ; - } -if (bdrv_open (bs, filename,BRDV_O_FLAGS |BDRV_O_RDWR , drv) <0 ) { -error ("Could not open '%s'" , filename); - } + bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS |BDRV_O_RDWR ); ret =bdrv_commit (bs);switch (ret) {case 0 :
@@ -633,7 +603,7 @@ static int img_convert(int argc, char **argv) total_sectors =0 ;for (bs_i =0 ; bs_i < bs_n; bs_i++) { - bs[bs_i] =bdrv_new_open (argv[optind + bs_i], fmt,1 ); + bs[bs_i] =bdrv_new_open (argv[optind + bs_i], fmt,BRDV_O_FLAGS );if (!bs[bs_i])error ("Could not open '%s'" , argv[optind + bs_i]);bdrv_get_geometry (bs[bs_i], &bs_sectors);
@@ -691,7 +661,7 @@ static int img_convert(int argc, char **argv) } } - out_bs =bdrv_new_open (out_filename, out_fmt,0 ); + out_bs =bdrv_new_open (out_filename, out_fmt,BRDV_O_FLAGS |BDRV_O_RDWR ); bs_i =0 ; bs_offset =0 ;
@@ -889,7 +859,6 @@ static int img_info(int argc, char **argv) {int c;const char *filename, *fmt; -BlockDriver *drv;BlockDriverState *bs;char fmt_name[128 ], size_buf[128 ], dsize_buf[128 ];uint64_t total_sectors;
@@ -916,19 +885,7 @@ static int img_info(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new ("" ); -if (!bs) -error ("Not enough memory" ); -if (fmt) { - drv =bdrv_find_format (fmt); -if (!drv) -error ("Unknown file format '%s'" , fmt); - }else { - drv =NULL ; - } -if (bdrv_open (bs, filename,BRDV_O_FLAGS |BDRV_O_NO_BACKING , drv) <0 ) { -error ("Could not open '%s'" , filename); - } + bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS |BDRV_O_NO_BACKING );bdrv_get_format (bs, fmt_name,sizeof (fmt_name));bdrv_get_geometry (bs, &total_sectors);get_human_readable_size (size_buf,sizeof (size_buf), total_sectors *512 );
@@ -1028,13 +985,7 @@ static int img_snapshot(int argc, char **argv) filename = argv[optind++];/* Open the image */ - bs =bdrv_new ("" ); -if (!bs) -error ("Not enough memory" ); - -if (bdrv_open (bs, filename, bdrv_oflags,NULL ) <0 ) { -error ("Could not open '%s'" , filename); - } + bs =bdrv_new_open (filename,NULL , bdrv_oflags);/* Perform the requested action */ switch (action) {
@@ -1080,7 +1031,7 @@ static int img_snapshot(int argc, char **argv)static int img_rebase (int argc,char **argv) {BlockDriverState *bs, *bs_old_backing, *bs_new_backing; -BlockDriver *drv, *old_backing_drv, *new_backing_drv; +BlockDriver *old_backing_drv, *new_backing_drv;char *filename;const char *fmt, *out_basefmt, *out_baseimg;int c, flags, ret;
@@ -1124,22 +1075,8 @@ static int img_rebase(int argc, char **argv)* Ignore the old backing file for unsafe rebase in case we want to correct * the reference to a renamed or moved backing file. */ - bs =bdrv_new ("" ); -if (!bs) -error ("Not enough memory" ); - - drv =NULL ; -if (fmt) { - drv =bdrv_find_format (fmt); -if (drv ==NULL ) { -error ("Invalid format name: '%s'" , fmt); - } - } - flags =BRDV_O_FLAGS |BDRV_O_RDWR | (unsafe ?BDRV_O_NO_BACKING :0 ); -if (bdrv_open (bs, filename, flags, drv) <0 ) { -error ("Could not open '%s'" , filename); - } + bs =bdrv_new_open (filename, fmt, flags);/* Find the right drivers for the backing files */ old_backing_drv =NULL ;
Signature · 1 line
1.6.6.1
PATCH 23/26 qemu-img: Fix BRDV_O_FLAGS typo
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
It should be BDRV_O_FLAGS instead of BRDV_O_FLAGS.
--- qemu-img.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-)
qemu-img.c +10 -10
@@ -37,7 +37,7 @@ typedef struct img_cmd_t { } img_cmd_t;/* Default to cache=writeback as data integrity is not important for qemu-tcg. */ -#define BRDV_O_FLAGS BDRV_O_CACHE_WB +#define BDRV_O_FLAGS BDRV_O_CACHE_WB static void QEMU_NORETURN error(const char *fmt, ...) {
@@ -345,7 +345,7 @@ static int img_create(int argc, char **argv) } } - bs =bdrv_new_open (backing_file->value.s, fmt,BRDV_O_FLAGS ); + bs =bdrv_new_open (backing_file->value.s, fmt,BDRV_O_FLAGS );bdrv_get_geometry (bs, &size); size *=512 ;bdrv_delete (bs);
@@ -400,7 +400,7 @@ static int img_check(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS ); + bs =bdrv_new_open (filename, fmt,BDRV_O_FLAGS ); ret =bdrv_check (bs);switch (ret) {case 0 :
@@ -446,7 +446,7 @@ static int img_commit(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS |BDRV_O_RDWR ); + bs =bdrv_new_open (filename, fmt,BDRV_O_FLAGS |BDRV_O_RDWR ); ret =bdrv_commit (bs);switch (ret) {case 0 :
@@ -603,7 +603,7 @@ static int img_convert(int argc, char **argv) total_sectors =0 ;for (bs_i =0 ; bs_i < bs_n; bs_i++) { - bs[bs_i] =bdrv_new_open (argv[optind + bs_i], fmt,BRDV_O_FLAGS ); + bs[bs_i] =bdrv_new_open (argv[optind + bs_i], fmt,BDRV_O_FLAGS );if (!bs[bs_i])error ("Could not open '%s'" , argv[optind + bs_i]);bdrv_get_geometry (bs[bs_i], &bs_sectors);
@@ -661,7 +661,7 @@ static int img_convert(int argc, char **argv) } } - out_bs =bdrv_new_open (out_filename, out_fmt,BRDV_O_FLAGS |BDRV_O_RDWR ); + out_bs =bdrv_new_open (out_filename, out_fmt,BDRV_O_FLAGS |BDRV_O_RDWR ); bs_i =0 ; bs_offset =0 ;
@@ -885,7 +885,7 @@ static int img_info(int argc, char **argv)help (); filename = argv[optind++]; - bs =bdrv_new_open (filename, fmt,BRDV_O_FLAGS |BDRV_O_NO_BACKING ); + bs =bdrv_new_open (filename, fmt,BDRV_O_FLAGS |BDRV_O_NO_BACKING );bdrv_get_format (bs, fmt_name,sizeof (fmt_name));bdrv_get_geometry (bs, &total_sectors);get_human_readable_size (size_buf,sizeof (size_buf), total_sectors *512 );
@@ -1075,7 +1075,7 @@ static int img_rebase(int argc, char **argv)* Ignore the old backing file for unsafe rebase in case we want to correct * the reference to a renamed or moved backing file. */ - flags =BRDV_O_FLAGS |BDRV_O_RDWR | (unsafe ?BDRV_O_NO_BACKING :0 ); + flags =BDRV_O_FLAGS |BDRV_O_RDWR | (unsafe ?BDRV_O_NO_BACKING :0 ); bs =bdrv_new_open (filename, fmt, flags);/* Find the right drivers for the backing files */
@@ -1106,7 +1106,7 @@ static int img_rebase(int argc, char **argv) bs_old_backing =bdrv_new ("old_backing" );bdrv_get_backing_filename (bs, backing_name,sizeof (backing_name)); -if (bdrv_open (bs_old_backing, backing_name,BRDV_O_FLAGS , +if (bdrv_open (bs_old_backing, backing_name,BDRV_O_FLAGS , old_backing_drv)) {error ("Could not open old backing file '%s'" , backing_name);
@@ -1114,7 +1114,7 @@ static int img_rebase(int argc, char **argv) } bs_new_backing =bdrv_new ("new_backing" ); -if (bdrv_open (bs_new_backing, out_baseimg,BRDV_O_FLAGS |BDRV_O_RDWR , +if (bdrv_open (bs_new_backing, out_baseimg,BDRV_O_FLAGS |BDRV_O_RDWR , new_backing_drv)) {error ("Could not open new backing file '%s'" , out_baseimg);
Signature · 1 line
1.6.6.1
PATCH 24/26 linux-aio: Fix typo in read() EINTR check
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
--- linux-aio.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
linux-aio.c +1 -1
@@ -123,7 +123,7 @@ static void qemu_laio_completion_cb(void *opaque)do { ret =read (s->efd, &val,sizeof (val)); - }while (ret ==1 && errno ==EINTR ); + }while (ret ==-1 && errno ==EINTR );if (ret ==-1 && errno ==EAGAIN )break ;
Signature · 1 line
1.6.6.1
PATCH 25/26 qcow2: Use QLIST_FOREACH_SAFE macro
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
--- block/qcow2.c | 10 ++-------- 1 files changed, 2 insertions(+), 8 deletions(-)
block/qcow2.c +2 -8
@@ -539,14 +539,8 @@ static void run_dependent_requests(QCowL2Meta *m)QLIST_REMOVE (m, next_in_flight); } -/* -* Restart all dependent requests. -* Can't use QLIST_FOREACH here - the next link might not be the same -* any more after the callback (request could depend on a different -* request now) -*/ -for (req = m->dependent_requests.lh_first; req !=NULL ; req = next) { - next = req->next_depend.le_next; +/* Restart all dependent requests */ + QLIST_FOREACH_SAFE(req, &m->dependent_requests, next_depend, next) {qcow_aio_write_cb (req,0 ); }
Signature · 1 line
1.6.6.1
PATCH 26/26 block: Free iovec arrays allocated by multiwrite_merge()
In reply to Kevin WolfFrom: Stefan Hajnoczi <[email protected]>
A new iovec array is allocated when creating a merged write request. This patch ensures that the iovec array is deleted in addition to its qiov owner.
--- block.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
block.c +3 -0
@@ -1739,6 +1739,9 @@ static void multiwrite_user_cb(MultiwriteCB *mcb)for (i =0 ; i < mcb->num_callbacks; i++) { mcb->callbacks[i].cb (mcb->callbacks[i].opaque, mcb->error); +if (mcb->callbacks[i].free_qiov) { +qemu_iovec_destroy (mcb->callbacks[i].free_qiov); + }qemu_free (mcb->callbacks[i].free_qiov);qemu_vfree (mcb->callbacks[i].free_buf); }
Signature · 1 line
1.6.6.1
Re: [Qemu-devel] [PATCH 26/26] block: Free iovec arrays allocated by multiwrite_merge()
Quoted 6 lines · Kevin Wolf
From: Stefan Hajnoczi <[email protected]>
A new iovec array is allocated when creating a merged write request. This patch ensures that the iovec array is deleted in addition to its qiov owner.
Submit for [STABLE] ?
Quoted 25 lines
Reported-by Leszek Urbanski <[email protected]>Signed-off-by Stefan Hajnoczi <[email protected]>Signed-off-by Kevin Wolf <[email protected]>--- block.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)block.c +3
-0@@ -1739,6 +1739,9 @@ static void multiwrite_user_cb(MultiwriteCB *mcb)for (i =0 ; i < mcb->num_callbacks; i++) { mcb->callbacks[i].cb (mcb->callbacks[i].opaque, mcb->error); +if (mcb->callbacks[i].free_qiov) { +qemu_iovec_destroy (mcb->callbacks[i].free_qiov); + }qemu_free (mcb->callbacks[i].free_qiov);qemu_vfree (mcb->callbacks[i].free_buf); }Signature · 1 line
1.6.6.1
Signature · 4 lines
Ryan Harper Software Engineer; Linux Technology Center IBM Corp., Austin, Tx [email protected]
Re: [Qemu-devel] [PATCH 26/26] block: Free iovec arrays allocated by multiwrite_merge()
Quoted 10 lines · Ryan Harper
Quoted 6 lines · Kevin Wolf
From: Stefan Hajnoczi <[email protected]>
A new iovec array is allocated when creating a merged write request. This patch ensures that the iovec array is deleted in addition to its qiov owner.
Submit for [STABLE] ?
I have just cherry-picked it into stable
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
Quoted 10 lines · Kevin Wolf
Hi Anthony,
this is the first part of the block patches that accumulated in my block branch during your absence. I consider these patches ready to be merged into master. I've not included another 13 patches that might still need discussion/review or depend on such patches. I'm going to send another pull request for them some time next week.
Kevin
Quoted 8 lines
The following changes since commit
6c557ab975fc8e5edb4167a241266c7c4657054a:
Serge Ziryukin (1):
audio/sdlaudio: remove unused variableare available in the git repository at:
git://repo.or.cz/qemu/kevin.gitfor-anthony
Pulled. Thanks for gathering these up!
Regards,
Anthony Liguori
Quoted 61 lines
Bruce Rogers (1):
Remove un-needed codeChristoph Hellwig (3):
block: get rid of theBDRV_O_FILEflag
block: splitraw_getlength
cleanup block driver option handling invl.cKevin Wolf (14):
qemu-config:qemu_read_config_file()reads the normal config file
qemu-config: Makeqemu_config_parsemore generic
blkdebug: Basic request passthrough
blkdebug: Inject errors
Make qemu-config available for tools
blkdebug: Add events and rules
qcow2: Trigger blkdebug events
qcow2: Fix creation of large images
Replace calls of oldbdrv_open
qcow2: Return 0/-errno inwrite_l2_entries
qcow2: Fix error return code inqcow2_alloc_cluster_link_l2
qcow2: Return 0/-errno inwrite_l1_entry
qcow2: Return 0/-errno inl2_allocate
block.h:bdrv_create2doesn't exist any moreStefan Hajnoczi (8):
block: Do not exportbdrv_first
block: Convertbdrv_firstto QTAILQ
block: Convertfirst_drvto QLIST
qemu-img: Eliminatebdrv_new_open()code duplication
qemu-img: FixBRDV_O_FLAGStypo
linux-aio: Fix typo inread()EINTR check
qcow2: UseQLIST_FOREACH_SAFEmacro
block: Free iovec arrays allocated bymultiwrite_merge()Makefile.objs | 6 +- block-migration.c | 63 ++++--- block.c | 119 +++++++------ block.h | 66 ++++++- block/blkdebug.c | 475 ++++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2-cluster.c | 78 +++++--- block/qcow2-refcount.c | 18 ++ block/qcow2.c | 63 +++++-- block/raw-posix.c | 65 +++++--- block/vmdk.c | 2 +- block/vvfat.c | 5 +- block_int.h | 9 +- hw/qdev-properties.c | 19 ++- hw/qdev.h | 1 - hw/virtio-blk.c | 1 - hw/xen_disk.c | 2 +- linux-aio.c | 2 +- monitor.c | 2 +- qemu-config.c | 48 +++--- qemu-config.h | 4 +- qemu-img.c | 93 ++-------- qemu-io.c | 28 ++-- qemu-nbd.c | 2 +- vl.c | 82 +++------ 24 files changed, 902 insertions(+), 351 deletions(-)create mode 100644
block/blkdebug.c