1 /* 2 * block_copy API 3 * 4 * Copyright (C) 2013 Proxmox Server Solutions 5 * Copyright (c) 2019 Virtuozzo International GmbH. 6 * 7 * Authors: 8 * Dietmar Maurer (dietmar@proxmox.com) 9 * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2 or later. 12 * See the COPYING file in the top-level directory. 13 */ 14 15 #ifndef BLOCK_COPY_H 16 #define BLOCK_COPY_H 17 18 #include "block/block.h" 19 #include "qemu/co-shared-resource.h" 20 21 typedef struct BlockCopyInFlightReq { 22 int64_t start_byte; 23 int64_t end_byte; 24 QLIST_ENTRY(BlockCopyInFlightReq) list; 25 CoQueue wait_queue; /* coroutines blocked on this request */ 26 } BlockCopyInFlightReq; 27 28 typedef void (*ProgressBytesCallbackFunc)(int64_t bytes, void *opaque); 29 typedef void (*ProgressResetCallbackFunc)(void *opaque); 30 typedef struct BlockCopyState { 31 /* 32 * BdrvChild objects are not owned or managed by block-copy. They are 33 * provided by block-copy user and user is responsible for appropriate 34 * permissions on these children. 35 */ 36 BdrvChild *source; 37 BdrvChild *target; 38 BdrvDirtyBitmap *copy_bitmap; 39 int64_t cluster_size; 40 bool use_copy_range; 41 int64_t copy_size; 42 uint64_t len; 43 QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs; 44 45 BdrvRequestFlags write_flags; 46 47 /* 48 * skip_unallocated: 49 * 50 * Used by sync=top jobs, which first scan the source node for unallocated 51 * areas and clear them in the copy_bitmap. During this process, the bitmap 52 * is thus not fully initialized: It may still have bits set for areas that 53 * are unallocated and should actually not be copied. 54 * 55 * This is indicated by skip_unallocated. 56 * 57 * In this case, block_copy() will query the source’s allocation status, 58 * skip unallocated regions, clear them in the copy_bitmap, and invoke 59 * block_copy_reset_unallocated() every time it does. 60 */ 61 bool skip_unallocated; 62 63 /* progress_bytes_callback: called when some copying progress is done. */ 64 ProgressBytesCallbackFunc progress_bytes_callback; 65 66 /* 67 * progress_reset_callback: called when some bytes reset from copy_bitmap 68 * (see @skip_unallocated above). The callee is assumed to recalculate how 69 * many bytes remain based on the dirty bit count of copy_bitmap. 70 */ 71 ProgressResetCallbackFunc progress_reset_callback; 72 void *progress_opaque; 73 74 SharedResource *mem; 75 } BlockCopyState; 76 77 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, 78 int64_t cluster_size, 79 BdrvRequestFlags write_flags, 80 Error **errp); 81 82 void block_copy_set_callbacks( 83 BlockCopyState *s, 84 ProgressBytesCallbackFunc progress_bytes_callback, 85 ProgressResetCallbackFunc progress_reset_callback, 86 void *progress_opaque); 87 88 void block_copy_state_free(BlockCopyState *s); 89 90 int64_t block_copy_reset_unallocated(BlockCopyState *s, 91 int64_t offset, int64_t *count); 92 93 int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes, 94 bool *error_is_read); 95 96 #endif /* BLOCK_COPY_H */ 97