ublk: reset the FETCH round in release also without a disk

The release of /dev/ublkcN resets the queues only when the device has a
disk. Without one it skips ublk_reset_ch_dev():

  server fetches, never starts;         old server exits
  or STOP_DEV removed the disk           release: no disk → skip reset
                                         ios stay ACTIVE / CANCELED,
                                         nr_io_ready stays full
  new server opens /dev/ublkcN           FETCH: -EBUSY (still ready), or
                                         -EINVAL after a partial round
                                         → the device can only be deleted

All uring_cmds are done when the release work runs, with or without a
disk, so the reset is safe either way. Do it in both cases. Then a new
server can fetch and start the device again, as the STOP_DEV entry in
Documentation/block/ublk.rst says ("ublk device is ready for the new
process").

Fixes: 82a8a30c58 ("ublk: improve detection and handling of ublk server exit")
Cc: stable@vger.kernel.org
Tested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20261011063555.1142277-5-tom.leiming@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Ming Lei 2026-10-11 01:35:47 -05:00 committed by Jens Axboe
parent b59e96011d
commit f06ca594ea

View File

@ -2551,12 +2551,13 @@ static void ublk_ch_release_work_fn(struct work_struct *work)
}
/*
* disk isn't attached yet, either device isn't live, or it has
* been removed already, so we needn't to do anything
* No disk: the device isn't live, or it has been removed already.
* There are no requests to abort, but the round still has to be
* reset, so that a new server can fetch and start the device.
*/
disk = ublk_get_disk(ub);
if (!disk)
goto out;
goto reset;
/*
* All uring_cmd are done now, so abort any request outstanding to
@ -2617,10 +2618,9 @@ static void ublk_ch_release_work_fn(struct work_struct *work)
unlock:
mutex_unlock(&ub->mutex);
ublk_put_disk(disk);
reset:
/* all uring_cmd has been done now, reset device & ubq */
ublk_reset_ch_dev(ub);
out:
clear_bit(UB_STATE_OPEN, &ub->state);
/* put the reference grabbed in ublk_ch_release() */