From patchwork Wed Jul 13 11:31:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD71FC43334 for ; Wed, 13 Jul 2022 11:31:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234672AbiGMLbe (ORCPT ); Wed, 13 Jul 2022 07:31:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229640AbiGMLbe (ORCPT ); Wed, 13 Jul 2022 07:31:34 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18DA8102701; Wed, 13 Jul 2022 04:31:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=L6HDvaP1SmiE0rcJ7oRdsYduI0rwTBK1ov+lk6NYzWk=; b=phKk3z6fkgMkQwMRW9ldNvgQwC YpDEhvu7VU4NtIysAYbpNErQmkk83gqs8E7XoKy5RJC86OsI+lhxAYJNw1Or0XgFd79qZJRl5M9rB WLiL0dacpL5KZMCgpEcBSYl6dT7WqYvu/3KFl7MMX8Q5nYDoyHdTnrhF2AGDVXtR6f7mVc4X+6r0/ so5+byuNjr8XK5/Pj3jMcJvZneiyMcOH84fUHF1zvXRM2qk4mJZ5eG4/3OYIvqzkxBjsd6S5ubm5L UKuOPtL2kK8f+Z6zHu4mcc467E8EXXBOz1nkK2it1IFx5lTuQ9jDHV2/iZsGGRfIZcIHQ0zp9AXDj LtPoI1ow==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaaY-0039zg-I6; Wed, 13 Jul 2022 11:31:30 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 1/9] md: fix error handling in md_alloc Date: Wed, 13 Jul 2022 13:31:17 +0200 Message-Id: <20220713113125.2232975-2-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Error handling in md_alloc is a mess. Untangle it to just free the mddev directly before add_disk is called and thus the gendisk is globally visible. After that clear the hold flag and let the mddev_put take care of cleaning up the mddev through the usual mechanisms. Fixes: 5e55e2f5fc95 ("[PATCH] md: convert compile time warnings into runtime warnings") Fixes: 9be68dd7ac0e ("md: add error handling support for add_disk()") Fixes: 7ad1069166c0 ("md: properly unwind when failing to add the kobject in md_alloc") Signed-off-by: Christoph Hellwig --- Note: the put_disk here is not fully correct on md-next, but will do the right thing once merged with the block tree. drivers/md/md.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index b64de313838f2..7affddade8b6b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -791,6 +791,15 @@ static struct mddev *mddev_alloc(dev_t unit) return ERR_PTR(error); } +static void mddev_free(struct mddev *mddev) +{ + spin_lock(&all_mddevs_lock); + list_del(&mddev->all_mddevs); + spin_unlock(&all_mddevs_lock); + + kfree(mddev); +} + static const struct attribute_group md_redundancy_group; void mddev_unlock(struct mddev *mddev) @@ -5664,8 +5673,8 @@ int md_alloc(dev_t dev, char *name) mutex_lock(&disks_mutex); mddev = mddev_alloc(dev); if (IS_ERR(mddev)) { - mutex_unlock(&disks_mutex); - return PTR_ERR(mddev); + error = PTR_ERR(mddev); + goto out_unlock; } partitioned = (MAJOR(mddev->unit) != MD_MAJOR); @@ -5683,7 +5692,7 @@ int md_alloc(dev_t dev, char *name) strcmp(mddev2->gendisk->disk_name, name) == 0) { spin_unlock(&all_mddevs_lock); error = -EEXIST; - goto out_unlock_disks_mutex; + goto out_free_mddev; } spin_unlock(&all_mddevs_lock); } @@ -5696,7 +5705,7 @@ int md_alloc(dev_t dev, char *name) error = -ENOMEM; disk = blk_alloc_disk(NUMA_NO_NODE); if (!disk) - goto out_unlock_disks_mutex; + goto out_free_mddev; disk->major = MAJOR(mddev->unit); disk->first_minor = unit << shift; @@ -5717,25 +5726,35 @@ int md_alloc(dev_t dev, char *name) mddev->gendisk = disk; error = add_disk(disk); if (error) - goto out_cleanup_disk; + goto out_put_disk; error = kobject_add(&mddev->kobj, &disk_to_dev(disk)->kobj, "%s", "md"); - if (error) - goto out_del_gendisk; + if (error) { + /* + * The disk is already live at this point. Clear the hold flag + * and let mddev_put take care of the deletion, as it isn't any + * different from a normal close on last release now. + */ + mddev->hold_active = 0; + goto done; + } kobject_uevent(&mddev->kobj, KOBJ_ADD); mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state"); mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level"); - goto out_unlock_disks_mutex; -out_del_gendisk: - del_gendisk(disk); -out_cleanup_disk: - blk_cleanup_disk(disk); -out_unlock_disks_mutex: +done: mutex_unlock(&disks_mutex); mddev_put(mddev); return error; + +out_put_disk: + put_disk(disk); +out_free_mddev: + mddev_free(mddev); +out_unlock: + mutex_unlock(&disks_mutex); + return error; } static void md_probe(dev_t dev) From patchwork Wed Jul 13 11:31:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916592 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D25AC43334 for ; Wed, 13 Jul 2022 11:31:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235506AbiGMLbj (ORCPT ); Wed, 13 Jul 2022 07:31:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231596AbiGMLbg (ORCPT ); Wed, 13 Jul 2022 07:31:36 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12ABA102700; Wed, 13 Jul 2022 04:31:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=qCBykpr/hg8qLaH6YfnGQvtq3JJJqR4usp3uIuIPVBM=; b=RlwLN+njbXxP7deZRbZitvwi5R +Q4qsRL+A83rv6Gyg7gyomyTxGpG+BOqo9XyovU1hjx9/Kzf4oF6ogl3JVtyXsZ1QlJJ7CnjDp9w1 3qM6oQjhKYmF3z9LafgZ+9VBmmELso71mJizu5IVWKhD5Hwaset+wDQrq9oHQYTI4ujM3eRTSQ0qr vUzncHYwH4clgZe3LWqQNL1IiTyGFVxGRUAaZwAnVSThkvnjNnougDJMED7gL70x4KO8cyNS799I0 Arx3UD0drcvunSgefsRzW5/iv3KrB7K7witbZdPAlMteZfFwFWMZHPOOqbUAhSlEAvkvZ9bOhkZjV yjsplmvg==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaaa-003A0k-R5; Wed, 13 Jul 2022 11:31:33 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 2/9] md: implement ->free_disk Date: Wed, 13 Jul 2022 13:31:18 +0200 Message-Id: <20220713113125.2232975-3-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Ensure that all private data is only freed once all accesses are done. Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 7affddade8b6b..2beaadd202c4e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5603,11 +5603,6 @@ static void md_free(struct kobject *ko) del_gendisk(mddev->gendisk); blk_cleanup_disk(mddev->gendisk); } - percpu_ref_exit(&mddev->writes_pending); - - bioset_exit(&mddev->bio_set); - bioset_exit(&mddev->sync_set); - kfree(mddev); } static const struct sysfs_ops md_sysfs_ops = { @@ -7877,6 +7872,17 @@ static unsigned int md_check_events(struct gendisk *disk, unsigned int clearing) return ret; } +static void md_free_disk(struct gendisk *disk) +{ + struct mddev *mddev = disk->private_data; + + percpu_ref_exit(&mddev->writes_pending); + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); + + kfree(mddev); +} + const struct block_device_operations md_fops = { .owner = THIS_MODULE, @@ -7890,6 +7896,7 @@ const struct block_device_operations md_fops = .getgeo = md_getgeo, .check_events = md_check_events, .set_read_only = md_set_read_only, + .free_disk = md_free_disk, }; static int md_thread(void *arg) From patchwork Wed Jul 13 11:31:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E06A5CCA483 for ; Wed, 13 Jul 2022 11:31:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231596AbiGMLbj (ORCPT ); Wed, 13 Jul 2022 07:31:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234588AbiGMLbh (ORCPT ); Wed, 13 Jul 2022 07:31:37 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42B9E102720; Wed, 13 Jul 2022 04:31:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=rbTZo0mQNN/DNA+MsAJn+JMvWsFE/h02GkL+IF+Hh2k=; b=RjQOKwF+wZEtJ3nUlfE4BNIHuL nHdA4iNnlJBxGRc56cMgr2q0rCxmgW7hveYwGyrYrK+dJeopquXvJQCSSAFG/0xuBLft+VuJxqM/N u145eYUKU7btkzyaIHI+Mq/GkS0EdDKbiBgg8KnpbDUrrzLpal3A2yg6EcDGX++wZySRPASrJPxAJ zOErHIq0kq4VgHBAGZx3USIkhiXQjRjvPLHDzmR4j/KMmVm+JsM/Ai5JoR6i4LxuXlwdfZ/JxG/O9 8/yur7spq4sx2iY1gHY8QtgKCl/THWrf5XMT7EUxrfmcfSJ8M12mnV8382Twt+dPIaEeVlEWKnsrE 1W2L6oIQ==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaad-003A2V-2o; Wed, 13 Jul 2022 11:31:35 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 3/9] md: rename md_free to md_kobj_release Date: Wed, 13 Jul 2022 13:31:19 +0200 Message-Id: <20220713113125.2232975-4-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org The md_free name is rather misleading, so pick a better one. Signed-off-by: Christoph Hellwig Acked-by: Guoqing Jiang --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 2beaadd202c4e..3127dcb8102ce 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5590,7 +5590,7 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, return rv; } -static void md_free(struct kobject *ko) +static void md_kobj_release(struct kobject *ko) { struct mddev *mddev = container_of(ko, struct mddev, kobj); @@ -5610,7 +5610,7 @@ static const struct sysfs_ops md_sysfs_ops = { .store = md_attr_store, }; static struct kobj_type md_ktype = { - .release = md_free, + .release = md_kobj_release, .sysfs_ops = &md_sysfs_ops, .default_groups = md_attr_groups, }; From patchwork Wed Jul 13 11:31:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916594 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 763A1C433EF for ; Wed, 13 Jul 2022 11:31:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235703AbiGMLbl (ORCPT ); Wed, 13 Jul 2022 07:31:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235603AbiGMLbk (ORCPT ); Wed, 13 Jul 2022 07:31:40 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EBA1102726; Wed, 13 Jul 2022 04:31:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=W1e6MzbMvcjOzxPlhjQN2IPC6OQvXK65Jnlzyh8Wt5w=; b=Q5hDKDCBGnwfuAZzKk1G2iYRmr I41HgF/hfNYBkio2BSrRU0p9wo8Vy1rSPvf+OBdziTySpfTmdp6PVSjGmCkx4/BVegmiZW1OdVxNc zM+3CMELy8Hx5GZAmt1N2n4WLjOYdk3L76l/FIKhkpYROY6jqtpEqMBSxQy2EKudRi+dtG3zeF/ig 2ZXaQQLfBPksAMfRZzEk7L6e0lP9MZNQUvWRhrBIgzzO8DSVOte106vw/AUec6qGqUIbG9yhRi+hh m1sXFcEOKslxqocB6YHQuRENc7Yy99TBuH6UZ3K9O9eoFCrDmN8La7M7Fqx3n9zqAOKtj3splcoH1 9shTU5Xg==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaaf-003A3r-A4; Wed, 13 Jul 2022 11:31:37 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 4/9] md: factor out the rdev overlaps check from rdev_size_store Date: Wed, 13 Jul 2022 13:31:20 +0200 Message-Id: <20220713113125.2232975-5-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org This splits the code into nicely readable chunks and also avoids the refcount inc/dec manipulations. Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 84 +++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 3127dcb8102ce..5346135ab51c8 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3344,14 +3344,33 @@ rdev_size_show(struct md_rdev *rdev, char *page) return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2); } -static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2) +static int md_rdevs_overlap(struct md_rdev *a, struct md_rdev *b) { /* check if two start/length pairs overlap */ - if (s1+l1 <= s2) - return 0; - if (s2+l2 <= s1) - return 0; - return 1; + if (a->data_offset + a->sectors <= b->data_offset) + return false; + if (b->data_offset + b->sectors <= a->data_offset) + return false; + return true; +} + +static bool md_rdev_overlaps(struct md_rdev *rdev) +{ + struct mddev *mddev; + struct md_rdev *rdev2; + + spin_lock(&all_mddevs_lock); + list_for_each_entry(mddev, &all_mddevs, all_mddevs) { + rdev_for_each(rdev2, mddev) { + if (rdev != rdev2 && rdev->bdev == rdev2->bdev && + md_rdevs_overlap(rdev, rdev2)) { + spin_unlock(&all_mddevs_lock); + return true; + } + } + } + spin_unlock(&all_mddevs_lock); + return false; } static int strict_blocks_to_sectors(const char *buf, sector_t *sectors) @@ -3403,46 +3422,21 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len) return -EINVAL; /* component must fit device */ rdev->sectors = sectors; - if (sectors > oldsectors && my_mddev->external) { - /* Need to check that all other rdevs with the same - * ->bdev do not overlap. 'rcu' is sufficient to walk - * the rdev lists safely. - * This check does not provide a hard guarantee, it - * just helps avoid dangerous mistakes. - */ - struct mddev *mddev; - int overlap = 0; - struct list_head *tmp; - rcu_read_lock(); - for_each_mddev(mddev, tmp) { - struct md_rdev *rdev2; - - rdev_for_each(rdev2, mddev) - if (rdev->bdev == rdev2->bdev && - rdev != rdev2 && - overlaps(rdev->data_offset, rdev->sectors, - rdev2->data_offset, - rdev2->sectors)) { - overlap = 1; - break; - } - if (overlap) { - mddev_put(mddev); - break; - } - } - rcu_read_unlock(); - if (overlap) { - /* Someone else could have slipped in a size - * change here, but doing so is just silly. - * We put oldsectors back because we *know* it is - * safe, and trust userspace not to race with - * itself - */ - rdev->sectors = oldsectors; - return -EBUSY; - } + /* + * Check that all other rdevs with the same bdev do not overlap. This + * check does not provide a hard guarantee, it just helps avoid + * dangerous mistakes. + */ + if (sectors > oldsectors && my_mddev->external && + md_rdev_overlaps(rdev)) { + /* + * Someone else could have slipped in a size change here, but + * doing so is just silly. We put oldsectors back because we + * know it is safe, and trust userspace not to race with itself. + */ + rdev->sectors = oldsectors; + return -EBUSY; } return len; } From patchwork Wed Jul 13 11:31:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916595 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85C54C43334 for ; Wed, 13 Jul 2022 11:31:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236090AbiGMLbs (ORCPT ); Wed, 13 Jul 2022 07:31:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235789AbiGMLbm (ORCPT ); Wed, 13 Jul 2022 07:31:42 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAC8F102726; Wed, 13 Jul 2022 04:31:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=7+vEvONgQN1JlW1sJ6AYFOXQb9AQbSdq5spcDhChHzQ=; b=Ggx93m3gDZdGFh+yL0AKL9ukAG JHygWl58eVYrAApYmel1hLacsfbOsiIBv9d8Wo7wp8T7jihyC5H2aC1IeEmNeNj4w0vcyNvQ5xyw9 smN6ATUdWYL6J4gCcjLYS1WCcVV3OGLre3h2oxoazuYtzRj46xU4Ouc7lXTeQ6FH4Oyxz8jm1aH9E Wo+UxIdk9yJSweKyi/+grSp4miqPFEM5KIG4DR9GQkddNFlpfaSi2UiRmCejWR3aEsrx1Eq4aHdzm 36hlY3dSMnvyNIGE+6GVL7iUvYY3HvGpu2Dj2d3VybQOF0djtLsMrz3dCzxQ+d+sCe4RTyxLHMih1 Eok9N4FQ==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaah-003A5J-HZ; Wed, 13 Jul 2022 11:31:39 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 5/9] md: stop using for_each_mddev in md_do_sync Date: Wed, 13 Jul 2022 13:31:21 +0200 Message-Id: <20220713113125.2232975-6-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Just do a plain list_for_each that only grabs a mddev reference in the case where the thread sleeps and restarts the list iteration. Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 5346135ab51c8..a2c2e45cb4c18 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8726,7 +8726,6 @@ void md_do_sync(struct md_thread *thread) unsigned long update_time; sector_t mark_cnt[SYNC_MARKS]; int last_mark,m; - struct list_head *tmp; sector_t last_check; int skipped = 0; struct md_rdev *rdev; @@ -8790,7 +8789,8 @@ void md_do_sync(struct md_thread *thread) try_again: if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) goto skip; - for_each_mddev(mddev2, tmp) { + spin_lock(&all_mddevs_lock); + list_for_each_entry(mddev2, &all_mddevs, all_mddevs) { if (mddev2 == mddev) continue; if (!mddev->parallel_resync @@ -8822,7 +8822,8 @@ void md_do_sync(struct md_thread *thread) desc, mdname(mddev), mdname(mddev2)); } - mddev_put(mddev2); + spin_unlock(&all_mddevs_lock); + if (signal_pending(current)) flush_signals(current); schedule(); @@ -8832,6 +8833,7 @@ void md_do_sync(struct md_thread *thread) finish_wait(&resync_wait, &wq); } } + spin_unlock(&all_mddevs_lock); } while (mddev->curr_resync < MD_RESYNC_DELAYED); j = 0; From patchwork Wed Jul 13 11:31:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916596 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AC64CCA479 for ; Wed, 13 Jul 2022 11:31:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235895AbiGMLbu (ORCPT ); Wed, 13 Jul 2022 07:31:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54178 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235402AbiGMLbr (ORCPT ); Wed, 13 Jul 2022 07:31:47 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFE96102901; Wed, 13 Jul 2022 04:31:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=bngMjYE6V+XiRTbGrn4zsxCyBaGkCajcx67H9eDcFnw=; b=1hfedvL2eoJfFmn1dj1bBqDpZW AzAmvNhGfu3gMtkEEaCltlIo8wPNI+AfPI1ZUaHlw/eiVx9HB9lPGCOAmgxX4w0M9yi4gIOOyvwhr l1Oya/Ql3xGTWF2KG7/48ZjsrMVXBI9fkNpisjfLJ2z47uSZfY/PjJe05LYOFIQESBe6bXgBW8Xyf 8p/fUwKps0l5Lg9MIpid0zwY35QStZOGu1z73FoNp9NpqybmigjsuaMLaIBryLNLCCe20+fPTRkBB kloPCwBpV6wG4Eceg8WFkhr8HTSZjsuCJGOAHE8PvZBMPNvPifITIXx4Vp3Fn6qzCAGGBTRfLb4nk 4PycjnrQ==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaaj-003A6Q-OO; Wed, 13 Jul 2022 11:31:42 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 6/9] md: stop using for_each_mddev in md_notify_reboot Date: Wed, 13 Jul 2022 13:31:22 +0200 Message-Id: <20220713113125.2232975-7-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Just do a simple list_for_each_entry_safe on all_mddevs, and only grab a reference when we drop the lock. Reviewed-by: Christoph Hellwig --- drivers/md/md.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index a2c2e45cb4c18..d3e587271ef3f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9588,11 +9588,13 @@ EXPORT_SYMBOL_GPL(rdev_clear_badblocks); static int md_notify_reboot(struct notifier_block *this, unsigned long code, void *x) { - struct list_head *tmp; - struct mddev *mddev; + struct mddev *mddev, *n; int need_delay = 0; - for_each_mddev(mddev, tmp) { + spin_lock(&all_mddevs_lock); + list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) { + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); if (mddev_trylock(mddev)) { if (mddev->pers) __md_stop_writes(mddev); @@ -9601,7 +9603,11 @@ static int md_notify_reboot(struct notifier_block *this, mddev_unlock(mddev); } need_delay = 1; + mddev_put(mddev); + spin_lock(&all_mddevs_lock); } + spin_unlock(&all_mddevs_lock); + /* * certain more exotic SCSI devices are known to be * volatile wrt too early system reboots. While the From patchwork Wed Jul 13 11:31:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916597 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FA8EC433EF for ; Wed, 13 Jul 2022 11:31:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235845AbiGMLbw (ORCPT ); Wed, 13 Jul 2022 07:31:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234588AbiGMLbs (ORCPT ); Wed, 13 Jul 2022 07:31:48 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 276A110290C; Wed, 13 Jul 2022 04:31:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=13JWl8G1n50DQSYQx0/GVQsTIr5MiAERL7BVRB2LV4E=; b=KoPt3GfCFeTV2dED1smmIlNKHJ VOtZa6yc5oCuOpITNL51LGwuUpOmgKpDh1o1GlqIczdf2yfeNLesrIxP1hCq1wY0xNsj41gbTtOHp EQxkxm0Tgc93tdqXH+7oZTzYI2l+VBHJc+Dod+5lUIQRVHSrUSnCXazSU5gMi3a/NIKussI/NGmn+ r7TxDY2NV4woZMQNUK4grSdlXXY/8cacbuep5oyFVMZQYFe4YnxMAeQDY0hnYJTIhhh6TYcDwmn2X qikKUN6/AnezLoVI1g6MBsrx6Bhc1PTusc13+qgU3UfIo3qVYjgIp/K4/0lvENq5Lr5Q2QHZHNmAK rEOrtC/g==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaal-003A8H-W4; Wed, 13 Jul 2022 11:31:44 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 7/9] md: stop using for_each_mddev in md_exit Date: Wed, 13 Jul 2022 13:31:23 +0200 Message-Id: <20220713113125.2232975-8-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Just do a simple list_for_each_entry_safe on all_mddevs, and only grab a reference when we drop the lock and delete the now unused for_each_mddev macro. Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index d3e587271ef3f..df99a16892bce 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -368,28 +368,6 @@ EXPORT_SYMBOL_GPL(md_new_event); static LIST_HEAD(all_mddevs); static DEFINE_SPINLOCK(all_mddevs_lock); -/* - * iterates through all used mddevs in the system. - * We take care to grab the all_mddevs_lock whenever navigating - * the list, and to always hold a refcount when unlocked. - * Any code which breaks out of this loop while own - * a reference to the current mddev and must mddev_put it. - */ -#define for_each_mddev(_mddev,_tmp) \ - \ - for (({ spin_lock(&all_mddevs_lock); \ - _tmp = all_mddevs.next; \ - _mddev = NULL;}); \ - ({ if (_tmp != &all_mddevs) \ - mddev_get(list_entry(_tmp, struct mddev, all_mddevs));\ - spin_unlock(&all_mddevs_lock); \ - if (_mddev) mddev_put(_mddev); \ - _mddev = list_entry(_tmp, struct mddev, all_mddevs); \ - _tmp != &all_mddevs;}); \ - ({ spin_lock(&all_mddevs_lock); \ - _tmp = _tmp->next;}) \ - ) - /* Rather than calling directly into the personality make_request function, * IO requests come here first so that we can check if the device is * being suspended pending a reconfiguration. @@ -9926,8 +9904,7 @@ void md_autostart_arrays(int part) static __exit void md_exit(void) { - struct mddev *mddev; - struct list_head *tmp; + struct mddev *mddev, *n; int delay = 1; unregister_blkdev(MD_MAJOR,"md"); @@ -9947,17 +9924,23 @@ static __exit void md_exit(void) } remove_proc_entry("mdstat", NULL); - for_each_mddev(mddev, tmp) { + spin_lock(&all_mddevs_lock); + list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) { + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); export_array(mddev); mddev->ctime = 0; mddev->hold_active = 0; /* - * for_each_mddev() will call mddev_put() at the end of each - * iteration. As the mddev is now fully clear, this will - * schedule the mddev for destruction by a workqueue, and the + * As the mddev is now fully clear, mddev_put will schedule + * the mddev for destruction by a workqueue, and the * destroy_workqueue() below will wait for that to complete. */ + mddev_put(mddev); + spin_lock(&all_mddevs_lock); } + spin_unlock(&all_mddevs_lock); + destroy_workqueue(md_rdev_misc_wq); destroy_workqueue(md_misc_wq); destroy_workqueue(md_wq); From patchwork Wed Jul 13 11:31:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916598 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32E9AC433EF for ; Wed, 13 Jul 2022 11:32:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236144AbiGMLb6 (ORCPT ); Wed, 13 Jul 2022 07:31:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54238 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235860AbiGMLbt (ORCPT ); Wed, 13 Jul 2022 07:31:49 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6022E10272D; Wed, 13 Jul 2022 04:31:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=knSIqFo/SrgbF+0BNSi9jf07y509Gse6Gydnoplpxg8=; b=KAjG50uPOti2LkZUxXnJUiBcyC V0OCay57avOPnTHG43lbQvz6BDn/woNcn1E8jtyRkpFI6OPk8Jx5BcykFTOcK6Fs4clQZfG1I7V1m SQTEMS/uLv68rH4KmSjH/AQuoS6stP3Pas9vr6RJ1YOFBJqqCLSTlEqqutpn8doR7O1DSHoAR6xJU yzukm7IlvXiJW/eEIZ6AMDp/krU4310NpcpReAKRpYzxPUITsjoKbpW/FdDsmlp2Tw4qOlViQflZH +wN0xiHXiWZVPCavnO0/BJVdPOegOJ6YRqWnRTBFLvHVz3KsMLYuK7gTrTkksQftZWY/OUqZpHL9m mfA3gP8g==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaao-003A9m-82; Wed, 13 Jul 2022 11:31:46 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 8/9] md: only delete entries from all_mddevs when the disk is freed Date: Wed, 13 Jul 2022 13:31:24 +0200 Message-Id: <20220713113125.2232975-9-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org This ensures device names don't get prematurely reused. Instead add a deleted flag to skip already deleted devices in mddev_get and other places that only want to see live mddevs. Reported-by; Logan Gunthorpe Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 56 +++++++++++++++++++++++++++++++++---------------- drivers/md/md.h | 1 + 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index df99a16892bce..f3ff61e540ee0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -625,6 +625,10 @@ EXPORT_SYMBOL(md_flush_request); static inline struct mddev *mddev_get(struct mddev *mddev) { + lockdep_assert_held(&all_mddevs_lock); + + if (mddev->deleted) + return NULL; atomic_inc(&mddev->active); return mddev; } @@ -639,7 +643,7 @@ static void mddev_put(struct mddev *mddev) mddev->ctime == 0 && !mddev->hold_active) { /* Array is not configured at all, and not held active, * so destroy it */ - list_del_init(&mddev->all_mddevs); + mddev->deleted = true; /* * Call queue_work inside the spinlock so that @@ -720,8 +724,8 @@ static struct mddev *mddev_find(dev_t unit) spin_lock(&all_mddevs_lock); mddev = mddev_find_locked(unit); - if (mddev) - mddev_get(mddev); + if (mddev && !mddev_get(mddev)) + mddev = NULL; spin_unlock(&all_mddevs_lock); return mddev; @@ -3339,6 +3343,8 @@ static bool md_rdev_overlaps(struct md_rdev *rdev) spin_lock(&all_mddevs_lock); list_for_each_entry(mddev, &all_mddevs, all_mddevs) { + if (mddev->deleted) + continue; rdev_for_each(rdev2, mddev) { if (rdev != rdev2 && rdev->bdev == rdev2->bdev && md_rdevs_overlap(rdev, rdev2)) { @@ -5526,11 +5532,10 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) if (!entry->show) return -EIO; spin_lock(&all_mddevs_lock); - if (list_empty(&mddev->all_mddevs)) { + if (!mddev_get(mddev)) { spin_unlock(&all_mddevs_lock); return -EBUSY; } - mddev_get(mddev); spin_unlock(&all_mddevs_lock); rv = entry->show(mddev, page); @@ -5551,11 +5556,10 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, if (!capable(CAP_SYS_ADMIN)) return -EACCES; spin_lock(&all_mddevs_lock); - if (list_empty(&mddev->all_mddevs)) { + if (!mddev_get(mddev)) { spin_unlock(&all_mddevs_lock); return -EBUSY; } - mddev_get(mddev); spin_unlock(&all_mddevs_lock); rv = entry->store(mddev, page, length); mddev_put(mddev); @@ -7852,7 +7856,7 @@ static void md_free_disk(struct gendisk *disk) bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - kfree(mddev); + mddev_free(mddev); } const struct block_device_operations md_fops = @@ -8174,6 +8178,8 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos) if (!l--) { mddev = list_entry(tmp, struct mddev, all_mddevs); mddev_get(mddev); + if (!mddev_get(mddev)) + continue; spin_unlock(&all_mddevs_lock); return mddev; } @@ -8187,25 +8193,35 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct list_head *tmp; struct mddev *next_mddev, *mddev = v; + struct mddev *to_put = NULL; ++*pos; if (v == (void*)2) return NULL; spin_lock(&all_mddevs_lock); - if (v == (void*)1) + if (v == (void*)1) { tmp = all_mddevs.next; - else + } else { + to_put = mddev; tmp = mddev->all_mddevs.next; - if (tmp != &all_mddevs) - next_mddev = mddev_get(list_entry(tmp,struct mddev,all_mddevs)); - else { - next_mddev = (void*)2; - *pos = 0x10000; } + + for (;;) { + if (tmp == &all_mddevs) { + next_mddev = (void*)2; + *pos = 0x10000; + break; + } + next_mddev = list_entry(tmp, struct mddev, all_mddevs); + if (mddev_get(next_mddev)) + break; + mddev = next_mddev; + tmp = mddev->all_mddevs.next; + }; spin_unlock(&all_mddevs_lock); - if (v != (void*)1) + if (to_put) mddev_put(mddev); return next_mddev; @@ -8769,6 +8785,8 @@ void md_do_sync(struct md_thread *thread) goto skip; spin_lock(&all_mddevs_lock); list_for_each_entry(mddev2, &all_mddevs, all_mddevs) { + if (mddev2->deleted) + continue; if (mddev2 == mddev) continue; if (!mddev->parallel_resync @@ -9571,7 +9589,8 @@ static int md_notify_reboot(struct notifier_block *this, spin_lock(&all_mddevs_lock); list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) { - mddev_get(mddev); + if (!mddev_get(mddev)) + continue; spin_unlock(&all_mddevs_lock); if (mddev_trylock(mddev)) { if (mddev->pers) @@ -9926,7 +9945,8 @@ static __exit void md_exit(void) spin_lock(&all_mddevs_lock); list_for_each_entry_safe(mddev, n, &all_mddevs, all_mddevs) { - mddev_get(mddev); + if (!mddev_get(mddev)) + continue; spin_unlock(&all_mddevs_lock); export_array(mddev); mddev->ctime = 0; diff --git a/drivers/md/md.h b/drivers/md/md.h index 1a85dbe78a71c..bc870e1f1e8c2 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -503,6 +503,7 @@ struct mddev { atomic_t max_corr_read_errors; /* max read retries */ struct list_head all_mddevs; + bool deleted; const struct attribute_group *to_remove; From patchwork Wed Jul 13 11:31:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 12916599 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B0ECC43334 for ; Wed, 13 Jul 2022 11:32:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236216AbiGMLcD (ORCPT ); Wed, 13 Jul 2022 07:32:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235763AbiGMLbw (ORCPT ); Wed, 13 Jul 2022 07:31:52 -0400 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1ED4102720; Wed, 13 Jul 2022 04:31:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=jQF5bV9jdiOfWy5z7Pp3x2W7dG14gudAMuB9AiDToLQ=; b=sK+BC1G9w2sO0hQcfRLPE3X8t4 Xvd96xq5MaqMh1H52YNZivK5RJ4/z+crC2svIOvmsSrvqszK9dLaQHEEC/Qjoj8qeEUyUNfAdUxZm 0yu4Eck7i6K4rr/bsS264mcEKe+TioyorI5pEmgqTeIe1sLOCKrgj5+gyli0GshUZ85LyaXuyTs7w keuOvf2/cm9ceS/94my+yxyv0aZI55dqLcANVSR9wItTwX1H+4ey3Yiinr4OdEPKPpMn1IFEqV+8n u7j1ncXeblgULpQQLAuXDyrktgRqq2qM4Be8Gxiv3edyvo3hCv/ceHWUsDDprDvxKjWQQxhEPn8+3 6pjElC7w==; Received: from ip4d15c27d.dynamic.kabel-deutschland.de ([77.21.194.125] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1oBaaq-003ABN-HV; Wed, 13 Jul 2022 11:31:48 +0000 From: Christoph Hellwig To: Song Liu Cc: Logan Gunthorpe , linux-raid@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH 9/9] md: simplify md_open Date: Wed, 13 Jul 2022 13:31:25 +0200 Message-Id: <20220713113125.2232975-10-hch@lst.de> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220713113125.2232975-1-hch@lst.de> References: <20220713113125.2232975-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Now that devices are on the all_mddevs list until the gendisk is freed, there can't be any duplicates. Remove the global list lookup and just grab a reference. Signed-off-by: Christoph Hellwig --- drivers/md/md.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index f3ff61e540ee0..41e752c97a196 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7786,45 +7786,33 @@ static int md_set_read_only(struct block_device *bdev, bool ro) static int md_open(struct block_device *bdev, fmode_t mode) { - /* - * Succeed if we can lock the mddev, which confirms that - * it isn't being stopped right now. - */ - struct mddev *mddev = mddev_find(bdev->bd_dev); + struct mddev *mddev; int err; + spin_lock(&all_mddevs_lock); + mddev = mddev_get(bdev->bd_disk->private_data); + spin_unlock(&all_mddevs_lock); if (!mddev) return -ENODEV; - if (mddev->gendisk != bdev->bd_disk) { - /* we are racing with mddev_put which is discarding this - * bd_disk. - */ - mddev_put(mddev); - /* Wait until bdev->bd_disk is definitely gone */ - if (work_pending(&mddev->del_work)) - flush_workqueue(md_misc_wq); - return -EBUSY; - } - BUG_ON(mddev != bdev->bd_disk->private_data); - - if ((err = mutex_lock_interruptible(&mddev->open_mutex))) + err = mutex_lock_interruptible(&mddev->open_mutex); + if (err) goto out; - if (test_bit(MD_CLOSING, &mddev->flags)) { - mutex_unlock(&mddev->open_mutex); - err = -ENODEV; - goto out; - } + err = -ENODEV; + if (test_bit(MD_CLOSING, &mddev->flags)) + goto out_unlock; - err = 0; atomic_inc(&mddev->openers); mutex_unlock(&mddev->open_mutex); bdev_check_media_change(bdev); - out: - if (err) - mddev_put(mddev); + return 0; + +out_unlock: + mutex_unlock(&mddev->open_mutex); +out: + mddev_put(mddev); return err; }