@ -45,13 +45,12 @@ static void bdrv_parent_cb_resize(BlockDriverState *bs);
static int coroutine_fn bdrv_co_do_pwrite_zeroes ( BlockDriverState * bs ,
int64_t offset , int64_t bytes , BdrvRequestFlags flags ) ;
static void bdrv_parent_drained_begin ( BlockDriverState * bs , BdrvChild * ignore ,
bool ignore_bds_parents )
static void bdrv_parent_drained_begin ( BlockDriverState * bs , BdrvChild * ignore )
{
BdrvChild * c , * next ;
QLIST_FOREACH_SAFE ( c , & bs - > parents , next_parent , next ) {
if ( c = = ignore | | ( ignore_bds_parents & & c - > klass - > parent_is_bds ) ) {
if ( c = = ignore ) {
continue ;
}
bdrv_parent_drained_begin_single ( c , false ) ;
@ -70,13 +69,12 @@ void bdrv_parent_drained_end_single(BdrvChild *c)
}
}
static void bdrv_parent_drained_end ( BlockDriverState * bs , BdrvChild * ignore ,
bool ignore_bds_parents )
static void bdrv_parent_drained_end ( BlockDriverState * bs , BdrvChild * ignore )
{
BdrvChild * c ;
QLIST_FOREACH ( c , & bs - > parents , next_parent ) {
if ( c = = ignore | | ( ignore_bds_parents & & c - > klass - > parent_is_bds ) ) {
if ( c = = ignore ) {
continue ;
}
bdrv_parent_drained_end_single ( c ) ;
@ -242,7 +240,6 @@ typedef struct {
bool begin ;
bool poll ;
BdrvChild * parent ;
bool ignore_bds_parents ;
} BdrvCoDrainData ;
/* Returns true if BDRV_POLL_WHILE() should go into a blocking aio_poll() */
@ -269,9 +266,8 @@ static bool bdrv_drain_poll_top_level(BlockDriverState *bs,
}
static void bdrv_do_drained_begin ( BlockDriverState * bs , BdrvChild * parent ,
bool ignore_bds_parents , bool poll ) ;
static void bdrv_do_drained_end ( BlockDriverState * bs , BdrvChild * parent ,
bool ignore_bds_parents ) ;
bool poll ) ;
static void bdrv_do_drained_end ( BlockDriverState * bs , BdrvChild * parent ) ;
static void bdrv_co_drain_bh_cb ( void * opaque )
{
@ -284,11 +280,10 @@ static void bdrv_co_drain_bh_cb(void *opaque)
aio_context_acquire ( ctx ) ;
bdrv_dec_in_flight ( bs ) ;
if ( data - > begin ) {
bdrv_do_drained_begin ( bs , data - > parent , data - > ignore_bds_parents ,
data - > poll ) ;
bdrv_do_drained_begin ( bs , data - > parent , data - > poll ) ;
} else {
assert ( ! data - > poll ) ;
bdrv_do_drained_end ( bs , data - > parent , data - > ignore_bds_parents ) ;
bdrv_do_drained_end ( bs , data - > parent ) ;
}
aio_context_release ( ctx ) ;
} else {
@ -303,7 +298,6 @@ static void bdrv_co_drain_bh_cb(void *opaque)
static void coroutine_fn bdrv_co_yield_to_drain ( BlockDriverState * bs ,
bool begin ,
BdrvChild * parent ,
bool ignore_bds_parents ,
bool poll )
{
BdrvCoDrainData data ;
@ -321,7 +315,6 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
. done = false ,
. begin = begin ,
. parent = parent ,
. ignore_bds_parents = ignore_bds_parents ,
. poll = poll ,
} ;
@ -353,8 +346,7 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
}
}
void bdrv_do_drained_begin_quiesce ( BlockDriverState * bs ,
BdrvChild * parent , bool ignore_bds_parents )
void bdrv_do_drained_begin_quiesce ( BlockDriverState * bs , BdrvChild * parent )
{
IO_OR_GS_CODE ( ) ;
assert ( ! qemu_in_coroutine ( ) ) ;
@ -362,9 +354,7 @@ void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
/* Stop things in parent-to-child order */
if ( qatomic_fetch_inc ( & bs - > quiesce_counter ) = = 0 ) {
aio_disable_external ( bdrv_get_aio_context ( bs ) ) ;
/* TODO Remove ignore_bds_parents, we don't consider it any more */
bdrv_parent_drained_begin ( bs , parent , false ) ;
bdrv_parent_drained_begin ( bs , parent ) ;
if ( bs - > drv & & bs - > drv - > bdrv_drain_begin ) {
bs - > drv - > bdrv_drain_begin ( bs ) ;
}
@ -372,14 +362,14 @@ void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
}
static void bdrv_do_drained_begin ( BlockDriverState * bs , BdrvChild * parent ,
bool ignore_bds_parents , bool poll )
bool poll )
{
if ( qemu_in_coroutine ( ) ) {
bdrv_co_yield_to_drain ( bs , true , parent , ignore_bds_parents , poll ) ;
bdrv_co_yield_to_drain ( bs , true , parent , poll ) ;
return ;
}
bdrv_do_drained_begin_quiesce ( bs , parent , ignore_bds_parents ) ;
bdrv_do_drained_begin_quiesce ( bs , parent ) ;
/*
* Wait for drained requests to finish .
@ -391,7 +381,6 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
* nodes .
*/
if ( poll ) {
assert ( ! ignore_bds_parents ) ;
BDRV_POLL_WHILE ( bs , bdrv_drain_poll_top_level ( bs , parent ) ) ;
}
}
@ -399,20 +388,19 @@ static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
void bdrv_drained_begin ( BlockDriverState * bs )
{
IO_OR_GS_CODE ( ) ;
bdrv_do_drained_begin ( bs , NULL , false , true ) ;
bdrv_do_drained_begin ( bs , NULL , true ) ;
}
/**
* This function does not poll , nor must any of its recursively called
* functions .
*/
static void bdrv_do_drained_end ( BlockDriverState * bs , BdrvChild * parent ,
bool ignore_bds_parents )
static void bdrv_do_drained_end ( BlockDriverState * bs , BdrvChild * parent )
{
int old_quiesce_counter ;
if ( qemu_in_coroutine ( ) ) {
bdrv_co_yield_to_drain ( bs , false , parent , ignore_bds_parents , false ) ;
bdrv_co_yield_to_drain ( bs , false , parent , false ) ;
return ;
}
assert ( bs - > quiesce_counter > 0 ) ;
@ -423,9 +411,7 @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent,
if ( bs - > drv & & bs - > drv - > bdrv_drain_end ) {
bs - > drv - > bdrv_drain_end ( bs ) ;
}
/* TODO Remove ignore_bds_parents, we don't consider it any more */
bdrv_parent_drained_end ( bs , parent , false ) ;
bdrv_parent_drained_end ( bs , parent ) ;
aio_enable_external ( bdrv_get_aio_context ( bs ) ) ;
}
}
@ -433,7 +419,7 @@ static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent,
void bdrv_drained_end ( BlockDriverState * bs )
{
IO_OR_GS_CODE ( ) ;
bdrv_do_drained_end ( bs , NULL , false ) ;
bdrv_do_drained_end ( bs , NULL ) ;
}
void bdrv_drain ( BlockDriverState * bs )
@ -491,7 +477,7 @@ void bdrv_drain_all_begin(void)
GLOBAL_STATE_CODE ( ) ;
if ( qemu_in_coroutine ( ) ) {
bdrv_co_yield_to_drain ( NULL , true , NULL , true , true ) ;
bdrv_co_yield_to_drain ( NULL , true , NULL , true ) ;
return ;
}
@ -516,7 +502,7 @@ void bdrv_drain_all_begin(void)
AioContext * aio_context = bdrv_get_aio_context ( bs ) ;
aio_context_acquire ( aio_context ) ;
bdrv_do_drained_begin ( bs , NULL , true , false ) ;
bdrv_do_drained_begin ( bs , NULL , false ) ;
aio_context_release ( aio_context ) ;
}
@ -536,7 +522,7 @@ void bdrv_drain_all_end_quiesce(BlockDriverState *bs)
g_assert ( ! bs - > refcnt ) ;
while ( bs - > quiesce_counter ) {
bdrv_do_drained_end ( bs , NULL , true ) ;
bdrv_do_drained_end ( bs , NULL ) ;
}
}
@ -558,7 +544,7 @@ void bdrv_drain_all_end(void)
AioContext * aio_context = bdrv_get_aio_context ( bs ) ;
aio_context_acquire ( aio_context ) ;
bdrv_do_drained_end ( bs , NULL , true ) ;
bdrv_do_drained_end ( bs , NULL ) ;
aio_context_release ( aio_context ) ;
}