Block patches
The following changes since commit d3e8f95753114a827f9cd8e819b1d5cc8333f76b:
w32: Add implementation of gmtime_r, localtime_r (2012-09-23 17:09:30 +0000)
are available in the git repository at:
git://repo.or.cz/qemu/kevin.git for-anthony
Jeff Cody (18):
block: correctly set the keep_read_only flag
block: make bdrv_set_enable_write_cache() modify open_flags
block: Framework for reopening files safely
block: move aio initialization into a helper function
block: move open flag parsing in raw block drivers to helper functions
block: do not parse BDRV_O_CACHE_WB in block drivers
block: use BDRV_O_NOCACHE instead of s->aligned_buf in raw-posix.c
block: purge s->aligned_buf and s->aligned_buf_size from raw-posix.c
block: raw-posix image file reopen
block: raw image file reopen
block: qed image file reopen
block: qcow2 image file reopen
block: qcow image file reopen
block: vmdk image file reopen
block: vdi image file reopen
block: vpc image file reopen
block: convert bdrv_commit() to use bdrv_reopen()
block: remove keep_read_only flag from BlockDriverState struct
Kevin Shanahan (1):
blockdev: preserve readonly and snapshot states across media changes
block.c | 299 ++++++++++++++++++++++++++++++++++++++++++++--------- block.h | 18 +++ block/iscsi.c | 4 - block/qcow.c | 10 ++ block/qcow2.c | 10 ++ block/qed.c | 9 ++ block/raw-posix.c | 225 ++++++++++++++++++++++++++++++---------- block/raw-win32.c | 40 ++++---- block/raw.c | 10 ++ block/rbd.c | 6 - block/sheepdog.c | 14 +-- block/vdi.c | 7 ++ block/vmdk.c | 35 ++++++ block/vpc.c | 7 ++ block_int.h | 9 ++- blockdev.c | 2 + 16 files changed, 563 insertions(+), 142 deletions(-)
PATCH 1/19 blockdev: preserve readonly and snapshot states across media changes
From: Kevin Shanahan <[email protected]>
If readonly=on is given at device creation time, the ->readonly flag needs to be set in the block driver state for this device so that readonly-ness is preserved across media changes (qmp change command). Similarly, to preserve the snapshot property requires ->open_flags to be correct.
--- blockdev.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
blockdev.c +2 -0
@@ -527,6 +527,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) if_name[type], mediastr, unit_id); } dinfo->bdrv =bdrv_new (dinfo->id); + dinfo->bdrv->open_flags = snapshot ?BDRV_O_SNAPSHOT :0 ; + dinfo->bdrv->read_only = ro; dinfo->devaddr = devaddr; dinfo->type = type; dinfo->bus = bus_id;
Signature · 1 line
1.7.6.5
PATCH 2/19 block: correctly set the keep_read_only flag
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
I believe the bs->keep_read_only flag is supposed to reflect the initial open state of the device. If the device is initially opened R/O, then commit operations, or reopen operations changing to R/W, are prohibited.
Currently, the keep_read_only flag is only accurate for the active layer, and its backing file. Subsequent images end up always having the keep_read_only flag set.
For instance, what happens now:
[ base ] kro = 1, ro = 1
|
v
[ snap-1 ] kro = 1, ro = 1
|
v
[ snap-2 ] kro = 0, ro = 1
|
v[ active ] kro = 0, ro = 0
What we want:
[ base ] kro = 0, ro = 1
|
v
[ snap-1 ] kro = 0, ro = 1
|
v
[ snap-2 ] kro = 0, ro = 1
|
v[ active ] kro = 0, ro = 0
--- block.c | 14 +++++++------- block.h | 1 + 2 files changed, 8 insertions(+), 7 deletions(-)
block.c +7 -7
@@ -668,7 +668,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename, open_flags |=BDRV_O_RDWR ; } - bs->keep_read_only = bs->read_only = !(open_flags &BDRV_O_RDWR ); + bs->read_only = !(open_flags &BDRV_O_RDWR );/* Open the image, either directly or using a protocol */ if (drv->bdrv_file_open) {
@@ -808,6 +808,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, goto unlink_and_fail; } +if (flags &BDRV_O_RDWR ) { + flags |=BDRV_O_ALLOW_RDWR ; + } + + bs->keep_read_only = !(flags &BDRV_O_ALLOW_RDWR ); +/* Open the image */ ret =bdrv_open_common (bs, filename, flags, drv);if (ret <0 ) {
@@ -837,12 +843,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,bdrv_close (bs);return ret; } -if (bs->is_temporary) { - bs->backing_hd->keep_read_only = !(flags &BDRV_O_RDWR ); - }else { -/* base image inherits from "parent" */ - bs->backing_hd->keep_read_only = bs->keep_read_only; - } }if (!bdrv_key_required (bs)) {
block.h +1 -0
@@ -80,6 +80,7 @@ typedef struct BlockDevOps {#define BDRV_O_COPY_ON_READ 0x0400/* copy read backing sectors into image */ #define BDRV_O_INCOMING 0x0800/* consistency hint for incoming migration */ #define BDRV_O_CHECK 0x1000/* open solely for consistency check */ +#define BDRV_O_ALLOW_RDWR 0x2000/* allow reopen to change from r/o to r/w */ #define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
Signature · 1 line
1.7.6.5
PATCH 3/19 block: make bdrv_set_enable_write_cache() modify open_flags
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
bdrv_set_enable_write_cache() sets the bs->enable_write_cache flag, but without the flag recorded in bs->open_flags, then next time a reopen() is performed the enable_write_cache setting may be inadvertently lost.
This will set the flag in open_flags, so it is preserved across reopens.
--- block.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
block.c +7 -0
@@ -2168,6 +2168,13 @@ int bdrv_enable_write_cache(BlockDriverState *bs)void bdrv_set_enable_write_cache (BlockDriverState *bs,bool wce) { bs->enable_write_cache = wce; + +/* so a reopen() will preserve wce */ +if (wce) { + bs->open_flags |=BDRV_O_CACHE_WB ; + }else { + bs->open_flags &= ~BDRV_O_CACHE_WB ; + } }int bdrv_is_encrypted (BlockDriverState *bs)
Signature · 1 line
1.7.6.5
PATCH 4/19 block: Framework for reopening files safely
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
This is based on Supriya Kannery's bdrv_reopen() patch series.
This provides a transactional method to reopen multiple images files safely.
Image files are queue for reopen via bdrv_reopen_queue(), and the reopen occurs when bdrv_reopen_multiple() is called. Changes are staged in bdrv_reopen_prepare() and in the equivalent driver level functions. If any of the staged images fails a prepare, then all of the images left untouched, and the staged changes for each image abandoned.
Block drivers are passed a reopen state structure, that contains:
* BDS to reopen
* flags for the reopen
* opaque pointer for any driver-specific data that needs to be persistent from _prepare to _commit/_abort
* reopen queue pointer, if the driver needs to queue additional BDS for a reopen
--- block.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ block.h | 17 +++++ block_int.h | 8 ++ 3 files changed, 257 insertions(+), 0 deletions(-)
block.c +232 -0
@@ -863,6 +863,238 @@ unlink_and_fail:return ret; } +typedef struct BlockReopenQueueEntry { +bool prepared; +BDRVReopenState state; +QSIMPLEQ_ENTRY (BlockReopenQueueEntry) entry; +}BlockReopenQueueEntry ; + +/* +* Adds a BlockDriverState to a simple queue for an atomic, transactional +* reopen of multiple devices. +* +* bs_queue can either be an existing BlockReopenQueue that has had QSIMPLE_INIT +* already performed, or alternatively may be NULL a new BlockReopenQueue will +* be created and initialized. This newly created BlockReopenQueue should be +* passed back in for subsequent calls that are intended to be of the same +* atomic 'set'. +* +* bs is the BlockDriverState to add to the reopen queue. +* +* flags contains the open flags for the associated bs +* +* returns a pointer to bs_queue, which is either the newly allocated +* bs_queue, or the existing bs_queue being used. +* +*/ +BlockReopenQueue *bdrv_reopen_queue (BlockReopenQueue *bs_queue, +BlockDriverState *bs,int flags) +{ +assert (bs !=NULL ); + +BlockReopenQueueEntry *bs_entry; +if (bs_queue ==NULL ) { + bs_queue =g_new0 (BlockReopenQueue,1 ); +QSIMPLEQ_INIT (bs_queue); + } + +if (bs->file) { +bdrv_reopen_queue (bs_queue, bs->file, flags); + } + + bs_entry =g_new0 (BlockReopenQueueEntry,1 ); +QSIMPLEQ_INSERT_TAIL (bs_queue, bs_entry, entry); + + bs_entry->state.bs = bs; + bs_entry->state.flags = flags; + +return bs_queue; +} + +/* +* Reopen multiple BlockDriverStates atomically & transactionally. +* +* The queue passed in (bs_queue) must have been built up previous +* via bdrv_reopen_queue(). +* +* Reopens all BDS specified in the queue, with the appropriate +* flags. All devices are prepared for reopen, and failure of any +* device will cause all device changes to be abandonded, and intermediate +* data cleaned up. +* +* If all devices prepare successfully, then the changes are committed +* to all devices. +* +*/ +int bdrv_reopen_multiple (BlockReopenQueue *bs_queue,Error **errp) +{ +int ret =-1 ; +BlockReopenQueueEntry *bs_entry, *next; +Error *local_err =NULL ; + +assert (bs_queue !=NULL ); + +bdrv_drain_all (); + + QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) { +if (bdrv_reopen_prepare (&bs_entry->state, bs_queue, &local_err)) { +error_propagate (errp, local_err); + goto cleanup; + } + bs_entry->prepared = true; + } + +/* If we reach this point, we have success and just need to apply the +* changes +*/ + QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) { +bdrv_reopen_commit (&bs_entry->state); + } + + ret =0 ; + +cleanup: + QSIMPLEQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) { +if (ret && bs_entry->prepared) { +bdrv_reopen_abort (&bs_entry->state); + } +g_free (bs_entry); + } +g_free (bs_queue); +return ret; +} + + +/* Reopen a single BlockDriverState with the specified flags. */ +int bdrv_reopen (BlockDriverState *bs,int bdrv_flags,Error **errp) +{ +int ret =-1 ; +Error *local_err =NULL ; +BlockReopenQueue *queue =bdrv_reopen_queue (NULL , bs, bdrv_flags); + + ret =bdrv_reopen_multiple (queue, &local_err); +if (local_err !=NULL ) { +error_propagate (errp, local_err); + } +return ret; +} + + +/* +* Prepares a BlockDriverState for reopen. All changes are staged in the +* 'opaque' field of the BDRVReopenState, which is used and allocated by +* the block driver layer .bdrv_reopen_prepare() +* +* bs is the BlockDriverState to reopen +* flags are the new open flags +* queue is the reopen queue +* +* Returns 0 on success, non-zero on error. On error errp will be set +* as well. +* +* On failure, bdrv_reopen_abort() will be called to clean up any data. +* It is the responsibility of the caller to then call the abort() or +* commit() for any other BDS that have been left in a prepare() state +* +*/ +int bdrv_reopen_prepare (BDRVReopenState *reopen_state,BlockReopenQueue *queue, +Error **errp) +{ +int ret =-1 ; +Error *local_err =NULL ; +BlockDriver *drv; + +assert (reopen_state !=NULL ); +assert (reopen_state->bs->drv !=NULL ); + drv = reopen_state->bs->drv; + +/* if we are to stay read-only, do not allow permission change +* to r/w */ +if (!(reopen_state->bs->open_flags &BDRV_O_ALLOW_RDWR ) && + reopen_state->flags &BDRV_O_RDWR ) { +error_set (errp,QERR_DEVICE_IS_READ_ONLY , + reopen_state->bs->device_name); + goto error; + } + + + ret =bdrv_flush (reopen_state->bs); +if (ret) { +error_set (errp,ERROR_CLASS_GENERIC_ERROR ,"Error (%s) flushing drive" , +strerror (-ret)); + goto error; + } + +if (drv->bdrv_reopen_prepare) { + ret = drv->bdrv_reopen_prepare (reopen_state, queue, &local_err); +if (ret) { +if (local_err !=NULL ) { +error_propagate (errp, local_err); + }else { +error_set (errp,QERR_OPEN_FILE_FAILED , + reopen_state->bs->filename); + } + goto error; + } + }else { +/* It is currently mandatory to have a bdrv_reopen_prepare() +* handler for each supported drv. */ +error_set (errp,QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED , + drv->format_name, reopen_state->bs->device_name, +"reopening of file" ); + ret =-1 ; + goto error; + } + + ret =0 ; + +error: +return ret; +} + +/* +* Takes the staged changes for the reopen from bdrv_reopen_prepare(), and +* makes them final by swapping the staging BlockDriverState contents into +* the active BlockDriverState contents. +*/ +void bdrv_reopen_commit (BDRVReopenState *reopen_state) +{ +BlockDriver *drv; + +assert (reopen_state !=NULL ); + drv = reopen_state->bs->drv; +assert (drv !=NULL ); + +/* If there are any driver level actions to take */ +if (drv->bdrv_reopen_commit) { + drv->bdrv_reopen_commit (reopen_state); + } + +/* set BDS specific flags now */ + reopen_state->bs->open_flags = reopen_state->flags; + reopen_state->bs->enable_write_cache = !!(reopen_state->flags & +BDRV_O_CACHE_WB ); + reopen_state->bs->read_only = !(reopen_state->flags &BDRV_O_RDWR ); +} + +/* +* Abort the reopen, and delete and free the staged changes in +* reopen_state +*/ +void bdrv_reopen_abort (BDRVReopenState *reopen_state) +{ +BlockDriver *drv; + +assert (reopen_state !=NULL ); + drv = reopen_state->bs->drv; +assert (drv !=NULL ); + +if (drv->bdrv_reopen_abort) { + drv->bdrv_reopen_abort (reopen_state); + } +} + +void bdrv_close (BlockDriverState *bs) {bdrv_flush (bs);
block.h +17 -0
@@ -97,6 +97,15 @@ typedef enum { BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP } BlockQMPEventAction; +typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue; + +typedef struct BDRVReopenState { +BlockDriverState *bs; +int flags; +void *opaque; +}BDRVReopenState ; + +void bdrv_iostatus_enable (BlockDriverState *bs);void bdrv_iostatus_reset (BlockDriverState *bs);void bdrv_iostatus_disable (BlockDriverState *bs);
@@ -131,6 +140,14 @@ int bdrv_parse_cache_flags(const char *mode, int *flags);int bdrv_file_open (BlockDriverState **pbs,const char *filename,int flags);int bdrv_open (BlockDriverState *bs,const char *filename,int flags,BlockDriver *drv); +BlockReopenQueue *bdrv_reopen_queue (BlockReopenQueue *bs_queue, +BlockDriverState *bs,int flags); +int bdrv_reopen_multiple (BlockReopenQueue *bs_queue,Error **errp); +int bdrv_reopen (BlockDriverState *bs,int bdrv_flags,Error **errp); +int bdrv_reopen_prepare (BDRVReopenState *reopen_state, +BlockReopenQueue *queue,Error **errp); +void bdrv_reopen_commit (BDRVReopenState *reopen_state); +void bdrv_reopen_abort (BDRVReopenState *reopen_state);void bdrv_close (BlockDriverState *bs);int bdrv_attach_dev (BlockDriverState *bs,void *dev);void bdrv_attach_dev_nofail (BlockDriverState *bs,void *dev);
block_int.h +8 -0
@@ -139,6 +139,13 @@ struct BlockDriver {int instance_size;int (*bdrv_probe)(const uint8_t *buf,int buf_size,const char *filename);int (*bdrv_probe_device)(const char *filename); + +/* For handling image reopen for split or non-split files */ +int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state, +BlockReopenQueue *queue,Error **errp); +void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state); +void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state); +int (*bdrv_open)(BlockDriverState *bs,int flags);int (*bdrv_file_open)(BlockDriverState *bs,const char *filename,int flags); int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
@@ -336,6 +343,7 @@ struct BlockDriverState {/* long-running background operation */ BlockJob *job; + };int get_tmp_filename (char *filename,int size);
Signature · 1 line
1.7.6.5
PATCH 5/19 block: move aio initialization into a helper function
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
Move AIO initialization for raw-posix block driver into a helper function.
In addition to just code motion, the aio_ctx pointer is checked for NULL, prior to calling laio_init(), to make sure laio_init() is only run once.
--- block/raw-posix.c | 53 +++++++++++++++++++++++++++++++++++------------------ 1 files changed, 35 insertions(+), 18 deletions(-)
block/raw-posix.c +35 -18
@@ -185,6 +185,38 @@ static int raw_normalize_devicepath(const char **filename) }#endif +#ifdef CONFIG_LINUX_AIO +static int raw_set_aio (void **aio_ctx,int *use_aio,int bdrv_flags) +{ +int ret =-1 ; +assert (aio_ctx !=NULL ); +assert (use_aio !=NULL ); +/* +* Currently Linux do AIO only for files opened with O_DIRECT +* specified so check NOCACHE flag too +*/ +if ((bdrv_flags & (BDRV_O_NOCACHE |BDRV_O_NATIVE_AIO )) == + (BDRV_O_NOCACHE |BDRV_O_NATIVE_AIO )) { + +/* if non-NULL, laio_init() has already been run */ +if (*aio_ctx ==NULL ) { + *aio_ctx =laio_init (); +if (!*aio_ctx) { + goto error; + } + } + *use_aio =1 ; + }else { + *use_aio =0 ; + } + + ret =0 ; + +error: +return ret; +} +#endif +static int raw_open_common (BlockDriverState *bs,const char *filename,int bdrv_flags,int open_flags) {
@@ -240,25 +272,10 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, }#ifdef CONFIG_LINUX_AIO -/* -* Currently Linux do AIO only for files opened with O_DIRECT -* specified so check NOCACHE flag too -*/ -if ((bdrv_flags & (BDRV_O_NOCACHE |BDRV_O_NATIVE_AIO )) == - (BDRV_O_NOCACHE |BDRV_O_NATIVE_AIO )) { - - s->aio_ctx =laio_init (); -if (!s->aio_ctx) { - goto out_free_buf; - } - s->use_aio =1 ; - } else -#endif - { -#ifdef CONFIG_LINUX_AIO - s->use_aio =0 ; -#endif +if (raw_set_aio (&s->aio_ctx, &s->use_aio, bdrv_flags)) { + goto out_close; } +#endif #ifdef CONFIG_XFS if (platform_test_xfs_fd (s->fd)) {
Signature · 1 line
1.7.6.5
PATCH 6/19 block: move open flag parsing in raw block drivers to helper functions
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
Code motion, to move parsing of open flags into a helper function.
--- block/raw-posix.c | 38 ++++++++++++++++++++++++-------------- block/raw-win32.c | 43 +++++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 34 deletions(-)
block/raw-posix.c +24 -14
@@ -185,6 +185,28 @@ static int raw_normalize_devicepath(const char **filename) }#endif +static void raw_parse_flags (int bdrv_flags,int *open_flags) +{ +assert (open_flags !=NULL ); + + *open_flags |=O_BINARY ; + *open_flags &= ~O_ACCMODE ; +if (bdrv_flags &BDRV_O_RDWR ) { + *open_flags |=O_RDWR ; + }else { + *open_flags |=O_RDONLY ; + } + +/* Use O_DSYNC for write-through caching, no flags for write-back caching, +* and O_DIRECT for no caching. */ +if ((bdrv_flags &BDRV_O_NOCACHE )) { + *open_flags |=O_DIRECT ; + } +if (!(bdrv_flags &BDRV_O_CACHE_WB )) { + *open_flags |=O_DSYNC ; + } +} +#ifdef CONFIG_LINUX_AIO static int raw_set_aio (void **aio_ctx,int *use_aio,int bdrv_flags) {
@@ -228,20 +250,8 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,return ret; } - s->open_flags = open_flags |O_BINARY ; - s->open_flags &= ~O_ACCMODE ; -if (bdrv_flags &BDRV_O_RDWR ) { - s->open_flags |=O_RDWR ; - }else { - s->open_flags |=O_RDONLY ; - } - -/* Use O_DSYNC for write-through caching, no flags for write-back caching, -* and O_DIRECT for no caching. */ -if ((bdrv_flags &BDRV_O_NOCACHE )) - s->open_flags |=O_DIRECT ; -if (!(bdrv_flags &BDRV_O_CACHE_WB )) - s->open_flags |=O_DSYNC ; + s->open_flags = open_flags; +raw_parse_flags (bdrv_flags, &s->open_flags); s->fd =-1 ; fd =qemu_open (filename, s->open_flags,0644 );
block/raw-win32.c +23 -20
64 lines not on this page · raw message
Signature · 1 line
1.7.6.5
PATCH 7/19 block: do not parse BDRV_O_CACHE_WB in block drivers
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
Block drivers should ignore BDRV_O_CACHE_WB in .bdrv_open flags, and in the bs->open_flags.
This patch removes the code, leaving the behaviour behind as if BDRV_O_CACHE_WB was set.
--- block/iscsi.c | 4 ---- block/raw-posix.c | 3 --- block/raw-win32.c | 3 --- block/rbd.c | 6 ------ block/sheepdog.c | 14 ++++++-------- 5 files changed, 6 insertions(+), 24 deletions(-)
block/iscsi.c +0 -4
@@ -268,10 +268,6 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num, acb->task->xfer_dir =SCSI_XFER_WRITE ; acb->task->cdb_size =16 ; acb->task->cdb[0 ] =0x8a ; -if (!(bs->open_flags &BDRV_O_CACHE_WB )) { -/* set FUA on writes when cache mode is write through */ - acb->task->cdb[1 ] |=0x04 ; - } lba =sector_qemu2lun (sector_num, iscsilun); *(uint32_t *)&acb->task->cdb[2 ] =htonl (lba >>32 ); *(uint32_t *)&acb->task->cdb[6 ] =htonl (lba &0xffffffff );
block/raw-posix.c +0 -3
@@ -202,9 +202,6 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)if ((bdrv_flags &BDRV_O_NOCACHE )) { *open_flags |=O_DIRECT ; } -if (!(bdrv_flags &BDRV_O_CACHE_WB )) { - *open_flags |=O_DSYNC ; - } }#ifdef CONFIG_LINUX_AIO
block/raw-win32.c +0 -3
@@ -92,9 +92,6 @@ static void raw_parse_flags(int flags, int *access_flags, DWORD *overlapped)if (flags &BDRV_O_NOCACHE ) { *overlapped |=FILE_FLAG_NO_BUFFERING ; } -if (!(flags &BDRV_O_CACHE_WB )) { - *overlapped |=FILE_FLAG_WRITE_THROUGH ; - } }static int raw_open (BlockDriverState *bs,const char *filename,int flags)
block/rbd.c +0 -6
@@ -487,12 +487,6 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)rados_conf_set (s->cluster,"rbd_cache" ,"false" ); }else {rados_conf_set (s->cluster,"rbd_cache" ,"true" ); -if (!(flags &BDRV_O_CACHE_WB )) { - r =rados_conf_set (s->cluster,"rbd_cache_max_dirty" ,"0" ); -if (r <0 ) { -rados_conf_set (s->cluster,"rbd_cache" ,"false" ); - } - } }if (strstr (conf,"conf=" ) ==NULL ) {
block/sheepdog.c +6 -8
@@ -1114,14 +1114,12 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) goto out; } -if (flags &BDRV_O_CACHE_WB ) { - s->cache_enabled =1 ; - s->flush_fd =connect_to_sdog (s->addr, s->port); -if (s->flush_fd <0 ) { -error_report ("failed to connect" ); - ret = s->flush_fd; - goto out; - } + s->cache_enabled =1 ; + s->flush_fd =connect_to_sdog (s->addr, s->port); +if (s->flush_fd <0 ) { +error_report ("failed to connect" ); + ret = s->flush_fd; + goto out; }if (snapid || tag[0 ] !='\0' ) {
Signature · 1 line
1.7.6.5
PATCH 8/19 block: use BDRV_O_NOCACHE instead of s->aligned_buf in raw-posix.c
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
Rather than check for a non-NULL aligned_buf to determine if raw_aio_submit needs to check for alignment, check for the presence of BDRV_O_NOCACHE in the bs->open_flags.
--- block/raw-posix.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
block/raw-posix.c +1 -1
@@ -354,7 +354,7 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,* boundary. Check if this is the case or tell the low-level * driver that it needs to copy the buffer. */ -if (s->aligned_buf) { +if ((bs->open_flags &BDRV_O_NOCACHE )) {if (!qiov_is_aligned (bs, qiov)) { type |=QEMU_AIO_MISALIGNED ;#ifdef CONFIG_LINUX_AIO
Signature · 1 line
1.7.6.5
PATCH 9/19 block: purge s->aligned_buf and s->aligned_buf_size from raw-posix.c
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
The aligned_buf pointer and aligned_buf size are no longer used in raw_posix.c, so remove all references to them.
--- block/raw-posix.c | 21 +-------------------- 1 files changed, 1 insertions(+), 20 deletions(-)
block/raw-posix.c +1 -20
@@ -133,8 +133,6 @@ typedef struct BDRVRawState {int use_aio;void *aio_ctx;#endif -uint8_t *aligned_buf; -unsigned aligned_buf_size;#ifdef CONFIG_XFS bool is_xfs : 1;#endif
@@ -259,23 +257,10 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,return ret; } s->fd = fd; - s->aligned_buf =NULL ; - -if ((bdrv_flags &BDRV_O_NOCACHE )) { -/* -* Allocate a buffer for read/modify/write cycles. Chose the size -* pessimistically as we don't know the block size yet. -*/ - s->aligned_buf_size =32 *MAX_BLOCKSIZE ; - s->aligned_buf =qemu_memalign (MAX_BLOCKSIZE , s->aligned_buf_size); -if (s->aligned_buf ==NULL ) { - goto out_close; - } - }/* We're falling back to POSIX AIO in some cases so init always */ if (paio_init () <0 ) { - goto out_free_buf; + goto out_close; }#ifdef CONFIG_LINUX_AIO
@@ -292,8 +277,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,return 0 ; -out_free_buf: -qemu_vfree (s->aligned_buf); out_close:qemu_close (fd);return -errno;
@@ -402,8 +385,6 @@ static void raw_close(BlockDriverState *bs)if (s->fd >=0 ) {qemu_close (s->fd); s->fd =-1 ; -if (s->aligned_buf !=NULL ) -qemu_vfree (s->aligned_buf); } }
Signature · 1 line
1.7.6.5
PATCH 10/19 block: raw-posix image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
This is derived from the Supriya Kannery's reopen patches.
This contains the raw-posix driver changes for the bdrv_reopen_* functions. All changes are staged into a temporary scratch buffer during the prepare() stage, and copied over to the live structure during commit(). Upon abort(), all changes are abandoned, and the live structures are unmodified.
The _prepare() will create an extra fd - either by means of a dup, if possible, or opening a new fd if not (for instance, access control changes). Upon _commit(), the original fd is closed and the new fd is used. Upon _abort(), the duplicate/new fd is closed.
--- block/raw-posix.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 114 insertions(+), 0 deletions(-)
block/raw-posix.c +114 -0
@@ -138,6 +138,14 @@ typedef struct BDRVRawState {#endif } BDRVRawState; +typedef struct BDRVRawReopenState { +int fd; +int open_flags; +#ifdef CONFIG_LINUX_AIO +int use_aio; +#endif +}BDRVRawReopenState ; +static int fd_open (BlockDriverState *bs);static int64_t raw_getlength (BlockDriverState *bs);
@@ -290,6 +298,109 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)return raw_open_common (bs, filename, flags,0 ); } +static int raw_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +BDRVRawState *s; +BDRVRawReopenState *raw_s; +int ret =0 ; + +assert (state !=NULL ); +assert (state->bs !=NULL ); + + s = state->bs->opaque; + + state->opaque =g_malloc0 (sizeof (BDRVRawReopenState)); + raw_s = state->opaque; + +#ifdef CONFIG_LINUX_AIO + raw_s->use_aio = s->use_aio; + +/* we can use s->aio_ctx instead of a copy, because the use_aio flag is +* valid in the 'false' condition even if aio_ctx is set, and raw_set_aio() +* won't override aio_ctx if aio_ctx is non-NULL */ +if (raw_set_aio (&s->aio_ctx, &raw_s->use_aio, state->flags)) { +return -1 ; + } +#endif + +raw_parse_flags (state->flags, &raw_s->open_flags); + + raw_s->fd =-1 ; + +int fcntl_flags =O_APPEND |O_ASYNC |O_NONBLOCK ; +#ifdef O_NOATIME + fcntl_flags |=O_NOATIME ; +#endif + +if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) { +/* dup the original fd */ +/* TODO: use qemu fcntl wrapper */ +#ifdef F_DUPFD_CLOEXEC + raw_s->fd =fcntl (s->fd,F_DUPFD_CLOEXEC ,0 ); +#else + raw_s->fd =dup (s->fd); +if (raw_s->fd !=-1 ) { +qemu_set_cloexec (raw_s->fd); + } +#endif +if (raw_s->fd >=0 ) { + ret =fcntl_setfl (raw_s->fd, raw_s->open_flags); +if (ret) { +qemu_close (raw_s->fd); + raw_s->fd =-1 ; + } + } + } + +/* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */ +if (raw_s->fd ==-1 ) { +assert (!(raw_s->open_flags &O_CREAT )); + raw_s->fd =qemu_open (state->bs->filename, raw_s->open_flags); +if (raw_s->fd ==-1 ) { + ret =-1 ; + } + } +return ret; +} + + +static void raw_reopen_commit (BDRVReopenState *state) +{ +BDRVRawReopenState *raw_s = state->opaque; +BDRVRawState *s = state->bs->opaque; + + s->open_flags = raw_s->open_flags; + +qemu_close (s->fd); + s->fd = raw_s->fd; +#ifdef CONFIG_LINUX_AIO + s->use_aio = raw_s->use_aio; +#endif + +g_free (state->opaque); + state->opaque =NULL ; +} + + +static void raw_reopen_abort (BDRVReopenState *state) +{ +BDRVRawReopenState *raw_s = state->opaque; + +/* nothing to do if NULL, we didn't get far enough */ +if (raw_s ==NULL ) { +return ; + } + +if (raw_s->fd >=0 ) { +qemu_close (raw_s->fd); + raw_s->fd =-1 ; + } +g_free (state->opaque); + state->opaque =NULL ; +} + +/* XXX: use host sector size if necessary with: #ifdef DIOCGSECTORSIZE {
@@ -740,6 +851,9 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_probe = NULL, /* no probe for protocols */ .bdrv_file_open = raw_open, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_reopen_commit = raw_reopen_commit, + .bdrv_reopen_abort = raw_reopen_abort, .bdrv_close = raw_close, .bdrv_create = raw_create, .bdrv_co_discard = raw_co_discard,
Signature · 1 line
1.7.6.5
PATCH 11/19 block: raw image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
These are the stubs for the file reopen drivers for the raw format.
There is currently nothing that needs to be done by the raw driver in reopen.
--- block/raw.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
block/raw.c +10 -0
@@ -9,6 +9,14 @@ static int raw_open(BlockDriverState *bs, int flags)return 0 ; } +/* We have nothing to do for raw reopen, stubs just return +* success */ +static int raw_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} + static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,int nb_sectors,QEMUIOVector *qiov) {
@@ -115,6 +123,8 @@ static BlockDriver bdrv_raw = { .bdrv_open = raw_open, .bdrv_close = raw_close, + .bdrv_reopen_prepare = raw_reopen_prepare, + .bdrv_co_readv = raw_co_readv, .bdrv_co_writev = raw_co_writev, .bdrv_co_is_allocated = raw_co_is_allocated,
Signature · 1 line
1.7.6.5
PATCH 12/19 block: qed image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
These are the stubs for the file reopen drivers for the qed format.
There is currently nothing that needs to be done by the qed driver in reopen.
--- block/qed.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
block/qed.c +9 -0
@@ -505,6 +505,14 @@ out:return ret; } +/* We have nothing to do for QED reopen, stubs just return +* success */ +static int bdrv_qed_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} +static void bdrv_qed_close (BlockDriverState *bs) {BDRVQEDState *s = bs->opaque;
@@ -1564,6 +1572,7 @@ static BlockDriver bdrv_qed = { .bdrv_rebind = bdrv_qed_rebind, .bdrv_open = bdrv_qed_open, .bdrv_close = bdrv_qed_close, + .bdrv_reopen_prepare = bdrv_qed_reopen_prepare, .bdrv_create = bdrv_qed_create, .bdrv_co_is_allocated = bdrv_qed_co_is_allocated, .bdrv_make_empty = bdrv_qed_make_empty,
Signature · 1 line
1.7.6.5
PATCH 13/19 block: qcow2 image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
These are the stubs for the file reopen drivers for the qcow2 format.
There is currently nothing that needs to be done by the qcow2 driver in reopen.
--- block/qcow2.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
block/qcow2.c +10 -0
@@ -52,6 +52,7 @@ typedef struct {uint32_t magic;uint32_t len; } QCowExtension; +#define QCOW2_EXT_MAGIC_END 0#define QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
@@ -558,6 +559,14 @@ static int qcow2_set_key(BlockDriverState *bs, const char *key)return 0 ; } +/* We have nothing to do for QCOW2 reopen, stubs just return +* success */ +static int qcow2_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} + static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,int64_t sector_num,int nb_sectors,int *pnum) {
@@ -1679,6 +1688,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_probe = qcow2_probe, .bdrv_open = qcow2_open, .bdrv_close = qcow2_close, + .bdrv_reopen_prepare = qcow2_reopen_prepare, .bdrv_create = qcow2_create, .bdrv_co_is_allocated = qcow2_co_is_allocated, .bdrv_set_key = qcow2_set_key,
Signature · 1 line
1.7.6.5
PATCH 14/19 block: qcow image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
These are the stubs for the file reopen drivers for the qcow format.
There is currently nothing that needs to be done by the qcow driver in reopen.
--- block/qcow.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
block/qcow.c +10 -0
@@ -197,6 +197,15 @@ static int qcow_open(BlockDriverState *bs, int flags)return ret; } + +/* We have nothing to do for QCOW reopen, stubs just return +* success */ +static int qcow_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} +static int qcow_set_key (BlockDriverState *bs,const char *key) {BDRVQcowState *s = bs->opaque;
@@ -868,6 +877,7 @@ static BlockDriver bdrv_qcow = { .bdrv_probe = qcow_probe, .bdrv_open = qcow_open, .bdrv_close = qcow_close, + .bdrv_reopen_prepare = qcow_reopen_prepare, .bdrv_create = qcow_create, .bdrv_co_readv = qcow_co_readv,
Signature · 1 line
1.7.6.5
PATCH 15/19 block: vmdk image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
This patch supports reopen for VMDK image files. VMDK extents are added to the existing reopen queue, so that the transactional model of reopen is maintained with multiple image files.
--- block/vmdk.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-)
block/vmdk.c +35 -0
@@ -300,6 +300,40 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)return 1 ; } +/* Queue extents, if any, for reopen() */ +static int vmdk_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +BDRVVmdkState *s; +int ret =-1 ; +int i; +VmdkExtent *e; + +assert (state !=NULL ); +assert (state->bs !=NULL ); + +if (queue ==NULL ) { +error_set (errp,ERROR_CLASS_GENERIC_ERROR , +"No reopen queue for VMDK extents" ); + goto exit; + } + + s = state->bs->opaque; + +assert (s !=NULL ); + +for (i =0 ; i < s->num_extents; i++) { + e = &s->extents[i]; +if (e->file != state->bs->file) { +bdrv_reopen_queue (queue, e->file, state->flags); + } + } + ret =0 ; + +exit: +return ret; +} +static int vmdk_parent_open (BlockDriverState *bs) {char *p_name;
@@ -1646,6 +1680,7 @@ static BlockDriver bdrv_vmdk = { .instance_size = sizeof(BDRVVmdkState), .bdrv_probe = vmdk_probe, .bdrv_open = vmdk_open, + .bdrv_reopen_prepare = vmdk_reopen_prepare, .bdrv_read = vmdk_co_read, .bdrv_write = vmdk_co_write, .bdrv_close = vmdk_close,
Signature · 1 line
1.7.6.5
PATCH 16/19 block: vdi image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
There is currently nothing that needs to be done for VDI reopen.
--- block/vdi.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
block/vdi.c +7 -0
@@ -454,6 +454,12 @@ static int vdi_open(BlockDriverState *bs, int flags)return -1 ; } +static int vdi_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} + static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,int64_t sector_num,int nb_sectors,int *pnum) {
@@ -761,6 +767,7 @@ static BlockDriver bdrv_vdi = { .bdrv_probe = vdi_probe, .bdrv_open = vdi_open, .bdrv_close = vdi_close, + .bdrv_reopen_prepare = vdi_reopen_prepare, .bdrv_create = vdi_create, .bdrv_co_is_allocated = vdi_co_is_allocated, .bdrv_make_empty = vdi_make_empty,
Signature · 1 line
1.7.6.5
PATCH 17/19 block: vpc image file reopen
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
There is currently nothing that needs to be done for VPC image file reopen.
--- block/vpc.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
block/vpc.c +7 -0
@@ -265,6 +265,12 @@ static int vpc_open(BlockDriverState *bs, int flags)return err; } +static int vpc_reopen_prepare (BDRVReopenState *state, +BlockReopenQueue *queue,Error **errp) +{ +return 0 ; +} +/* * Returns the absolute byte offset of the given sector in the image file. * If the sector is not allocated, -1 is returned instead.
@@ -783,6 +789,7 @@ static BlockDriver bdrv_vpc = { .bdrv_probe = vpc_probe, .bdrv_open = vpc_open, .bdrv_close = vpc_close, + .bdrv_reopen_prepare = vpc_reopen_prepare, .bdrv_create = vpc_create, .bdrv_read = vpc_co_read,
Signature · 1 line
1.7.6.5
PATCH 18/19 block: convert bdrv_commit() to use bdrv_reopen()
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
Currently, bdrv_commit() reopens images r/w itself, via risky _delete() and _open() calls. Use the new safe method for drive reopen.
--- block.c | 48 +++++------------------------------------------- 1 files changed, 5 insertions(+), 43 deletions(-)
block.c +5 -43
@@ -1501,13 +1501,11 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)int bdrv_commit (BlockDriverState *bs) {BlockDriver *drv = bs->drv; -BlockDriver *backing_drv;int64_t sector, total_sectors;int n, ro, open_flags; -int ret =0 , rw_ret =0 ; +int ret =0 ;uint8_t *buf;char filename[1024 ]; -BlockDriverState *bs_rw, *bs_ro;if (!drv)return -ENOMEDIUM ;
@@ -1516,42 +1514,18 @@ int bdrv_commit(BlockDriverState *bs)return -ENOTSUP ; } -if (bs->backing_hd->keep_read_only) { -return -EACCES ; - } -if (bdrv_in_use (bs) ||bdrv_in_use (bs->backing_hd)) {return -EBUSY ; } - backing_drv = bs->backing_hd->drv; ro = bs->backing_hd->read_only;strncpy (filename, bs->backing_hd->filename,sizeof (filename)); open_flags = bs->backing_hd->open_flags;if (ro) { -/* re-open as RW */ -bdrv_delete (bs->backing_hd); - bs->backing_hd =NULL ; - bs_rw =bdrv_new ("" ); - rw_ret =bdrv_open (bs_rw, filename, open_flags |BDRV_O_RDWR , - backing_drv); -if (rw_ret <0 ) { -bdrv_delete (bs_rw); -/* try to re-open read-only */ - bs_ro =bdrv_new ("" ); - ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , - backing_drv); -if (ret <0 ) { -bdrv_delete (bs_ro); -/* drive not functional anymore */ - bs->drv =NULL ; -return ret; - } - bs->backing_hd = bs_ro; -return rw_ret; +if (bdrv_reopen (bs->backing_hd, open_flags |BDRV_O_RDWR ,NULL )) { +return -EACCES ; } - bs->backing_hd = bs_rw; } total_sectors =bdrv_getlength (bs) >>BDRV_SECTOR_BITS ;
@@ -1588,20 +1562,8 @@ ro_cleanup:g_free (buf);if (ro) { -/* re-open as RO */ -bdrv_delete (bs->backing_hd); - bs->backing_hd =NULL ; - bs_ro =bdrv_new ("" ); - ret =bdrv_open (bs_ro, filename, open_flags & ~BDRV_O_RDWR , - backing_drv); -if (ret <0 ) { -bdrv_delete (bs_ro); -/* drive not functional anymore */ - bs->drv =NULL ; -return ret; - } - bs->backing_hd = bs_ro; - bs->backing_hd->keep_read_only =0 ; +/* ignoring error return here */ +bdrv_reopen (bs->backing_hd, open_flags & ~BDRV_O_RDWR ,NULL ); }return ret;
Signature · 1 line
1.7.6.5
PATCH 19/19 block: remove keep_read_only flag from BlockDriverState struct
In reply to Kevin WolfFrom: Jeff Cody <[email protected]>
The keep_read_only flag is no longer used, in favor of the bdrv flag BDRV_O_ALLOW_RDWR.
--- block.c | 2 -- block_int.h | 1 - 2 files changed, 0 insertions(+), 3 deletions(-)
block.c +0 -2
@@ -812,8 +812,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags, flags |=BDRV_O_ALLOW_RDWR ; } - bs->keep_read_only = !(flags &BDRV_O_ALLOW_RDWR ); -/* Open the image */ ret =bdrv_open_common (bs, filename, flags, drv);if (ret <0 ) {
block_int.h +0 -1
@@ -275,7 +275,6 @@ struct BlockDriverState {int64_t total_sectors;/* if we are reading a disk image, give its size in sectors */ int read_only;/* if true, the media is read only */ -int keep_read_only;/* if true, the media was requested to stay read only */ int open_flags;/* flags used to open the file, re-used for re-open */ int encrypted;/* if true, the media is encrypted */ int valid_key;/* if true, a valid encryption key has been set */
Signature · 1 line
1.7.6.5
Quoted 7 lines · Kevin Wolf
The following changes since commit
d3e8f95753114a827f9cd8e819b1d5cc8333f76b:w32: Add implementation of
gmtime_r,localtime_r(2012-09-23 17:09:30 +0000)are available in the git repository at:
git://repo.or.cz/qemu/kevin.gitfor-anthony
Pulled. Thanks.
Regards,
Anthony Liguori
Quoted 41 lines
Jeff Cody (18):
block: correctly set thekeep_read_onlyflag
block: makebdrv_set_enable_write_cache()modifyopen_flags
block: Framework for reopening files safely
block: move aio initialization into a helper function
block: move open flag parsing in raw block drivers to helper functions
block: do not parseBDRV_O_CACHE_WBin block drivers
block: useBDRV_O_NOCACHEinstead ofs->aligned_bufinraw-posix.c
block: purges->aligned_bufands->aligned_buf_sizefromraw-posix.c
block: raw-posix image file reopen
block: raw image file reopen
block: qed image file reopen
block: qcow2 image file reopen
block: qcow image file reopen
block: vmdk image file reopen
block: vdi image file reopen
block: vpc image file reopen
block: convertbdrv_commit()to usebdrv_reopen()
block: removekeep_read_onlyflag from BlockDriverState structKevin Shanahan (1):
blockdev: preserve readonly and snapshot states across media changesblock.c | 299 ++++++++++++++++++++++++++++++++++++++++++++--------- block.h | 18 +++ block/iscsi.c | 4 - block/qcow.c | 10 ++ block/qcow2.c | 10 ++ block/qed.c | 9 ++ block/raw-posix.c | 225 ++++++++++++++++++++++++++++++---------- block/raw-win32.c | 40 ++++---- block/raw.c | 10 ++ block/rbd.c | 6 - block/sheepdog.c | 14 +-- block/vdi.c | 7 ++ block/vmdk.c | 35 ++++++ block/vpc.c | 7 ++ block_int.h | 9 ++- blockdev.c | 2 + 16 files changed, 563 insertions(+), 142 deletions(-)