ide: Clean up ide_trim_co_entry() to be idiomatic coroutine code
The previous commit did a minimal conversion of the callback based state machine for TRIM to a coroutine in order to fix a bug. Refactor it to actually look like normal coroutine based code, which improves its readability. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-ID: <20260421161132.99878-6-kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Kevin Wolf committed
Apr 21, 2026 at 18:11 UTC
c1c71a7e167fdabaa9827d00c0be3aeafebdd921
1 file changed
+39
-48
hw/ide/core.c
+39
-48
@@ -420,18 +420,15 @@ typedef struct TrimAIOCB {
420
QEMUBH *bh;
421
int ret;
422
QEMUIOVector *qiov;
423
- int i, j;
423
+ bool canceled;
424
} TrimAIOCB;
425
426
static void trim_aio_cancel(BlockAIOCB *acb)
427
{
428
TrimAIOCB *iocb = container_of(acb, TrimAIOCB, common);
429
430
- /* Exit the loop so ide_issue_trim_cb will not continue */
431
- iocb->j = iocb->qiov->niov - 1;
432
- iocb->i = (iocb->qiov->iov[iocb->j].iov_len / 8) - 1;
433
-
434
- iocb->ret = -ECANCELED;
430
+ /* Exit the loop so ide_trim_co_entry will not continue */
431
+ iocb->canceled = true;
432
}
433
434
static const AIOCBInfo trim_aiocb_info = {
@@ -458,60 +455,55 @@ static void coroutine_fn ide_trim_co_entry(void *opaque)
455
{
456
TrimAIOCB *iocb = opaque;
457
IDEState *s = iocb->s;
461
- int ret = 0;
458
+ int i, j;
459
+ int ret;
460
461
/* Paired with blk_end_request in ide_trim_bh_cb() */
462
blk_co_start_request(s->blk);
463
466
-loop:
467
- if (iocb->i >= 0) {
468
- if (ret >= 0) {
469
- block_acct_done(blk_get_stats(s->blk), &s->acct);
470
- } else {
471
- block_acct_failed(blk_get_stats(s->blk), &s->acct);
472
- }
473
- }
464
+ for (j = 0; j < iocb->qiov->niov; j++) {
465
+ for (i = 0; i < iocb->qiov->iov[j].iov_len / 8; i++) {
466
+ uint64_t *buffer = iocb->qiov->iov[j].iov_base;
467
475
- if (ret >= 0) {
476
- while (iocb->j < iocb->qiov->niov) {
477
- int j = iocb->j;
478
- while (++iocb->i < iocb->qiov->iov[j].iov_len / 8) {
479
- int i = iocb->i;
480
- uint64_t *buffer = iocb->qiov->iov[j].iov_base;
468
+ /* 6-byte LBA + 2-byte range per entry */
469
+ uint64_t entry = le64_to_cpu(buffer[i]);
470
+ uint64_t sector = entry & 0x0000ffffffffffffULL;
471
+ uint16_t count = entry >> 48;
472
482
- /* 6-byte LBA + 2-byte range per entry */
483
- uint64_t entry = le64_to_cpu(buffer[i]);
484
- uint64_t sector = entry & 0x0000ffffffffffffULL;
485
- uint16_t count = entry >> 48;
473
+ if (count == 0) {
474
+ continue;
475
+ }
476
487
- if (count == 0) {
488
- continue;
489
- }
477
+ if (iocb->canceled) {
478
+ iocb->ret = -ECANCELED;
479
+ goto done;
480
+ }
481
491
- if (!ide_sect_range_ok(s, sector, count)) {
492
- block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_UNMAP);
493
- iocb->ret = -EINVAL;
494
- goto done;
495
- }
482
+ if (!ide_sect_range_ok(s, sector, count)) {
483
+ block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_UNMAP);
484
+ iocb->ret = -EINVAL;
485
+ goto done;
486
+ }
487
497
- block_acct_start(blk_get_stats(s->blk), &s->acct,
498
- count << BDRV_SECTOR_BITS, BLOCK_ACCT_UNMAP);
488
+ block_acct_start(blk_get_stats(s->blk), &s->acct,
489
+ count << BDRV_SECTOR_BITS, BLOCK_ACCT_UNMAP);
490
500
- /* Got an entry! Submit and exit. */
501
- ret = blk_co_pdiscard(s->blk,
502
- sector << BDRV_SECTOR_BITS,
503
- count << BDRV_SECTOR_BITS,
504
- BDRV_REQ_NO_QUEUE);
505
- goto loop;
491
+ /* Got an entry! Submit and exit. */
492
+ ret = blk_co_pdiscard(s->blk,
493
+ sector << BDRV_SECTOR_BITS,
494
+ count << BDRV_SECTOR_BITS,
495
+ BDRV_REQ_NO_QUEUE);
496
+ if (ret >= 0) {
497
+ block_acct_done(blk_get_stats(s->blk), &s->acct);
498
+ } else {
499
+ iocb->ret = ret;
500
+ block_acct_failed(blk_get_stats(s->blk), &s->acct);
501
+ goto done;
502
}
507
-
508
- iocb->j++;
509
- iocb->i = -1;
503
}
511
- } else {
512
- iocb->ret = ret;
504
}
505
506
+ iocb->ret = 0;
507
done:
508
if (iocb->bh) {
509
replay_bh_schedule_event(iocb->bh);
@@ -533,8 +525,7 @@ BlockAIOCB *ide_issue_trim(
525
&DEVICE(dev)->mem_reentrancy_guard);
526
iocb->ret = 0;
527
iocb->qiov = qiov;
536
- iocb->i = -1;
537
- iocb->j = 0;
528
+ iocb->canceled = false;
529
530
co = qemu_coroutine_create(ide_trim_co_entry, iocb);
531
aio_co_enter(qemu_get_current_aio_context(), co);