From ac3a8726644d4783eacf54212d23db01d1d30044 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 27 Oct 2014 10:18:43 +0100 Subject: util: introduce MIN_NON_ZERO at least in block layer we have the case of limits being defined for a BlockDriverState. However, in this context often zero (0) has the special meanining of undefined which means no limit. If two of those limits are combined and the minimum is needed the minimum function should only return zero if both parameters are zero. Signed-off-by: Peter Lieven Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi --- include/qemu/osdep.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 1565404f7e..c0324344d5 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -68,6 +68,12 @@ typedef signed int int_fast16_t; #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +/* Minimum function that returns zero only iff both values are zero. + * Intended for use with unsigned values only. */ +#ifndef MIN_NON_ZERO +#define MIN_NON_ZERO(a, b) (((a) != 0 && (a) < (b)) ? (a) : (b)) +#endif + #ifndef ROUND_UP #define ROUND_UP(n,d) (((n) + (d) - 1) & -(d)) #endif -- cgit v1.2.3 From 2647fab57d5d5e38b36f8dbda367d688045e6a2d Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 27 Oct 2014 10:18:44 +0100 Subject: BlockLimits: introduce max_transfer_length Signed-off-by: Peter Lieven Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi --- include/block/block_int.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/block/block_int.h b/include/block/block_int.h index 8898c6c51b..a293e92852 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -289,6 +289,9 @@ typedef struct BlockLimits { /* optimal transfer length in sectors */ int opt_transfer_length; + /* maximal transfer length in sectors */ + int max_transfer_length; + /* memory alignment so that no bounce buffer is needed */ size_t opt_mem_alignment; } BlockLimits; -- cgit v1.2.3 From 94054183daffaa41cd77ced9301c01a01027923a Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 24 Oct 2014 15:57:32 +0200 Subject: qcow2: Optimize bdrv_make_empty() bdrv_make_empty() is currently only called if the current image represents an external snapshot that has been committed to its base image; it is therefore unlikely to have internal snapshots. In this case, bdrv_make_empty() can be greatly sped up by emptying the L1 and refcount table (while having the dirty flag set, which only works for compat=1.1) and creating a trivial refcount structure. If there are snapshots or for compat=0.10, fall back to the simple implementation (discard all clusters). [Applied s/clusters/cluster/ typo fix suggested by Eric Blake --Stefan] Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Reviewed-by: Eric Blake Message-id: 1414159063-25977-4-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/block.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 341054dcf7..b1f4385f03 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -498,6 +498,8 @@ typedef enum { BLKDBG_PWRITEV_ZERO, BLKDBG_PWRITEV_DONE, + BLKDBG_EMPTY_IMAGE_PREPARE, + BLKDBG_EVENT_MAX, } BlkDebugEvent; -- cgit v1.2.3 From 345f9e1b04ee18dcb1454dcec49781d5e06ecb60 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 24 Oct 2014 15:57:33 +0200 Subject: blockjob: Introduce block_job_complete_sync() Implement block_job_complete_sync() by doing the exact same thing as block_job_cancel_sync() does, only with calling block_job_complete() instead of block_job_cancel(). Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Reviewed-by: Eric Blake Message-id: 1414159063-25977-5-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/blockjob.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/block/blockjob.h b/include/block/blockjob.h index acb399f87d..ab11a0f622 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -272,6 +272,21 @@ bool block_job_is_paused(BlockJob *job); */ int block_job_cancel_sync(BlockJob *job); +/** + * block_job_complete_sync: + * @job: The job to be completed. + * @errp: Error object which may be set by block_job_complete(); this is not + * necessarily set on every error, the job return value has to be + * checked as well. + * + * Synchronously complete the job. The completion callback is called before the + * function returns, unless it is NULL (which is permissible when using this + * function). + * + * Returns the return value from the job. + */ +int block_job_complete_sync(BlockJob *job, Error **errp); + /** * block_job_iostatus_reset: * @job: The job whose I/O status should be reset. -- cgit v1.2.3 From ef6dbf1e46ebd1d41ab669df5bba0bbdec6bd374 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 24 Oct 2014 15:57:34 +0200 Subject: blockjob: Add "ready" field When a block job signals readiness, this is currently reported only through QMP. If qemu wants to use block jobs for internal tasks, there needs to be another way to correctly detect when a block job may be completed. For this reason, introduce a bool "ready" which is set when the block job may be completed. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Kevin Wolf Message-id: 1414159063-25977-6-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/blockjob.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/block/blockjob.h b/include/block/blockjob.h index ab11a0f622..9694f130b0 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -91,6 +91,11 @@ struct BlockJob { */ bool busy; + /** + * Set to true when the job is ready to be completed. + */ + bool ready; + /** Status that is published by the query-block-jobs QMP API */ BlockDeviceIoStatus iostatus; -- cgit v1.2.3 From 77485434206bbbfbb7f6a446866f6a327b062d5e Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Mon, 27 Oct 2014 11:12:50 +0100 Subject: block: Add status callback to bdrv_amend_options() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depending on the changed options and the image format, bdrv_amend_options() may take a significant amount of time. In these cases, a way to be informed about the operation's status is desirable. Since the operation is rather complex and may fundamentally change the image, implementing it as AIO or a coroutine does not seem feasible. On the other hand, implementing it as a block job would be significantly more difficult than a simple callback and would not add benefits other than progress report to the amending operation, because it should not actually be run as a block job at all. A callback may not be very pretty, but it's very easy to implement and perfectly fits its purpose here. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: BenoƮt Canet Reviewed-by: Kevin Wolf Message-id: 1414404776-4919-2-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/block.h | 8 +++++++- include/block/block_int.h | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index b1f4385f03..5d13282fa9 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -268,7 +268,13 @@ typedef enum { int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); -int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts); +/* The units of offset and total_work_size may be chosen arbitrarily by the + * block driver; total_work_size may change during the course of the amendment + * operation */ +typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset, + int64_t total_work_size); +int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts, + BlockDriverAmendStatusCB *status_cb); /* external snapshots */ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index a293e92852..a1c17b9578 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -232,7 +232,8 @@ struct BlockDriver { int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result, BdrvCheckMode fix); - int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts); + int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts, + BlockDriverAmendStatusCB *status_cb); void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); -- cgit v1.2.3 From dec7d421f85578b0949292336f784f55ac84812d Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 21 Oct 2014 12:03:54 +0100 Subject: blockjob: add block_job_defer_to_main_loop() Block jobs will run in the BlockDriverState's AioContext, which may not always be the QEMU main loop. There are some block layer APIs that are either not thread-safe or risk lock ordering problems. This includes bdrv_unref(), bdrv_close(), and anything that calls bdrv_drain_all(). The block_job_defer_to_main_loop() API allows a block job to schedule a function to run in the main loop with the BlockDriverState AioContext held. This function will be used to perform cleanup and backing chain manipulations in block jobs. Signed-off-by: Stefan Hajnoczi Reviewed-by: Max Reitz Message-id: 1413889440-32577-6-git-send-email-stefanha@redhat.com --- include/block/blockjob.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 9694f130b0..b6d4ebbe03 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -315,4 +315,23 @@ void block_job_iostatus_reset(BlockJob *job); BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs, BlockdevOnError on_err, int is_read, int error); + +typedef void BlockJobDeferToMainLoopFn(BlockJob *job, void *opaque); + +/** + * block_job_defer_to_main_loop: + * @job: The job + * @fn: The function to run in the main loop + * @opaque: The opaque value that is passed to @fn + * + * Execute a given function in the main loop with the BlockDriverState + * AioContext acquired. Block jobs must call bdrv_unref(), bdrv_close(), and + * anything that uses bdrv_drain_all() in the main loop. + * + * The @job AioContext is held while @fn executes. + */ +void block_job_defer_to_main_loop(BlockJob *job, + BlockJobDeferToMainLoopFn *fn, + void *opaque); + #endif -- cgit v1.2.3 From 5b98db0ad3ad2919c71572085d104765bad6c658 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 21 Oct 2014 12:03:55 +0100 Subject: block: add bdrv_drain() Now that op blockers are in use, we can ensure that no other sources are generating I/O on a BlockDriverState. Therefore it is possible to drain requests for a single BDS. Signed-off-by: Stefan Hajnoczi Reviewed-by: Max Reitz Message-id: 1413889440-32577-7-git-send-email-stefanha@redhat.com --- 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 5d13282fa9..13e453736c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -334,6 +334,7 @@ int bdrv_flush(BlockDriverState *bs); int coroutine_fn bdrv_co_flush(BlockDriverState *bs); int bdrv_flush_all(void); void bdrv_close_all(void); +void bdrv_drain(BlockDriverState *bs); void bdrv_drain_all(void); int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); -- cgit v1.2.3