}
 
 static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
-               unsigned nsid, struct nvme_id_ns *id)
+               unsigned nsid, struct nvme_id_ns *id,
+               struct nvme_ns_ids *ids)
 {
        struct nvme_ns_head *head;
        size_t size = sizeof(*head);
                goto out_ida_remove;
        head->subsys = ctrl->subsys;
        head->ns_id = nsid;
+       head->ids = *ids;
        kref_init(&head->ref);
 
-       ret = nvme_report_ns_ids(ctrl, nsid, id, &head->ids);
-       if (ret)
-               goto out_cleanup_srcu;
-
        ret = __nvme_check_ids(ctrl->subsys, head);
        if (ret) {
                dev_err(ctrl->device,
        struct nvme_ctrl *ctrl = ns->ctrl;
        bool is_shared = id->nmic & (1 << 0);
        struct nvme_ns_head *head = NULL;
+       struct nvme_ns_ids ids;
        int ret = 0;
 
+       ret = nvme_report_ns_ids(ctrl, nsid, id, &ids);
+       if (ret)
+               goto out;
+
        mutex_lock(&ctrl->subsys->lock);
        if (is_shared)
                head = nvme_find_ns_head(ctrl->subsys, nsid);
        if (!head) {
-               head = nvme_alloc_ns_head(ctrl, nsid, id);
+               head = nvme_alloc_ns_head(ctrl, nsid, id, &ids);
                if (IS_ERR(head)) {
                        ret = PTR_ERR(head);
                        goto out_unlock;
                }
        } else {
-               struct nvme_ns_ids ids;
-
-               ret = nvme_report_ns_ids(ctrl, nsid, id, &ids);
-               if (ret)
-                       goto out_unlock;
-
                if (!nvme_ns_ids_equal(&head->ids, &ids)) {
                        dev_err(ctrl->device,
                                "IDs don't match for shared namespace %d\n",
 
 out_unlock:
        mutex_unlock(&ctrl->subsys->lock);
+out:
        if (ret > 0)
                ret = blk_status_to_errno(nvme_error_status(ret));
        return ret;