nvme: move common logic into nvme_update_ns_info
authorChristoph Hellwig <hch@lst.de>
Mon, 4 Mar 2024 14:04:54 +0000 (07:04 -0700)
committerKeith Busch <kbusch@kernel.org>
Mon, 4 Mar 2024 16:24:56 +0000 (08:24 -0800)
nvme_update_ns_info_generic and nvme_update_ns_info_block share a
fair amount of logic related to not fully supported namespace
formats and updating the multipath information.  Move this logic
into the common caller.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/core.c

index ce70bfb66242e2009d75eb3763dfb6bbbc089db4..f0686a872d0e309988baa7effa2bc46d8f4a7748 100644 (file)
@@ -2070,21 +2070,8 @@ static int nvme_update_ns_info_generic(struct nvme_ns *ns,
        set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
        blk_mq_unfreeze_queue(ns->disk->queue);
 
-       if (nvme_ns_head_multipath(ns->head)) {
-               blk_mq_freeze_queue(ns->head->disk->queue);
-               set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
-               nvme_mpath_revalidate_paths(ns);
-               blk_stack_limits(&ns->head->disk->queue->limits,
-                                &ns->queue->limits, 0);
-               ns->head->disk->flags |= GENHD_FL_HIDDEN;
-               blk_mq_unfreeze_queue(ns->head->disk->queue);
-       }
-
        /* Hide the block-interface for these devices */
-       ns->disk->flags |= GENHD_FL_HIDDEN;
-       set_bit(NVME_NS_READY, &ns->flags);
-
-       return 0;
+       return -ENODEV;
 }
 
 static int nvme_update_ns_info_block(struct nvme_ns *ns,
@@ -2104,7 +2091,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
                /* namespace not allocated or attached */
                info->is_removed = true;
                ret = -ENODEV;
-               goto error;
+               goto out;
        }
 
        blk_mq_freeze_queue(ns->disk->queue);
@@ -2162,54 +2149,67 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
                        goto out;
        }
 
-       if (nvme_ns_head_multipath(ns->head)) {
-               blk_mq_freeze_queue(ns->head->disk->queue);
-               nvme_init_integrity(ns->head->disk, ns->head);
-               set_capacity_and_notify(ns->head->disk, get_capacity(ns->disk));
-               set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
-               nvme_mpath_revalidate_paths(ns);
-               blk_stack_limits(&ns->head->disk->queue->limits,
-                                &ns->queue->limits, 0);
-               disk_update_readahead(ns->head->disk);
-               blk_mq_unfreeze_queue(ns->head->disk->queue);
-       }
-
        ret = 0;
 out:
-       /*
-        * If probing fails due an unsupported feature, hide the block device,
-        * but still allow other access.
-        */
-       if (ret == -ENODEV) {
-               ns->disk->flags |= GENHD_FL_HIDDEN;
-               set_bit(NVME_NS_READY, &ns->flags);
-               ret = 0;
-       }
-
-error:
        kfree(id);
        return ret;
 }
 
 static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
 {
+       bool unsupported = false;
+       int ret;
+
        switch (info->ids.csi) {
        case NVME_CSI_ZNS:
                if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
                        dev_info(ns->ctrl->device,
        "block device for nsid %u not supported without CONFIG_BLK_DEV_ZONED\n",
                                info->nsid);
-                       return nvme_update_ns_info_generic(ns, info);
+                       ret = nvme_update_ns_info_generic(ns, info);
+                       break;
                }
-               return nvme_update_ns_info_block(ns, info);
+               ret = nvme_update_ns_info_block(ns, info);
+               break;
        case NVME_CSI_NVM:
-               return nvme_update_ns_info_block(ns, info);
+               ret = nvme_update_ns_info_block(ns, info);
+               break;
        default:
                dev_info(ns->ctrl->device,
                        "block device for nsid %u not supported (csi %u)\n",
                        info->nsid, info->ids.csi);
-               return nvme_update_ns_info_generic(ns, info);
+               ret = nvme_update_ns_info_generic(ns, info);
+               break;
        }
+
+       /*
+        * If probing fails due an unsupported feature, hide the block device,
+        * but still allow other access.
+        */
+       if (ret == -ENODEV) {
+               ns->disk->flags |= GENHD_FL_HIDDEN;
+               set_bit(NVME_NS_READY, &ns->flags);
+               unsupported = true;
+               ret = 0;
+       }
+
+       if (!ret && nvme_ns_head_multipath(ns->head)) {
+               blk_mq_freeze_queue(ns->head->disk->queue);
+               if (unsupported)
+                       ns->head->disk->flags |= GENHD_FL_HIDDEN;
+               else
+                       nvme_init_integrity(ns->head->disk, ns->head);
+               set_capacity_and_notify(ns->head->disk, get_capacity(ns->disk));
+               set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
+               nvme_mpath_revalidate_paths(ns);
+               blk_stack_limits(&ns->head->disk->queue->limits,
+                                &ns->queue->limits, 0);
+
+               disk_update_readahead(ns->head->disk);
+               blk_mq_unfreeze_queue(ns->head->disk->queue);
+       }
+
+       return ret;
 }
 
 #ifdef CONFIG_BLK_SED_OPAL