Page MenuHomeFreeBSD

D32963.id98421.diff
No OneTemporary

D32963.id98421.diff

Index: sys/dev/nvme/nvme.c
===================================================================
--- sys/dev/nvme/nvme.c
+++ sys/dev/nvme/nvme.c
@@ -294,12 +294,14 @@
return;
ns = &ctrlr->ns[nsid - 1];
+ nvme_ns_construct(ns, nsid, ctrlr, NVME_REASON_FLAGGED);
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
cons = &nvme_consumer[i];
if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL &&
(ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL)
ns->cons_cookie[i] = (*cons->ns_fn)(ns, ctrlr_cookie);
}
+ ns->flags &= ~NVME_NS_FLAG_CHANGED;
}
struct nvme_consumer *
Index: sys/dev/nvme/nvme_ctrlr.c
===================================================================
--- sys/dev/nvme/nvme_ctrlr.c
+++ sys/dev/nvme/nvme_ctrlr.c
@@ -586,7 +586,7 @@
for (i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) {
ns = &ctrlr->ns[i];
- nvme_ns_construct(ns, i+1, ctrlr);
+ nvme_ns_construct(ns, i+1, ctrlr, NVME_REASON_RESET);
}
return (0);
Index: sys/dev/nvme/nvme_ns.c
===================================================================
--- sys/dev/nvme/nvme_ns.c
+++ sys/dev/nvme/nvme_ns.c
@@ -510,7 +510,7 @@
int
nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
- struct nvme_controller *ctrlr)
+ struct nvme_controller *ctrlr, enum nvme_ctor_reason why)
{
struct make_dev_args md_args;
struct nvme_completion_poll_status status;
@@ -549,10 +549,13 @@
* If the size of is zero, chances are this isn't a valid
* namespace (eg one that's not been configured yet). The
* standard says the entire id will be zeros, so this is a
- * cheap way to test for that.
+ * cheap way to test for that. If we previously added this
+ * device, then it's now gone.
*/
- if (ns->data.nsze == 0)
- return (ENXIO);
+ if (ns->data.nsze == 0) {
+ ns->flags |= NVME_NS_FLAG_GONE;
+ return ((ns->flags & NVME_NS_FLAG_ADDED) ? 0 : ENXIO);
+ }
flbas_fmt = (ns->data.flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) &
NVME_NS_DATA_FLBAS_FORMAT_MASK;
@@ -597,10 +600,14 @@
/*
* cdev may have already been created, if we are reconstructing the
- * namespace after a controller-level reset.
+ * namespace after a controller-level reset. If not, then flag this
+ * ns as changed for notification.
*/
- if (ns->cdev != NULL)
+ if (ns->cdev != NULL) {
+ if (why != NVME_REASON_RESET)
+ ns->flags |= NVME_NS_FLAG_CHANGED;
return (0);
+ }
/*
* Namespace IDs start at 1, so we need to subtract 1 to create a
@@ -619,6 +626,7 @@
return (ENXIO);
ns->cdev->si_flags |= SI_UNMAPPED;
+ ns->flags |= NVME_NS_FLAG_ADDED;
return (0);
}
Index: sys/dev/nvme/nvme_private.h
===================================================================
--- sys/dev/nvme/nvme_private.h
+++ sys/dev/nvme/nvme_private.h
@@ -222,6 +222,9 @@
struct nvme_namespace_data data;
uint32_t id;
uint32_t flags;
+#define NVME_NS_FLAG_ADDED 0x1
+#define NVME_NS_FLAG_CHANGED 0x2
+#define NVME_NS_FLAG_GONE 0x4
struct cdev *cdev;
void *cons_cookie[NVME_MAX_CONSUMERS];
uint32_t boundary;
@@ -333,6 +336,11 @@
uint64_t hmb_desc_paddr;
};
+enum nvme_ctor_reason {
+ NVME_REASON_RESET, /* Controller was reset, rebuilding */
+ NVME_REASON_FLAGGED, /* NS was flagged as changed somehow */
+};
+
#define nvme_mmio_offsetof(reg) \
offsetof(struct nvme_registers, reg)
@@ -442,7 +450,7 @@
void nvme_io_qpair_destroy(struct nvme_qpair *qpair);
int nvme_ns_construct(struct nvme_namespace *ns, uint32_t id,
- struct nvme_controller *ctrlr);
+ struct nvme_controller *ctrlr, enum nvme_ctor_reason why);
void nvme_ns_destruct(struct nvme_namespace *ns);
void nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr);
Index: sys/dev/nvme/nvme_sim.c
===================================================================
--- sys/dev/nvme/nvme_sim.c
+++ sys/dev/nvme/nvme_sim.c
@@ -326,25 +326,37 @@
nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg)
{
struct nvme_sim_softc *sc = sc_arg;
+ struct cam_path *tmppath;
union ccb *ccb;
+ if (xpt_create_path(&tmppath, /*periph*/NULL,
+ cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
+ printf("unable to create path for rescan\n");
+ return (NULL);
+ }
+ /*
+ * If it's gone, then signal that and leave.
+ */
+ if (ns->flags & NVME_NS_FLAG_GONE) {
+ xpt_async(AC_LOST_DEVICE, tmppath, NULL);
+ xpt_free_path(tmppath);
+ return (sc_arg);
+ }
+
ccb = xpt_alloc_ccb_nowait();
if (ccb == NULL) {
printf("unable to alloc CCB for rescan\n");
return (NULL);
}
+ ccb->ccb_h.path = tmppath;
/*
* We map the NVMe namespace idea onto the CAM unit LUN. For
* each new namespace, we create a new CAM path for it. We then
* rescan the path to get it to enumerate.
+ *
+ * At the end of the scan, the path is freed, I think...
*/
- if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL,
- cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) {
- printf("unable to create path for rescan\n");
- xpt_free_ccb(ccb);
- return (NULL);
- }
xpt_rescan(ccb);
return (sc_arg);

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 24, 6:56 PM (12 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16097889
Default Alt Text
D32963.id98421.diff (4 KB)

Event Timeline