@@ -4124,19 +4124,26 @@ void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue)
4124
4124
*
4125
4125
* All affected nodes must be drained between bdrv_reopen_queue() and
4126
4126
* bdrv_reopen_multiple().
4127
+ *
4128
+ * To be called from the main thread, with all other AioContexts unlocked.
4127
4129
*/
4128
4130
int bdrv_reopen_multiple (BlockReopenQueue * bs_queue , Error * * errp )
4129
4131
{
4130
4132
int ret = -1 ;
4131
4133
BlockReopenQueueEntry * bs_entry , * next ;
4134
+ AioContext * ctx ;
4132
4135
Transaction * tran = tran_new ();
4133
4136
g_autoptr (GHashTable ) found = NULL ;
4134
4137
g_autoptr (GSList ) refresh_list = NULL ;
4135
4138
4139
+ assert (qemu_get_current_aio_context () == qemu_get_aio_context ());
4136
4140
assert (bs_queue != NULL );
4137
4141
4138
4142
QTAILQ_FOREACH (bs_entry , bs_queue , entry ) {
4143
+ ctx = bdrv_get_aio_context (bs_entry -> state .bs );
4144
+ aio_context_acquire (ctx );
4139
4145
ret = bdrv_flush (bs_entry -> state .bs );
4146
+ aio_context_release (ctx );
4140
4147
if (ret < 0 ) {
4141
4148
error_setg_errno (errp , - ret , "Error flushing drive" );
4142
4149
goto abort ;
@@ -4145,7 +4152,10 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
4145
4152
4146
4153
QTAILQ_FOREACH (bs_entry , bs_queue , entry ) {
4147
4154
assert (bs_entry -> state .bs -> quiesce_counter > 0 );
4155
+ ctx = bdrv_get_aio_context (bs_entry -> state .bs );
4156
+ aio_context_acquire (ctx );
4148
4157
ret = bdrv_reopen_prepare (& bs_entry -> state , bs_queue , tran , errp );
4158
+ aio_context_release (ctx );
4149
4159
if (ret < 0 ) {
4150
4160
goto abort ;
4151
4161
}
@@ -4188,7 +4198,10 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
4188
4198
* to first element.
4189
4199
*/
4190
4200
QTAILQ_FOREACH_REVERSE (bs_entry , bs_queue , entry ) {
4201
+ ctx = bdrv_get_aio_context (bs_entry -> state .bs );
4202
+ aio_context_acquire (ctx );
4191
4203
bdrv_reopen_commit (& bs_entry -> state );
4204
+ aio_context_release (ctx );
4192
4205
}
4193
4206
4194
4207
tran_commit (tran );
@@ -4197,7 +4210,10 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
4197
4210
BlockDriverState * bs = bs_entry -> state .bs ;
4198
4211
4199
4212
if (bs -> drv -> bdrv_reopen_commit_post ) {
4213
+ ctx = bdrv_get_aio_context (bs );
4214
+ aio_context_acquire (ctx );
4200
4215
bs -> drv -> bdrv_reopen_commit_post (& bs_entry -> state );
4216
+ aio_context_release (ctx );
4201
4217
}
4202
4218
}
4203
4219
@@ -4208,7 +4224,10 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
4208
4224
tran_abort (tran );
4209
4225
QTAILQ_FOREACH_SAFE (bs_entry , bs_queue , entry , next ) {
4210
4226
if (bs_entry -> prepared ) {
4227
+ ctx = bdrv_get_aio_context (bs_entry -> state .bs );
4228
+ aio_context_acquire (ctx );
4211
4229
bdrv_reopen_abort (& bs_entry -> state );
4230
+ aio_context_release (ctx );
4212
4231
}
4213
4232
}
4214
4233
@@ -4218,23 +4237,39 @@ int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
4218
4237
return ret ;
4219
4238
}
4220
4239
4221
- int bdrv_reopen_set_read_only (BlockDriverState * bs , bool read_only ,
4222
- Error * * errp )
4240
+ int bdrv_reopen (BlockDriverState * bs , QDict * opts , bool keep_old_opts ,
4241
+ Error * * errp )
4223
4242
{
4224
- int ret ;
4243
+ AioContext * ctx = bdrv_get_aio_context ( bs ) ;
4225
4244
BlockReopenQueue * queue ;
4226
- QDict * opts = qdict_new ();
4227
-
4228
- qdict_put_bool (opts , BDRV_OPT_READ_ONLY , read_only );
4245
+ int ret ;
4229
4246
4230
4247
bdrv_subtree_drained_begin (bs );
4231
- queue = bdrv_reopen_queue (NULL , bs , opts , true);
4248
+ if (ctx != qemu_get_aio_context ()) {
4249
+ aio_context_release (ctx );
4250
+ }
4251
+
4252
+ queue = bdrv_reopen_queue (NULL , bs , opts , keep_old_opts );
4232
4253
ret = bdrv_reopen_multiple (queue , errp );
4254
+
4255
+ if (ctx != qemu_get_aio_context ()) {
4256
+ aio_context_acquire (ctx );
4257
+ }
4233
4258
bdrv_subtree_drained_end (bs );
4234
4259
4235
4260
return ret ;
4236
4261
}
4237
4262
4263
+ int bdrv_reopen_set_read_only (BlockDriverState * bs , bool read_only ,
4264
+ Error * * errp )
4265
+ {
4266
+ QDict * opts = qdict_new ();
4267
+
4268
+ qdict_put_bool (opts , BDRV_OPT_READ_ONLY , read_only );
4269
+
4270
+ return bdrv_reopen (bs , opts , true, errp );
4271
+ }
4272
+
4238
4273
/*
4239
4274
* Take a BDRVReopenState and check if the value of 'backing' in the
4240
4275
* reopen_state->options QDict is valid or not.
0 commit comments