From patchwork Thu Sep 28 19:36:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Wilck X-Patchwork-Id: 9976691 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6F29E603F2 for ; Thu, 28 Sep 2017 19:37:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 60150296D9 for ; Thu, 28 Sep 2017 19:37:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5479029702; Thu, 28 Sep 2017 19:37:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC264296D9 for ; Thu, 28 Sep 2017 19:37:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751058AbdI1ThX (ORCPT ); Thu, 28 Sep 2017 15:37:23 -0400 Received: from smtp.nue.novell.com ([195.135.221.5]:46950 "EHLO smtp.nue.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750775AbdI1ThX (ORCPT ); Thu, 28 Sep 2017 15:37:23 -0400 Received: from emea4-mta.ukb.novell.com ([10.120.13.87]) by smtp.nue.novell.com with ESMTP (TLS encrypted); Thu, 28 Sep 2017 21:37:21 +0200 Received: from apollon.suse.de.de (nwb-a10-snat.microfocus.com [10.120.13.201]) by emea4-mta.ukb.novell.com with ESMTP (TLS encrypted); Thu, 28 Sep 2017 20:37:01 +0100 From: Martin Wilck To: Jens Axboe , Christoph Hellwig , Johannes Thumshirn Cc: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Hannes Reinecke , linux-nvme@lists.infradead.org, Martin Wilck Subject: [PATCH 1/2] block: genhd: add device_add_disk_with_groups Date: Thu, 28 Sep 2017 21:36:36 +0200 Message-Id: <20170928193637.24707-1-mwilck@suse.com> X-Mailer: git-send-email 2.14.0 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In the NVME subsystem, we're seeing a race condition with udev where device_add_disk() is called (which triggers an "add" uevent), and a sysfs attribute group is added to the disk device afterwards. If udev rules access these attributes before they are created, udev processing of the device is incomplete, in particular, device WWIDs may not be determined correctly. To fix this, this patch introduces a new function device_add_disk_with_groups(), which takes a list of attribute groups and adds them to the device before sending out uevents. Signed-off-by: Martin Wilck Tested-by: Steve Schremmer Reviewed-by: Keith Busch Reviewed-by: Sagi Grimberg --- block/genhd.c | 17 ++++++++++++----- include/linux/genhd.h | 8 +++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index dd305c65ffb0..1900682a221e 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -552,7 +552,8 @@ static int exact_lock(dev_t devt, void *data) return 0; } -static void register_disk(struct device *parent, struct gendisk *disk) +static void register_disk(struct device *parent, struct gendisk *disk, + const struct attribute_group **groups) { struct device *ddev = disk_to_dev(disk); struct block_device *bdev; @@ -578,6 +579,9 @@ static void register_disk(struct device *parent, struct gendisk *disk) } } + if (groups != NULL && sysfs_create_groups(&ddev->kobj, groups)) + dev_warn(ddev, "failed to add attribute groups"); + /* * avoid probable deadlock caused by allocating memory with * GFP_KERNEL in runtime_resume callback of its all ancestor @@ -619,16 +623,19 @@ static void register_disk(struct device *parent, struct gendisk *disk) } /** - * device_add_disk - add partitioning information to kernel list + * device_add_disk_with_groups - add partitioning information to kernel list * @parent: parent device for the disk * @disk: per-device partitioning information + * @groups: NULL-terminated array of attribute groups * * This function registers the partitioning information in @disk * with the kernel. * * FIXME: error handling */ -void device_add_disk(struct device *parent, struct gendisk *disk) +void device_add_disk_with_groups(struct device *parent, + struct gendisk *disk, + const struct attribute_group **groups) { struct backing_dev_info *bdi; dev_t devt; @@ -664,7 +671,7 @@ void device_add_disk(struct device *parent, struct gendisk *disk) blk_register_region(disk_devt(disk), disk->minors, NULL, exact_match, exact_lock, disk); - register_disk(parent, disk); + register_disk(parent, disk, groups); blk_register_queue(disk); /* @@ -680,7 +687,7 @@ void device_add_disk(struct device *parent, struct gendisk *disk) disk_add_events(disk); blk_integrity_add(disk); } -EXPORT_SYMBOL(device_add_disk); +EXPORT_SYMBOL(device_add_disk_with_groups); void del_gendisk(struct gendisk *disk) { diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ea652bfcd675..3404d92d5063 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -386,7 +386,13 @@ static inline void free_part_info(struct hd_struct *part) extern void part_round_stats(struct request_queue *q, int cpu, struct hd_struct *part); /* block/genhd.c */ -extern void device_add_disk(struct device *parent, struct gendisk *disk); +extern void device_add_disk_with_groups(struct device *parent, + struct gendisk *disk, + const struct attribute_group **groups); +static inline void device_add_disk(struct device *parent, struct gendisk *disk) +{ + device_add_disk_with_groups(parent, disk, NULL); +} static inline void add_disk(struct gendisk *disk) { device_add_disk(NULL, disk);