1beb5f545SVladimir Sementsov-Ogievskiy /* 2beb5f545SVladimir Sementsov-Ogievskiy * block_copy API 3beb5f545SVladimir Sementsov-Ogievskiy * 4beb5f545SVladimir Sementsov-Ogievskiy * Copyright (C) 2013 Proxmox Server Solutions 5beb5f545SVladimir Sementsov-Ogievskiy * Copyright (c) 2019 Virtuozzo International GmbH. 6beb5f545SVladimir Sementsov-Ogievskiy * 7beb5f545SVladimir Sementsov-Ogievskiy * Authors: 8beb5f545SVladimir Sementsov-Ogievskiy * Dietmar Maurer (dietmar@proxmox.com) 9beb5f545SVladimir Sementsov-Ogievskiy * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> 10beb5f545SVladimir Sementsov-Ogievskiy * 11beb5f545SVladimir Sementsov-Ogievskiy * This work is licensed under the terms of the GNU GPL, version 2 or later. 12beb5f545SVladimir Sementsov-Ogievskiy * See the COPYING file in the top-level directory. 13beb5f545SVladimir Sementsov-Ogievskiy */ 14beb5f545SVladimir Sementsov-Ogievskiy 15beb5f545SVladimir Sementsov-Ogievskiy #ifndef BLOCK_COPY_H 16beb5f545SVladimir Sementsov-Ogievskiy #define BLOCK_COPY_H 17beb5f545SVladimir Sementsov-Ogievskiy 18e2c1c34fSMarkus Armbruster #include "block/block-common.h" 19e2c1c34fSMarkus Armbruster #include "qemu/progress_meter.h" 20beb5f545SVladimir Sementsov-Ogievskiy 21149009beSEmanuele Giuseppe Esposito /* All APIs are thread-safe */ 22149009beSEmanuele Giuseppe Esposito 23de4641b4SVladimir Sementsov-Ogievskiy typedef void (*BlockCopyAsyncCallbackFunc)(void *opaque); 24397f4e9dSVladimir Sementsov-Ogievskiy typedef struct BlockCopyState BlockCopyState; 25de4641b4SVladimir Sementsov-Ogievskiy typedef struct BlockCopyCallState BlockCopyCallState; 26beb5f545SVladimir Sementsov-Ogievskiy 2700e30f05SVladimir Sementsov-Ogievskiy BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, 28006e845bSVladimir Sementsov-Ogievskiy BlockDriverState *copy_bitmap_bs, 291f7252e8SVladimir Sementsov-Ogievskiy const BdrvDirtyBitmap *bitmap, 300fd05c8dSVladimir Sementsov-Ogievskiy bool discard_source, 31*9484ad6cSFiona Ebner uint64_t min_cluster_size, 32b518e9e9SVladimir Sementsov-Ogievskiy Error **errp); 330f4b02b7SVladimir Sementsov-Ogievskiy 34f8b9504bSVladimir Sementsov-Ogievskiy /* Function should be called prior any actual copy request */ 35f8b9504bSVladimir Sementsov-Ogievskiy void block_copy_set_copy_opts(BlockCopyState *s, bool use_copy_range, 36f8b9504bSVladimir Sementsov-Ogievskiy bool compress); 37d0ebeca1SVladimir Sementsov-Ogievskiy void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm); 38d0ebeca1SVladimir Sementsov-Ogievskiy 39beb5f545SVladimir Sementsov-Ogievskiy void block_copy_state_free(BlockCopyState *s); 40beb5f545SVladimir Sementsov-Ogievskiy 41177541e6SVladimir Sementsov-Ogievskiy void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes); 427ff9579eSKevin Wolf 437ff9579eSKevin Wolf int64_t coroutine_fn GRAPH_RDLOCK 447ff9579eSKevin Wolf block_copy_reset_unallocated(BlockCopyState *s, int64_t offset, int64_t *count); 45beb5f545SVladimir Sementsov-Ogievskiy 468719091fSVladimir Sementsov-Ogievskiy int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes, 4715df6e69SVladimir Sementsov-Ogievskiy bool ignore_ratelimit, uint64_t timeout_ns, 4815df6e69SVladimir Sementsov-Ogievskiy BlockCopyAsyncCallbackFunc cb, 4915df6e69SVladimir Sementsov-Ogievskiy void *cb_opaque); 50beb5f545SVladimir Sementsov-Ogievskiy 51de4641b4SVladimir Sementsov-Ogievskiy /* 52de4641b4SVladimir Sementsov-Ogievskiy * Run block-copy in a coroutine, create corresponding BlockCopyCallState 53de4641b4SVladimir Sementsov-Ogievskiy * object and return pointer to it. Never returns NULL. 54de4641b4SVladimir Sementsov-Ogievskiy * 55de4641b4SVladimir Sementsov-Ogievskiy * Caller is responsible to call block_copy_call_free() to free 56de4641b4SVladimir Sementsov-Ogievskiy * BlockCopyCallState object. 5726be9d62SVladimir Sementsov-Ogievskiy * 5826be9d62SVladimir Sementsov-Ogievskiy * @max_workers means maximum of parallel coroutines to execute sub-requests, 5926be9d62SVladimir Sementsov-Ogievskiy * must be > 0. 6026be9d62SVladimir Sementsov-Ogievskiy * 6126be9d62SVladimir Sementsov-Ogievskiy * @max_chunk means maximum length for one IO operation. Zero means unlimited. 62de4641b4SVladimir Sementsov-Ogievskiy */ 63de4641b4SVladimir Sementsov-Ogievskiy BlockCopyCallState *block_copy_async(BlockCopyState *s, 64de4641b4SVladimir Sementsov-Ogievskiy int64_t offset, int64_t bytes, 6526be9d62SVladimir Sementsov-Ogievskiy int max_workers, int64_t max_chunk, 66de4641b4SVladimir Sementsov-Ogievskiy BlockCopyAsyncCallbackFunc cb, 67de4641b4SVladimir Sementsov-Ogievskiy void *cb_opaque); 68de4641b4SVladimir Sementsov-Ogievskiy 69de4641b4SVladimir Sementsov-Ogievskiy /* 70de4641b4SVladimir Sementsov-Ogievskiy * Free finished BlockCopyCallState. Trying to free running 71de4641b4SVladimir Sementsov-Ogievskiy * block-copy will crash. 72de4641b4SVladimir Sementsov-Ogievskiy */ 73de4641b4SVladimir Sementsov-Ogievskiy void block_copy_call_free(BlockCopyCallState *call_state); 74de4641b4SVladimir Sementsov-Ogievskiy 75de4641b4SVladimir Sementsov-Ogievskiy /* 76de4641b4SVladimir Sementsov-Ogievskiy * Note, that block-copy call is marked finished prior to calling 77de4641b4SVladimir Sementsov-Ogievskiy * the callback. 78de4641b4SVladimir Sementsov-Ogievskiy */ 79de4641b4SVladimir Sementsov-Ogievskiy bool block_copy_call_finished(BlockCopyCallState *call_state); 80de4641b4SVladimir Sementsov-Ogievskiy bool block_copy_call_succeeded(BlockCopyCallState *call_state); 81de4641b4SVladimir Sementsov-Ogievskiy bool block_copy_call_failed(BlockCopyCallState *call_state); 82a6d23d56SVladimir Sementsov-Ogievskiy bool block_copy_call_cancelled(BlockCopyCallState *call_state); 83de4641b4SVladimir Sementsov-Ogievskiy int block_copy_call_status(BlockCopyCallState *call_state, bool *error_is_read); 84de4641b4SVladimir Sementsov-Ogievskiy 857e032df0SVladimir Sementsov-Ogievskiy void block_copy_set_speed(BlockCopyState *s, uint64_t speed); 867e032df0SVladimir Sementsov-Ogievskiy void block_copy_kick(BlockCopyCallState *call_state); 877e032df0SVladimir Sementsov-Ogievskiy 88a6d23d56SVladimir Sementsov-Ogievskiy /* 89a6d23d56SVladimir Sementsov-Ogievskiy * Cancel running block-copy call. 90a6d23d56SVladimir Sementsov-Ogievskiy * 91a6d23d56SVladimir Sementsov-Ogievskiy * Cancel leaves block-copy state valid: dirty bits are correct and you may use 92a6d23d56SVladimir Sementsov-Ogievskiy * cancel + <run block_copy with same parameters> to emulate pause/resume. 93a6d23d56SVladimir Sementsov-Ogievskiy * 94a6d23d56SVladimir Sementsov-Ogievskiy * Note also, that the cancel is async: it only marks block-copy call to be 95a6d23d56SVladimir Sementsov-Ogievskiy * cancelled. So, the call may be cancelled (block_copy_call_cancelled() reports 96a6d23d56SVladimir Sementsov-Ogievskiy * true) but not yet finished (block_copy_call_finished() reports false). 97a6d23d56SVladimir Sementsov-Ogievskiy */ 98a6d23d56SVladimir Sementsov-Ogievskiy void block_copy_call_cancel(BlockCopyCallState *call_state); 99a6d23d56SVladimir Sementsov-Ogievskiy 100397f4e9dSVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s); 101b518e9e9SVladimir Sementsov-Ogievskiy int64_t block_copy_cluster_size(BlockCopyState *s); 102397f4e9dSVladimir Sementsov-Ogievskiy void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip); 103397f4e9dSVladimir Sementsov-Ogievskiy 104beb5f545SVladimir Sementsov-Ogievskiy #endif /* BLOCK_COPY_H */ 105