Received: by 2002:ac0:98c7:0:0:0:0:0 with SMTP id g7-v6csp1469612imd; Thu, 1 Nov 2018 16:31:10 -0700 (PDT) X-Google-Smtp-Source: AJdET5dN0Y7AhBDt7lrdIEUP5XP8E7Xioy870meywyZhWt6ZdiiqyoxGlZ+ngJ61eoT0OS7mrV5J X-Received: by 2002:a63:330e:: with SMTP id z14-v6mr8890164pgz.220.1541115070081; Thu, 01 Nov 2018 16:31:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1541115070; cv=none; d=google.com; s=arc-20160816; b=F5bPpq4eGRPH61Y5mRgS8xAfS5Xjmdpmzue+wDXs+l1a2zeDOVINJn8lAZp4W3fJWT CfSKq9ElAVvY59kU0zCi7ku21JO4HIEvseZH44C4QFrMM21XySgD02g6zQTPTRDLI26C jvb2GgGz92S+T0tiKcU0JCynyspg3Sm3gtSETMFHlVtL7FC7tyCHPJg7XiPbkMGcDRVR npCMmtRhOWK0IgLBI2fqst5Fp/yVZntxeggMocLJ06pb2+Us8DJBJkR6xyEGSzF8ZV1D R1l/kQw8Pdjdu80DC9tVL757cqYPMYi34RIOHLeHKn29/wycXL1u2BTYSfN29i08dAzM zHcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=y7zkTRB7nUMwyNkkHgHoGInLDJa+Mx87O7ie1xJdVgw=; b=SFlrX3SIbmRqC6QAHkBI1dK0QPGwS86JAwVeOB7NexBdJzdz0Pkek5X4Rc279xMQNk e2S3NHHhX5ssNPnYVezR4L0StFeGNsh6d6y3Jgt4+RXbLuStknT85GrJHrBZwwQdAtYo AmXdxeikEv6DB9R31CZe+Pp4BDSuQtBAipRj+oKPXCabs35ouE4LIuEhx8ZfHNglbTXa l6w1sgIwb/KxbGLG6aIJBipP7hRcokYJctjRNS2ljqrBorU8U1wkq9feaLiyTxilPfTQ SiiF+1rXpItNjtSAM/rf8LZK368Ru282yima4zJrnMrm11Z5MF6E/26oXI4I2FbbtqyV jl0Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d2-v6si32668134plh.152.2018.11.01.16.30.55; Thu, 01 Nov 2018 16:31:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=canonical.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728233AbeKBIfe (ORCPT + 99 others); Fri, 2 Nov 2018 04:35:34 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:59385 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727749AbeKBIfd (ORCPT ); Fri, 2 Nov 2018 04:35:33 -0400 Received: from 1.general.cascardo.us.vpn ([10.172.70.58] helo=localhost.localdomain) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gIMPy-00053v-91; Thu, 01 Nov 2018 23:30:26 +0000 From: Thadeu Lima de Souza Cascardo To: linux-nvme@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Sagi Grimberg , Jens Axboe , Thadeu Lima de Souza Cascardo , Christoph Hellwig , Potnuri Bharat Teja , Keith Busch , Hannes Reinecke , "Martin K . Petersen" Subject: [PATCH v2] nvme: create 'paths' entries for hidden controllers Date: Thu, 1 Nov 2018 20:29:55 -0300 Message-Id: <20181101232955.19329-1-cascardo@canonical.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When using initramfs-tools with only the necessary dependencies to mount the root filesystem, it will fail to include nvme drivers for a root on a multipath nvme. That happens because the slaves relationship is not present. As discussed in [1], using slaves will break lsblk, because the slaves are hidden from userspace, that is, they have no real block device, just an entry under sysfs. Introducing the paths subdir and using that on initramfs-tools makes it possible to now boot a system with nvme multipath as root. [1] https://www.spinics.net/lists/stable/msg222779.html Cc: Christoph Hellwig Cc: Potnuri Bharat Teja Cc: Keith Busch Cc: Hannes Reinecke Cc: Martin K. Petersen Signed-off-by: Thadeu Lima de Souza Cascardo --- Documentation/ABI/testing/sysfs-block-nvme | 10 ++++++++ drivers/nvme/host/core.c | 2 ++ drivers/nvme/host/multipath.c | 29 ++++++++++++++++++++-- drivers/nvme/host/nvme.h | 9 +++++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-block-nvme diff --git a/Documentation/ABI/testing/sysfs-block-nvme b/Documentation/ABI/testing/sysfs-block-nvme new file mode 100644 index 000000000000..3fe51b7be1e1 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-block-nvme @@ -0,0 +1,10 @@ +What: /sys/block/nvme*/paths +Date: Oct, 2019 +KernelVersion: v4.21 +Contact: Thadeu Lima de Souza Cascardo +Description: + This is a directory containing symlinks to other block + devices, when the block device is a nvme multipath + device. +Users: initramfs-tools + diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 9e4a30b05bd2..06be47e878f5 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3115,6 +3115,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups); nvme_mpath_add_disk(ns, id); + nvme_mpath_add_disk_links(ns); nvme_fault_inject_init(ns); kfree(id); @@ -3138,6 +3139,7 @@ static void nvme_ns_remove(struct nvme_ns *ns) nvme_fault_inject_fini(ns); if (ns->disk && ns->disk->flags & GENHD_FL_UP) { + nvme_mpath_remove_disk_links(ns); del_gendisk(ns->disk); blk_cleanup_queue(ns->queue); if (blk_get_integrity(ns->disk)) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 5e3cc8c59a39..65dabe7d6d7c 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -317,9 +317,12 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) if (!head->disk) return; - if (!(head->disk->flags & GENHD_FL_UP)) + if (!(head->disk->flags & GENHD_FL_UP)) { + struct kobject *hd_kobj = &disk_to_dev(head->disk)->kobj; device_add_disk(&head->subsys->dev, head->disk, nvme_ns_id_attr_groups); + head->path_dir = kobject_create_and_add("paths", hd_kobj); + } if (nvme_path_is_optimized(ns)) { int node, srcu_idx; @@ -530,6 +533,19 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) } } +void nvme_mpath_add_disk_links(struct nvme_ns *ns) +{ + struct kobject *path_disk_kobj; + + if (!ns->head->disk) + return; + + path_disk_kobj = &disk_to_dev(ns->disk)->kobj; + if (sysfs_create_link(ns->head->path_dir, path_disk_kobj, + kobject_name(path_disk_kobj))) + return; +} + void nvme_mpath_remove_disk(struct nvme_ns_head *head) { if (!head->disk) @@ -541,9 +557,19 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) kblockd_schedule_work(&head->requeue_work); flush_work(&head->requeue_work); blk_cleanup_queue(head->disk->queue); + kobject_put(head->path_dir); put_disk(head->disk); } +void nvme_mpath_remove_disk_links(struct nvme_ns *ns) +{ + if (!ns->head->disk) + return; + + sysfs_remove_link(ns->head->path_dir, + kobject_name(&disk_to_dev(ns->disk)->kobj)); +} + int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) { int error; @@ -593,4 +619,3 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl) { kfree(ctrl->ana_log_buf); } - diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 9fefba039d1e..6093649d4696 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -287,6 +287,7 @@ struct nvme_ns_head { int instance; #ifdef CONFIG_NVME_MULTIPATH struct gendisk *disk; + struct kobject *path_dir; struct bio_list requeue_list; spinlock_t requeue_lock; struct work_struct requeue_work; @@ -471,6 +472,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id); void nvme_mpath_remove_disk(struct nvme_ns_head *head); +void nvme_mpath_add_disk_links(struct nvme_ns *ns); +void nvme_mpath_remove_disk_links(struct nvme_ns *ns); int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); void nvme_mpath_uninit(struct nvme_ctrl *ctrl); void nvme_mpath_stop(struct nvme_ctrl *ctrl); @@ -521,6 +524,12 @@ static inline void nvme_mpath_add_disk(struct nvme_ns *ns, static inline void nvme_mpath_remove_disk(struct nvme_ns_head *head) { } +static inline void nvme_mpath_add_disk_links(struct nvme_ns *ns) +{ +} +static inline void nvme_mpath_remove_disk_links(struct nvme_ns *ns) +{ +} static inline void nvme_mpath_clear_current_path(struct nvme_ns *ns) { } -- 2.19.1