@@ -51,6 +51,7 @@ typedef struct BlockCopyCallState {
51
51
int ret ;
52
52
bool finished ;
53
53
QemuCoSleepState * sleep_state ;
54
+ bool cancelled ;
54
55
55
56
/* OUT parameters */
56
57
bool error_is_read ;
@@ -594,7 +595,7 @@ block_copy_dirty_clusters(BlockCopyCallState *call_state)
594
595
assert (QEMU_IS_ALIGNED (offset , s -> cluster_size ));
595
596
assert (QEMU_IS_ALIGNED (bytes , s -> cluster_size ));
596
597
597
- while (bytes && aio_task_pool_status (aio ) == 0 ) {
598
+ while (bytes && aio_task_pool_status (aio ) == 0 && ! call_state -> cancelled ) {
598
599
BlockCopyTask * task ;
599
600
int64_t status_bytes ;
600
601
@@ -707,7 +708,7 @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
707
708
do {
708
709
ret = block_copy_dirty_clusters (call_state );
709
710
710
- if (ret == 0 ) {
711
+ if (ret == 0 && ! call_state -> cancelled ) {
711
712
ret = block_copy_wait_one (call_state -> s , call_state -> offset ,
712
713
call_state -> bytes );
713
714
}
@@ -721,7 +722,7 @@ static int coroutine_fn block_copy_common(BlockCopyCallState *call_state)
721
722
* 2. We have waited for some intersecting block-copy request
722
723
* It may have failed and produced new dirty bits.
723
724
*/
724
- } while (ret > 0 );
725
+ } while (ret > 0 && ! call_state -> cancelled );
725
726
726
727
call_state -> finished = true;
727
728
@@ -801,12 +802,19 @@ bool block_copy_call_finished(BlockCopyCallState *call_state)
801
802
802
803
bool block_copy_call_succeeded (BlockCopyCallState * call_state )
803
804
{
804
- return call_state -> finished && call_state -> ret == 0 ;
805
+ return call_state -> finished && !call_state -> cancelled &&
806
+ call_state -> ret == 0 ;
805
807
}
806
808
807
809
bool block_copy_call_failed (BlockCopyCallState * call_state )
808
810
{
809
- return call_state -> finished && call_state -> ret < 0 ;
811
+ return call_state -> finished && !call_state -> cancelled &&
812
+ call_state -> ret < 0 ;
813
+ }
814
+
815
+ bool block_copy_call_cancelled (BlockCopyCallState * call_state )
816
+ {
817
+ return call_state -> cancelled ;
810
818
}
811
819
812
820
int block_copy_call_status (BlockCopyCallState * call_state , bool * error_is_read )
@@ -818,6 +826,12 @@ int block_copy_call_status(BlockCopyCallState *call_state, bool *error_is_read)
818
826
return call_state -> ret ;
819
827
}
820
828
829
+ void block_copy_call_cancel (BlockCopyCallState * call_state )
830
+ {
831
+ call_state -> cancelled = true;
832
+ block_copy_kick (call_state );
833
+ }
834
+
821
835
BdrvDirtyBitmap * block_copy_dirty_bitmap (BlockCopyState * s )
822
836
{
823
837
return s -> copy_bitmap ;
0 commit comments