diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2024-06-05 19:52:43 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2024-06-05 19:52:43 +0000 |
| commit | f6d434f110fd95e346f18fb09a6f91f36b528d2d (patch) | |
| tree | 3f36f077c61765ea07fe75b1b76a5c2dd07e1bf8 /sys/dev | |
| parent | 8a082ca89fc007850b302f4eead2f9b6eb2ccbe0 (diff) | |
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/nvmf/host/nvmf.c | 49 | ||||
| -rw-r--r-- | sys/dev/nvmf/host/nvmf_aer.c | 2 | ||||
| -rw-r--r-- | sys/dev/nvmf/host/nvmf_var.h | 1 |
3 files changed, 51 insertions, 1 deletions
diff --git a/sys/dev/nvmf/host/nvmf.c b/sys/dev/nvmf/host/nvmf.c index 086df5f637c9..1e7fce42b2a3 100644 --- a/sys/dev/nvmf/host/nvmf.c +++ b/sys/dev/nvmf/host/nvmf.c @@ -804,6 +804,55 @@ nvmf_rescan_ns(struct nvmf_softc *sc, uint32_t nsid) free(data, M_NVMF); } +static void +nvmf_purge_namespaces(struct nvmf_softc *sc, uint32_t first_nsid, + uint32_t next_valid_nsid) +{ + struct nvmf_namespace *ns; + + for (uint32_t nsid = first_nsid; nsid < next_valid_nsid; nsid++) + { + /* XXX: Needs locking around sc->ns[]. */ + ns = sc->ns[nsid - 1]; + if (ns != NULL) { + nvmf_destroy_ns(ns); + sc->ns[nsid - 1] = NULL; + + nvmf_sim_rescan_ns(sc, nsid); + } + } +} + +static bool +nvmf_rescan_ns_cb(struct nvmf_softc *sc, uint32_t nsid, + const struct nvme_namespace_data *data, void *arg) +{ + uint32_t *last_nsid = arg; + + /* Check for any gaps prior to this namespace. */ + nvmf_purge_namespaces(sc, *last_nsid + 1, nsid); + *last_nsid = nsid; + + nvmf_rescan_ns_1(sc, nsid, data); + return (true); +} + +void +nvmf_rescan_all_ns(struct nvmf_softc *sc) +{ + uint32_t last_nsid; + + last_nsid = 0; + if (!nvmf_scan_active_namespaces(sc, nvmf_rescan_ns_cb, &last_nsid)) + return; + + /* + * Check for any namespace devices after the last active + * namespace. + */ + nvmf_purge_namespaces(sc, last_nsid + 1, sc->cdata->nn + 1); +} + int nvmf_passthrough_cmd(struct nvmf_softc *sc, struct nvme_pt_command *pt, bool admin) diff --git a/sys/dev/nvmf/host/nvmf_aer.c b/sys/dev/nvmf/host/nvmf_aer.c index 4c950f1518d0..2f7f177d0421 100644 --- a/sys/dev/nvmf/host/nvmf_aer.c +++ b/sys/dev/nvmf/host/nvmf_aer.c @@ -62,7 +62,7 @@ nvmf_handle_changed_namespaces(struct nvmf_softc *sc, * probably just rescan the entire set of namespaces. */ if (ns_list->ns[0] == 0xffffffff) { - device_printf(sc->dev, "too many changed namespaces\n"); + nvmf_rescan_all_ns(sc); return; } diff --git a/sys/dev/nvmf/host/nvmf_var.h b/sys/dev/nvmf/host/nvmf_var.h index e0f6d33d2a73..2fa0216baab8 100644 --- a/sys/dev/nvmf/host/nvmf_var.h +++ b/sys/dev/nvmf/host/nvmf_var.h @@ -148,6 +148,7 @@ int nvmf_init_ivars(struct nvmf_ivars *ivars, struct nvmf_handoff_host *hh); void nvmf_free_ivars(struct nvmf_ivars *ivars); void nvmf_disconnect(struct nvmf_softc *sc); void nvmf_rescan_ns(struct nvmf_softc *sc, uint32_t nsid); +void nvmf_rescan_all_ns(struct nvmf_softc *sc); int nvmf_passthrough_cmd(struct nvmf_softc *sc, struct nvme_pt_command *pt, bool admin); |
