Skip to content

Commit 2fd6163

Browse files
bonzinikevmw
authored andcommitted
block: convert bdrv_check callback to coroutine_fn
Suggested-by: Kevin Wolf <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Kevin Wolf <[email protected]>
1 parent 2b148f3 commit 2fd6163

File tree

10 files changed

+103
-45
lines changed

10 files changed

+103
-45
lines changed

block.c

+40-3
Original file line numberDiff line numberDiff line change
@@ -3455,17 +3455,54 @@ static void bdrv_delete(BlockDriverState *bs)
34553455
* free of errors) or -errno when an internal error occurred. The results of the
34563456
* check are stored in res.
34573457
*/
3458-
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
3458+
static int coroutine_fn bdrv_co_check(BlockDriverState *bs,
3459+
BdrvCheckResult *res, BdrvCheckMode fix)
34593460
{
34603461
if (bs->drv == NULL) {
34613462
return -ENOMEDIUM;
34623463
}
3463-
if (bs->drv->bdrv_check == NULL) {
3464+
if (bs->drv->bdrv_co_check == NULL) {
34643465
return -ENOTSUP;
34653466
}
34663467

34673468
memset(res, 0, sizeof(*res));
3468-
return bs->drv->bdrv_check(bs, res, fix);
3469+
return bs->drv->bdrv_co_check(bs, res, fix);
3470+
}
3471+
3472+
typedef struct CheckCo {
3473+
BlockDriverState *bs;
3474+
BdrvCheckResult *res;
3475+
BdrvCheckMode fix;
3476+
int ret;
3477+
} CheckCo;
3478+
3479+
static void bdrv_check_co_entry(void *opaque)
3480+
{
3481+
CheckCo *cco = opaque;
3482+
cco->ret = bdrv_co_check(cco->bs, cco->res, cco->fix);
3483+
}
3484+
3485+
int bdrv_check(BlockDriverState *bs,
3486+
BdrvCheckResult *res, BdrvCheckMode fix)
3487+
{
3488+
Coroutine *co;
3489+
CheckCo cco = {
3490+
.bs = bs,
3491+
.res = res,
3492+
.ret = -EINPROGRESS,
3493+
.fix = fix,
3494+
};
3495+
3496+
if (qemu_in_coroutine()) {
3497+
/* Fast-path if already in coroutine context */
3498+
bdrv_check_co_entry(&cco);
3499+
} else {
3500+
co = qemu_coroutine_create(bdrv_check_co_entry, &cco);
3501+
qemu_coroutine_enter(co);
3502+
BDRV_POLL_WHILE(bs, cco.ret == -EINPROGRESS);
3503+
}
3504+
3505+
return cco.ret;
34693506
}
34703507

34713508
/*

block/parallels.c

+11-6
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,9 @@ static coroutine_fn int parallels_co_readv(BlockDriverState *bs,
378378
}
379379

380380

381-
static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
382-
BdrvCheckMode fix)
381+
static int coroutine_fn parallels_co_check(BlockDriverState *bs,
382+
BdrvCheckResult *res,
383+
BdrvCheckMode fix)
383384
{
384385
BDRVParallelsState *s = bs->opaque;
385386
int64_t size, prev_off, high_off;
@@ -394,6 +395,7 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
394395
return size;
395396
}
396397

398+
qemu_co_mutex_lock(&s->lock);
397399
if (s->header_unclean) {
398400
fprintf(stderr, "%s image was not closed correctly\n",
399401
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
@@ -442,11 +444,12 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
442444
prev_off = off;
443445
}
444446

447+
ret = 0;
445448
if (flush_bat) {
446449
ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size);
447450
if (ret < 0) {
448451
res->check_errors++;
449-
return ret;
452+
goto out;
450453
}
451454
}
452455

@@ -465,13 +468,15 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
465468
if (ret < 0) {
466469
error_report_err(local_err);
467470
res->check_errors++;
468-
return ret;
471+
goto out;
469472
}
470473
res->leaks_fixed += count;
471474
}
472475
}
473476

474-
return 0;
477+
out:
478+
qemu_co_mutex_unlock(&s->lock);
479+
return ret;
475480
}
476481

477482

@@ -799,7 +804,7 @@ static BlockDriver bdrv_parallels = {
799804
.bdrv_co_writev = parallels_co_writev,
800805
.supports_backing = true,
801806
.bdrv_co_create_opts = parallels_co_create_opts,
802-
.bdrv_check = parallels_check,
807+
.bdrv_co_check = parallels_co_check,
803808
.create_opts = &parallels_create_opts,
804809
};
805810

block/qcow2.c

+19-4
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,9 @@ int qcow2_mark_consistent(BlockDriverState *bs)
541541
return 0;
542542
}
543543

544-
static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
545-
BdrvCheckMode fix)
544+
static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs,
545+
BdrvCheckResult *result,
546+
BdrvCheckMode fix)
546547
{
547548
int ret = qcow2_check_refcounts(bs, result, fix);
548549
if (ret < 0) {
@@ -559,6 +560,19 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
559560
return ret;
560561
}
561562

563+
static int coroutine_fn qcow2_co_check(BlockDriverState *bs,
564+
BdrvCheckResult *result,
565+
BdrvCheckMode fix)
566+
{
567+
BDRVQcow2State *s = bs->opaque;
568+
int ret;
569+
570+
qemu_co_mutex_lock(&s->lock);
571+
ret = qcow2_co_check_locked(bs, result, fix);
572+
qemu_co_mutex_unlock(&s->lock);
573+
return ret;
574+
}
575+
562576
static int validate_table_offset(BlockDriverState *bs, uint64_t offset,
563577
uint64_t entries, size_t entry_len)
564578
{
@@ -1506,7 +1520,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
15061520
(s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {
15071521
BdrvCheckResult result = {0};
15081522

1509-
ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);
1523+
ret = qcow2_co_check_locked(bs, &result,
1524+
BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);
15101525
if (ret < 0 || result.check_errors) {
15111526
if (ret >= 0) {
15121527
ret = -EIO;
@@ -4413,7 +4428,7 @@ BlockDriver bdrv_qcow2 = {
44134428
.bdrv_inactivate = qcow2_inactivate,
44144429

44154430
.create_opts = &qcow2_create_opts,
4416-
.bdrv_check = qcow2_check,
4431+
.bdrv_co_check = qcow2_co_check,
44174432
.bdrv_amend_options = qcow2_amend_options,
44184433

44194434
.bdrv_detach_aio_context = qcow2_detach_aio_context,

block/qed-check.c

+1
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ static void qed_check_mark_clean(BDRVQEDState *s, BdrvCheckResult *result)
217217
qed_write_header_sync(s);
218218
}
219219

220+
/* Called with table_lock held. */
220221
int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
221222
{
222223
QEDCheck check = {

block/qed-table.c

+9-17
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "qed.h"
1919
#include "qemu/bswap.h"
2020

21-
/* Called either from qed_check or with table_lock held. */
21+
/* Called with table_lock held. */
2222
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
2323
{
2424
QEMUIOVector qiov;
@@ -33,13 +33,9 @@ static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
3333

3434
trace_qed_read_table(s, offset, table);
3535

36-
if (qemu_in_coroutine()) {
37-
qemu_co_mutex_unlock(&s->table_lock);
38-
}
36+
qemu_co_mutex_unlock(&s->table_lock);
3937
ret = bdrv_preadv(s->bs->file, offset, &qiov);
40-
if (qemu_in_coroutine()) {
41-
qemu_co_mutex_lock(&s->table_lock);
42-
}
38+
qemu_co_mutex_lock(&s->table_lock);
4339
if (ret < 0) {
4440
goto out;
4541
}
@@ -67,7 +63,7 @@ static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
6763
* @n: Number of elements
6864
* @flush: Whether or not to sync to disk
6965
*
70-
* Called either from qed_check or with table_lock held.
66+
* Called with table_lock held.
7167
*/
7268
static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
7369
unsigned int index, unsigned int n, bool flush)
@@ -104,13 +100,9 @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
104100
/* Adjust for offset into table */
105101
offset += start * sizeof(uint64_t);
106102

107-
if (qemu_in_coroutine()) {
108-
qemu_co_mutex_unlock(&s->table_lock);
109-
}
103+
qemu_co_mutex_unlock(&s->table_lock);
110104
ret = bdrv_pwritev(s->bs->file, offset, &qiov);
111-
if (qemu_in_coroutine()) {
112-
qemu_co_mutex_lock(&s->table_lock);
113-
}
105+
qemu_co_mutex_lock(&s->table_lock);
114106
trace_qed_write_table_cb(s, table, flush, ret);
115107
if (ret < 0) {
116108
goto out;
@@ -134,7 +126,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s)
134126
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
135127
}
136128

137-
/* Called either from qed_check or with table_lock held. */
129+
/* Called with table_lock held. */
138130
int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
139131
{
140132
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
@@ -148,7 +140,7 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
148140
return qed_write_l1_table(s, index, n);
149141
}
150142

151-
/* Called either from qed_check or with table_lock held. */
143+
/* Called with table_lock held. */
152144
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
153145
{
154146
int ret;
@@ -191,7 +183,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
191183
return qed_read_l2_table(s, request, offset);
192184
}
193185

194-
/* Called either from qed_check or with table_lock held. */
186+
/* Called with table_lock held. */
195187
int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
196188
unsigned int index, unsigned int n, bool flush)
197189
{

block/qed.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -1544,12 +1544,17 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
15441544
}
15451545
}
15461546

1547-
static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
1548-
BdrvCheckMode fix)
1547+
static int bdrv_qed_co_check(BlockDriverState *bs, BdrvCheckResult *result,
1548+
BdrvCheckMode fix)
15491549
{
15501550
BDRVQEDState *s = bs->opaque;
1551+
int ret;
15511552

1552-
return qed_check(s, result, !!fix);
1553+
qemu_co_mutex_lock(&s->table_lock);
1554+
ret = qed_check(s, result, !!fix);
1555+
qemu_co_mutex_unlock(&s->table_lock);
1556+
1557+
return ret;
15531558
}
15541559

15551560
static QemuOptsList qed_create_opts = {
@@ -1609,7 +1614,7 @@ static BlockDriver bdrv_qed = {
16091614
.bdrv_refresh_limits = bdrv_qed_refresh_limits,
16101615
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
16111616
.bdrv_co_invalidate_cache = bdrv_qed_co_invalidate_cache,
1612-
.bdrv_check = bdrv_qed_check,
1617+
.bdrv_co_check = bdrv_qed_co_check,
16131618
.bdrv_detach_aio_context = bdrv_qed_detach_aio_context,
16141619
.bdrv_attach_aio_context = bdrv_qed_attach_aio_context,
16151620
.bdrv_co_drain_begin = bdrv_qed_co_drain_begin,

block/vdi.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,8 @@ static void vdi_header_print(VdiHeader *header)
263263
}
264264
#endif
265265

266-
static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res,
267-
BdrvCheckMode fix)
266+
static int coroutine_fn vdi_co_check(BlockDriverState *bs, BdrvCheckResult *res,
267+
BdrvCheckMode fix)
268268
{
269269
/* TODO: additional checks possible. */
270270
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
@@ -908,7 +908,7 @@ static BlockDriver bdrv_vdi = {
908908
.bdrv_get_info = vdi_get_info,
909909

910910
.create_opts = &vdi_create_opts,
911-
.bdrv_check = vdi_check,
911+
.bdrv_co_check = vdi_co_check,
912912
};
913913

914914
static void bdrv_vdi_init(void)

block/vhdx.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1944,8 +1944,9 @@ static int coroutine_fn vhdx_co_create_opts(const char *filename, QemuOpts *opts
19441944
* r/w and any log has already been replayed, so there is nothing (currently)
19451945
* for us to do here
19461946
*/
1947-
static int vhdx_check(BlockDriverState *bs, BdrvCheckResult *result,
1948-
BdrvCheckMode fix)
1947+
static int coroutine_fn vhdx_co_check(BlockDriverState *bs,
1948+
BdrvCheckResult *result,
1949+
BdrvCheckMode fix)
19491950
{
19501951
BDRVVHDXState *s = bs->opaque;
19511952

@@ -2006,7 +2007,7 @@ static BlockDriver bdrv_vhdx = {
20062007
.bdrv_co_writev = vhdx_co_writev,
20072008
.bdrv_co_create_opts = vhdx_co_create_opts,
20082009
.bdrv_get_info = vhdx_get_info,
2009-
.bdrv_check = vhdx_check,
2010+
.bdrv_co_check = vhdx_co_check,
20102011
.bdrv_has_zero_init = bdrv_has_zero_init_1,
20112012

20122013
.create_opts = &vhdx_create_opts,

block/vmdk.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -2221,8 +2221,9 @@ static ImageInfo *vmdk_get_extent_info(VmdkExtent *extent)
22212221
return info;
22222222
}
22232223

2224-
static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
2225-
BdrvCheckMode fix)
2224+
static int coroutine_fn vmdk_co_check(BlockDriverState *bs,
2225+
BdrvCheckResult *result,
2226+
BdrvCheckMode fix)
22262227
{
22272228
BDRVVmdkState *s = bs->opaque;
22282229
VmdkExtent *extent = NULL;
@@ -2391,7 +2392,7 @@ static BlockDriver bdrv_vmdk = {
23912392
.instance_size = sizeof(BDRVVmdkState),
23922393
.bdrv_probe = vmdk_probe,
23932394
.bdrv_open = vmdk_open,
2394-
.bdrv_check = vmdk_check,
2395+
.bdrv_co_check = vmdk_co_check,
23952396
.bdrv_reopen_prepare = vmdk_reopen_prepare,
23962397
.bdrv_child_perm = bdrv_format_default_perms,
23972398
.bdrv_co_preadv = vmdk_co_preadv,

include/block/block_int.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,9 @@ struct BlockDriver {
307307
* Returns 0 for completed check, -errno for internal errors.
308308
* The check results are stored in result.
309309
*/
310-
int (*bdrv_check)(BlockDriverState *bs, BdrvCheckResult *result,
311-
BdrvCheckMode fix);
310+
int coroutine_fn (*bdrv_co_check)(BlockDriverState *bs,
311+
BdrvCheckResult *result,
312+
BdrvCheckMode fix);
312313

313314
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
314315
BlockDriverAmendStatusCB *status_cb,

0 commit comments

Comments
 (0)