]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
nvme: bring back auto-removal of deleted namespaces during sequential scan
authorChristoph Hellwig <hch@lst.de>
Tue, 21 Feb 2023 22:02:25 +0000 (14:02 -0800)
committerChristoph Hellwig <hch@lst.de>
Tue, 28 Feb 2023 13:14:29 +0000 (06:14 -0700)
Bring back the check of the Identify Namespace return value for the
legacy NVMe 1.0-style sequential scanning.  While NVMe 1.0 does not
support namespace management, there are "modern" cloud solutions like
Google Cloud Platform that claim the obsolete 1.0 compliance for no
good reason while supporting proprietary sideband namespace management.

Fixes: 1a893c2bfef4 ("nvme: refactor namespace probing")
Reported-by: Nils Hanke <nh@edgeless.systems>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Tested-by: Nils Hanke <nh@edgeless.systems>
drivers/nvme/host/core.c

index 384138f8f04ce496c2265ba7453c8e4be6622014..3345f866178e4db117dab5b2327feb6b942b9f62 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;
@@ -1402,16 +1403,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;
 }
 
@@ -1425,6 +1418,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;
@@ -4429,6 +4429,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;
@@ -4445,19 +4446,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);