|
@@ -1528,6 +1528,17 @@ static void nvme_validate_ns(struct nvme_ctrl *ctrl, unsigned nsid)
|
|
|
nvme_alloc_ns(ctrl, nsid);
|
|
|
}
|
|
|
|
|
|
+static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
|
|
|
+ unsigned nsid)
|
|
|
+{
|
|
|
+ struct nvme_ns *ns, *next;
|
|
|
+
|
|
|
+ list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
|
|
|
+ if (ns->ns_id > nsid)
|
|
|
+ nvme_ns_remove(ns);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
|
|
|
{
|
|
|
struct nvme_ns *ns;
|
|
@@ -1542,7 +1553,7 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
|
|
|
for (i = 0; i < num_lists; i++) {
|
|
|
ret = nvme_identify_ns_list(ctrl, prev, ns_list);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ goto free;
|
|
|
|
|
|
for (j = 0; j < min(nn, 1024U); j++) {
|
|
|
nsid = le32_to_cpu(ns_list[j]);
|
|
@@ -1560,13 +1571,14 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn)
|
|
|
nn -= j;
|
|
|
}
|
|
|
out:
|
|
|
+ nvme_remove_invalid_namespaces(ctrl, prev);
|
|
|
+ free:
|
|
|
kfree(ns_list);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl, unsigned nn)
|
|
|
{
|
|
|
- struct nvme_ns *ns, *next;
|
|
|
unsigned i;
|
|
|
|
|
|
lockdep_assert_held(&ctrl->namespaces_mutex);
|
|
@@ -1574,10 +1586,7 @@ static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl, unsigned nn)
|
|
|
for (i = 1; i <= nn; i++)
|
|
|
nvme_validate_ns(ctrl, i);
|
|
|
|
|
|
- list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
|
|
|
- if (ns->ns_id > nn)
|
|
|
- nvme_ns_remove(ns);
|
|
|
- }
|
|
|
+ nvme_remove_invalid_namespaces(ctrl, nn);
|
|
|
}
|
|
|
|
|
|
static void nvme_scan_work(struct work_struct *work)
|