diff --git a/module/bdev/nvme/bdev_nvme.c b/module/bdev/nvme/bdev_nvme.c index e9940ddf5..7e0ecf5bd 100644 --- a/module/bdev/nvme/bdev_nvme.c +++ b/module/bdev/nvme/bdev_nvme.c @@ -1263,12 +1263,39 @@ bdev_nvme_reset_complete(struct nvme_ctrlr *nvme_ctrlr, bool success) _bdev_nvme_reset_complete); } +static void +bdev_nvme_reset_create_qpairs_failed(struct spdk_io_channel_iter *i, int status) +{ + struct nvme_ctrlr *nvme_ctrlr = spdk_io_channel_iter_get_io_device(i); + + bdev_nvme_reset_complete(nvme_ctrlr, false); +} + +static void +bdev_nvme_reset_destroy_qpair(struct spdk_io_channel_iter *i) +{ + struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); + struct nvme_ctrlr_channel *ctrlr_ch = spdk_io_channel_get_ctx(ch); + + bdev_nvme_destroy_qpair(ctrlr_ch); + + spdk_for_each_channel_continue(i, 0); +} + static void bdev_nvme_reset_create_qpairs_done(struct spdk_io_channel_iter *i, int status) { struct nvme_ctrlr *nvme_ctrlr = spdk_io_channel_iter_get_io_device(i); - bdev_nvme_reset_complete(nvme_ctrlr, status == 0); + if (status == 0) { + bdev_nvme_reset_complete(nvme_ctrlr, true); + } else { + /* Delete the added qpairs and quiesce ctrlr to make the states clean. */ + spdk_for_each_channel(nvme_ctrlr, + bdev_nvme_reset_destroy_qpair, + NULL, + bdev_nvme_reset_create_qpairs_failed); + } } static void @@ -1329,17 +1356,6 @@ bdev_nvme_reset_ctrlr(struct spdk_io_channel_iter *i, int status) nvme_ctrlr, 0); } -static void -bdev_nvme_reset_destroy_qpair(struct spdk_io_channel_iter *i) -{ - struct spdk_io_channel *ch = spdk_io_channel_iter_get_channel(i); - struct nvme_ctrlr_channel *ctrlr_ch = spdk_io_channel_get_ctx(ch); - - bdev_nvme_destroy_qpair(ctrlr_ch); - - spdk_for_each_channel_continue(i, 0); -} - static void _bdev_nvme_reset(void *ctx) {