nvme: bring back auto-removal of deleted namespaces during sequential scan
[platform/kernel/linux-starfive.git] / drivers / nvme / host / core.c
index 5acc9ae..2031fd9 100644 (file)
@@ -38,6 +38,7 @@ struct nvme_ns_info {
        bool is_shared;
        bool is_readonly;
        bool is_ready;
+       bool is_removed;
 };
 
 unsigned int admin_timeout = 60;
@@ -1439,16 +1440,8 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
        error = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
        if (error) {
                dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error);
-               goto out_free_id;
+               kfree(*id);
        }
-
-       error = NVME_SC_INVALID_NS | NVME_SC_DNR;
-       if ((*id)->ncap == 0) /* namespace not allocated or attached */
-               goto out_free_id;
-       return 0;
-
-out_free_id:
-       kfree(*id);
        return error;
 }
 
@@ -1462,6 +1455,13 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
        ret = nvme_identify_ns(ctrl, info->nsid, &id);
        if (ret)
                return ret;
+
+       if (id->ncap == 0) {
+               /* namespace not allocated or attached */
+               info->is_removed = true;
+               return -ENODEV;
+       }
+
        info->anagrpid = id->anagrpid;
        info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
        info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
@@ -4388,6 +4388,7 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 {
        struct nvme_ns_info info = { .nsid = nsid };
        struct nvme_ns *ns;
+       int ret;
 
        if (nvme_identify_ns_descs(ctrl, &info))
                return;
@@ -4404,19 +4405,19 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
         * set up a namespace.  If not fall back to the legacy version.
         */
        if ((ctrl->cap & NVME_CAP_CRMS_CRIMS) ||
-           (info.ids.csi != NVME_CSI_NVM && info.ids.csi != NVME_CSI_ZNS)) {
-               if (nvme_ns_info_from_id_cs_indep(ctrl, &info))
-                       return;
-       } else {
-               if (nvme_ns_info_from_identify(ctrl, &info))
-                       return;
-       }
+           (info.ids.csi != NVME_CSI_NVM && info.ids.csi != NVME_CSI_ZNS))
+               ret = nvme_ns_info_from_id_cs_indep(ctrl, &info);
+       else
+               ret = nvme_ns_info_from_identify(ctrl, &info);
+
+       if (info.is_removed)
+               nvme_ns_remove_by_nsid(ctrl, nsid);
 
        /*
         * Ignore the namespace if it is not ready. We will get an AEN once it
         * becomes ready and restart the scan.
         */
-       if (!info.is_ready)
+       if (ret || !info.is_ready)
                return;
 
        ns = nvme_find_get_ns(ctrl, nsid);