Skip to content

Commit e4c4bfe

Browse files
Ming Leiaxboe
authored andcommitted
ublk: fix canceling flag handling in batch I/O recovery
Two issues with ubq->canceling flag handling: 1) In ublk_queue_reset_io_flags(), ubq->canceling is set outside cancel_lock, violating the locking requirement. Move it inside the spinlock-protected section. 2) In ublk_batch_unprep_io(), when rolling back after a batch prep failure, if the queue became ready during prep (which cleared canceling), the flag is not restored when the queue becomes not-ready again. This allows new requests to be queued to uninitialized IO slots. Fix by restoring ubq->canceling = true under cancel_lock when the queue transitions from ready to not-ready during rollback. Reported-by: Jens Axboe <[email protected]> Fixes: 3f38507 ("ublk: fix batch I/O recovery -ENODEV error") Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent dbc635c commit e4c4bfe

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

drivers/block/ublk_drv.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,9 +2806,9 @@ static void ublk_queue_reset_io_flags(struct ublk_queue *ubq)
28062806
spin_lock(&ubq->cancel_lock);
28072807
for (j = 0; j < ubq->q_depth; j++)
28082808
ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED;
2809+
ubq->canceling = false;
28092810
spin_unlock(&ubq->cancel_lock);
28102811
ubq->fail_io = false;
2811-
ubq->canceling = false;
28122812
}
28132813

28142814
/* device can only be started after all IOs are ready */
@@ -3435,10 +3435,15 @@ static int ublk_batch_unprep_io(struct ublk_queue *ubq,
34353435

34363436
/*
34373437
* If queue was ready before this decrement, it won't be anymore,
3438-
* so we need to decrement the queue ready count too.
3438+
* so we need to decrement the queue ready count and restore the
3439+
* canceling flag to prevent new requests from being queued.
34393440
*/
3440-
if (ublk_queue_ready(ubq))
3441+
if (ublk_queue_ready(ubq)) {
34413442
data->ub->nr_queue_ready--;
3443+
spin_lock(&ubq->cancel_lock);
3444+
ubq->canceling = true;
3445+
spin_unlock(&ubq->cancel_lock);
3446+
}
34423447
ubq->nr_io_ready--;
34433448

34443449
ublk_io_lock(io);

0 commit comments

Comments
 (0)