diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fe38792d..2c059a2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,11 @@ they did not account for PCI devices being inserted or removed while the caller returned from these APIs. Existing users of these APIs should switch to spdk_pci_for_each_device instead. +### nvmf + +Added a 'subsystem' parameter to spdk_nvmf_transport_stop_listen_async. When not NULL, +it will only disconnect qpairs for controllers associated with the specified subsystem. + ## v21.10 Structure `spdk_nvmf_target_opts` has been extended with new member `discovery_filter` which allows to specify diff --git a/include/spdk/nvmf.h b/include/spdk/nvmf.h index 085fbcc10..13e9f1308 100644 --- a/include/spdk/nvmf.h +++ b/include/spdk/nvmf.h @@ -1109,12 +1109,15 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport, * Stop accepting new connections at the provided address. * * This is a counterpart to spdk_nvmf_tgt_listen_ext(). It differs - * from spdk_nvmf_transport_stop_listen() in that it also destroys all + * from spdk_nvmf_transport_stop_listen() in that it also destroys * qpairs that are connected to the specified listener. Because * this function disconnects the qpairs, it has to be asynchronous. * * \param transport The transport associated with the listen address. * \param trid The address to stop listening at. + * \param subsystem The subsystem to match for qpairs with the specified + * trid. If NULL, it will disconnect all qpairs with the + * specified trid. * \param cb_fn The function to call on completion. * \param cb_arg The argument to pass to the cb_fn. * @@ -1122,6 +1125,7 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport, */ int spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport, const struct spdk_nvme_transport_id *trid, + struct spdk_nvmf_subsystem *subsystem, spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, void *cb_arg); diff --git a/lib/nvmf/nvmf_rpc.c b/lib/nvmf/nvmf_rpc.c index d9518552f..a9d6a3b87 100644 --- a/lib/nvmf/nvmf_rpc.c +++ b/lib/nvmf/nvmf_rpc.c @@ -792,8 +792,8 @@ nvmf_rpc_listen_paused(struct spdk_nvmf_subsystem *subsystem, } else if (ctx->op == NVMF_RPC_LISTEN_REMOVE) { rc = spdk_nvmf_subsystem_remove_listener(subsystem, &ctx->trid); if (rc == 0) { - spdk_nvmf_transport_stop_listen_async(ctx->transport, &ctx->trid, nvmf_rpc_stop_listen_async_done, - ctx); + spdk_nvmf_transport_stop_listen_async(ctx->transport, &ctx->trid, subsystem, + nvmf_rpc_stop_listen_async_done, ctx); return; } SPDK_ERRLOG("Unable to remove listener, rc %d\n", rc); diff --git a/lib/nvmf/transport.c b/lib/nvmf/transport.c index d255e7290..a261b565a 100644 --- a/lib/nvmf/transport.c +++ b/lib/nvmf/transport.c @@ -363,6 +363,7 @@ spdk_nvmf_transport_stop_listen(struct spdk_nvmf_transport *transport, struct nvmf_stop_listen_ctx { struct spdk_nvmf_transport *transport; struct spdk_nvme_transport_id trid; + struct spdk_nvmf_subsystem *subsystem; spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn; void *cb_arg; }; @@ -409,7 +410,10 @@ nvmf_stop_listen_disconnect_qpairs(struct spdk_io_channel_iter *i) } if (!spdk_nvme_transport_id_compare(&ctx->trid, &tmp_trid)) { - spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); + if (ctx->subsystem == NULL || + ctx->subsystem == qpair->ctrlr->subsys) { + spdk_nvmf_qpair_disconnect(qpair, NULL, NULL); + } } } spdk_for_each_channel_continue(i, 0); @@ -418,6 +422,7 @@ nvmf_stop_listen_disconnect_qpairs(struct spdk_io_channel_iter *i) int spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport, const struct spdk_nvme_transport_id *trid, + struct spdk_nvmf_subsystem *subsystem, spdk_nvmf_tgt_subsystem_listen_done_fn cb_fn, void *cb_arg) { @@ -429,6 +434,7 @@ spdk_nvmf_transport_stop_listen_async(struct spdk_nvmf_transport *transport, } ctx->trid = *trid; + ctx->subsystem = subsystem; ctx->transport = transport; ctx->cb_fn = cb_fn; ctx->cb_arg = cb_arg;