From fa166538743d4e28de7374c41332c3e448826f4b Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 13 Jun 2016 12:56:35 -0600 Subject: block: Assert that flags are in range Add a new BDRV_REQ_MASK constant, and use it to make sure that caller flags are always valid. Tested with 'make check' and with qemu-iotests on both '-raw' and '-qcow2'; the only failure turned up was fixed in the previous commit. Signed-off-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- include/block/block.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 54cca28..8cabcdd 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -65,6 +65,9 @@ typedef enum { BDRV_REQ_MAY_UNMAP = 0x4, BDRV_REQ_NO_SERIALISING = 0x8, BDRV_REQ_FUA = 0x10, + + /* Mask of valid flags */ + BDRV_REQ_MASK = 0x1f, } BdrvRequestFlags; typedef struct BlockSizes { -- cgit v1.1 From 244483e64ee726cc89a1e05bed2be0ed37071403 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 2 Jun 2016 11:41:52 +0200 Subject: block: Byte-based bdrv_co_do_copy_on_readv() In a first step to convert the common I/O path to work on bytes rather than sectors, this converts the copy-on-read logic that is used by bdrv_aligned_preadv(). Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- include/block/block.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 8cabcdd..9c3a62c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -404,10 +404,14 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi); ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs); +void bdrv_round_sectors_to_clusters(BlockDriverState *bs, + int64_t sector_num, int nb_sectors, + int64_t *cluster_sector_num, + int *cluster_nb_sectors); void bdrv_round_to_clusters(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - int64_t *cluster_sector_num, - int *cluster_nb_sectors); + int64_t offset, unsigned int bytes, + int64_t *cluster_offset, + unsigned int *cluster_bytes); const char *bdrv_get_encrypted_filename(BlockDriverState *bs); void bdrv_get_backing_filename(BlockDriverState *bs, -- cgit v1.1 From f1e8474115d6be7eda14092050ffa2b031afb729 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 9 Jun 2016 16:36:00 +0200 Subject: block: Introduce bdrv_preadv() We already have a byte-based bdrv_pwritev(), but the read counterpart was still missing. This commit adds it. Signed-off-by: Kevin Wolf Reviewed-by: Fam Zheng Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- include/block/block.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 9c3a62c..9c63d07 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -235,6 +235,7 @@ int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags); int bdrv_pread(BlockDriverState *bs, int64_t offset, void *buf, int count); +int bdrv_preadv(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov); int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf, int count); int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov); -- cgit v1.1 From 5ddda0b8f0c07c8082c87d248c8eb23f43fd44a1 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 9 Jun 2016 16:50:16 +0200 Subject: block: Make .bdrv_load_vmstate() vectored This brings it in line with .bdrv_save_vmstate(). Signed-off-by: Kevin Wolf Reviewed-by: Fam Zheng Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- include/block/block.h | 1 + include/block/block_int.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 9c63d07..733a8ec 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -431,6 +431,7 @@ void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); +int bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size); diff --git a/include/block/block_int.h b/include/block/block_int.h index 8a4963c..f9a32cc 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -226,8 +226,8 @@ struct BlockDriver { int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos); - int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf, - int64_t pos, int size); + int (*bdrv_load_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, + int64_t pos); int (*bdrv_change_backing_file)(BlockDriverState *bs, const char *backing_file, const char *backing_fmt); -- cgit v1.1 From 1a8ae8221799901dc399a174b52a970d8e6f976a Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Thu, 9 Jun 2016 16:24:44 +0200 Subject: block: Make bdrv_load/save_vmstate coroutine_fns This allows drivers to share code between normal I/O and vmstate accesses. Signed-off-by: Kevin Wolf Reviewed-by: Fam Zheng Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- include/block/block_int.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/block/block_int.h b/include/block/block_int.h index f9a32cc..1fe0811 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -224,10 +224,12 @@ struct BlockDriver { int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi); ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs); - int (*bdrv_save_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos); - int (*bdrv_load_vmstate)(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos); + int coroutine_fn (*bdrv_save_vmstate)(BlockDriverState *bs, + QEMUIOVector *qiov, + int64_t pos); + int coroutine_fn (*bdrv_load_vmstate)(BlockDriverState *bs, + QEMUIOVector *qiov, + int64_t pos); int (*bdrv_change_backing_file)(BlockDriverState *bs, const char *backing_file, const char *backing_fmt); -- cgit v1.1 From c9d20029f43a08c6362a655c2c5272612186a004 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 1 Jun 2016 17:13:47 +0200 Subject: block: Remove bs->zero_beyond_eof It is always true for open images now. Signed-off-by: Kevin Wolf Reviewed-by: Fam Zheng Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- include/block/block_int.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/block/block_int.h b/include/block/block_int.h index 1fe0811..16c43e2 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -451,9 +451,6 @@ struct BlockDriverState { /* I/O Limits */ BlockLimits bl; - /* Whether produces zeros when read beyond eof */ - bool zero_beyond_eof; - /* Alignment requirement for offset/length of I/O requests */ unsigned int request_alignment; /* Flags honored during pwrite (so far: BDRV_REQ_FUA) */ -- cgit v1.1 From 274fccee2bf63702b34e3923b1e50a49147a7918 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 10 Jun 2016 20:57:47 +0200 Subject: block/mirror: Fix target backing BDS Currently, we are trying to move the backing BDS from the source to the target in bdrv_replace_in_backing_chain() which is called from mirror_exit(). However, mirror_complete() already tries to open the target's backing chain with a call to bdrv_open_backing_file(). First, we should only set the target's backing BDS once. Second, the mirroring block job has a better idea of what to set it to than the generic code in bdrv_replace_in_backing_chain() (in fact, the latter's conditions on when to move the backing BDS from source to target are not really correct). Therefore, remove that code from bdrv_replace_in_backing_chain() and leave it to mirror_complete(). Depending on what kind of mirroring is performed, we furthermore want to use different strategies to open the target's backing chain: - If blockdev-mirror is used, we can assume the user made sure that the target already has the correct backing chain. In particular, we should not try to open a backing file if the target does not have any yet. - If drive-mirror with mode=absolute-paths is used, we can and should reuse the already existing chain of nodes that the source BDS is in. In case of sync=full, no backing BDS is required; with sync=top, we just link the source's backing BDS to the target, and with sync=none, we use the source BDS as the target's backing BDS. We should not try to open these backing files anew because this would lead to two BDSs existing per physical file in the backing chain, and we would like to avoid such concurrent access. - If drive-mirror with mode=existing is used, we have to use the information provided in the physical image file which means opening the target's backing chain completely anew, just as it has been done already. If the target's backing chain shares images with the source, this may lead to multiple BDSs per physical image file. But since we cannot reliably ascertain this case, there is nothing we can do about it. Signed-off-by: Max Reitz Message-id: 20160610185750.30956-3-mreitz@redhat.com Reviewed-by: Kevin Wolf Reviewed-by: Fam Zheng Signed-off-by: Max Reitz --- include/block/block_int.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/block/block_int.h b/include/block/block_int.h index 16c43e2..688c6be 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -509,6 +509,20 @@ struct BlockBackendRootState { BlockdevDetectZeroesOptions detect_zeroes; }; +typedef enum BlockMirrorBackingMode { + /* Reuse the existing backing chain from the source for the target. + * - sync=full: Set backing BDS to NULL. + * - sync=top: Use source's backing BDS. + * - sync=none: Use source as the backing BDS. */ + MIRROR_SOURCE_BACKING_CHAIN, + + /* Open the target's backing chain completely anew */ + MIRROR_OPEN_BACKING_CHAIN, + + /* Do not change the target's backing BDS after job completion */ + MIRROR_LEAVE_BACKING_CHAIN, +} BlockMirrorBackingMode; + static inline BlockDriverState *backing_bs(BlockDriverState *bs) { return bs->backing ? bs->backing->bs : NULL; @@ -671,6 +685,7 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base, * @granularity: The chosen granularity for the dirty bitmap. * @buf_size: The amount of data that can be in flight at one time. * @mode: Whether to collapse all images in the chain to the target. + * @backing_mode: How to establish the target's backing chain after completion. * @on_source_error: The action to take upon error reading from the source. * @on_target_error: The action to take upon error writing to the target. * @unmap: Whether to unmap target where source sectors only contain zeroes. @@ -686,7 +701,8 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base, void mirror_start(BlockDriverState *bs, BlockDriverState *target, const char *replaces, int64_t speed, uint32_t granularity, int64_t buf_size, - MirrorSyncMode mode, BlockdevOnError on_source_error, + MirrorSyncMode mode, BlockMirrorBackingMode backing_mode, + BlockdevOnError on_source_error, BlockdevOnError on_target_error, bool unmap, BlockCompletionFunc *cb, -- cgit v1.1