From patchwork Wed Feb 24 03:58:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 12101229 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0402C433E0 for ; Wed, 24 Feb 2021 04:00:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 71EFC64E6F for ; Wed, 24 Feb 2021 04:00:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231815AbhBXEAS (ORCPT ); Tue, 23 Feb 2021 23:00:18 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:56873 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229999AbhBXEAQ (ORCPT ); Tue, 23 Feb 2021 23:00:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614139130; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DSml4ZDvXo8RN3I4XE8bl8UTrUdFIfkGqMaNCq86Rms=; b=ULV4otz8SG2uz1diAdCC8LdgrKdw0PLofEG5LL1xHP0y1ydGPBjDf3bXMB/O0tSljvcBh8 PU/y2NSHutVcD5+e8+Y76dDNtouLQYU9R35rrvSYfmHaX/yOtp5+aJP1hiFI+quw6LBNQN R8j1hYkm7G5XRd5ki84NHe/T5OudFAY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-498-FoRpbip5Pq-AAlKASE6KMg-1; Tue, 23 Feb 2021 22:58:48 -0500 X-MC-Unique: FoRpbip5Pq-AAlKASE6KMg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E76F51009617; Wed, 24 Feb 2021 03:58:46 +0000 (UTC) Received: from localhost (ovpn-13-84.pek2.redhat.com [10.72.13.84]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4245F709AF; Wed, 24 Feb 2021 03:58:42 +0000 (UTC) From: Ming Lei To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Ming Lei , Ewan Milne Subject: [PATCH V2 1/4] block: define parsed_partitions.flags as 'unsigned char' Date: Wed, 24 Feb 2021 11:58:27 +0800 Message-Id: <20210224035830.990123-2-ming.lei@redhat.com> In-Reply-To: <20210224035830.990123-1-ming.lei@redhat.com> References: <20210224035830.990123-1-ming.lei@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org So far, only 3 partition flags are used, it is enough to hold it in 'unsigned char'. Cc: Ewan Milne Signed-off-by: Ming Lei Reviewed-by: Chaitanya Kulkarni --- block/partitions/check.h | 2 +- block/partitions/core.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/block/partitions/check.h b/block/partitions/check.h index c577e9ee67f0..8f0ceed06c7b 100644 --- a/block/partitions/check.h +++ b/block/partitions/check.h @@ -14,7 +14,7 @@ struct parsed_partitions { struct { sector_t from; sector_t size; - int flags; + unsigned char flags; bool has_info; struct partition_meta_info info; } *parts; diff --git a/block/partitions/core.c b/block/partitions/core.c index f3d9ff2cafb6..430ff7863556 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -314,7 +314,8 @@ static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); * after all disk users are gone. */ static struct block_device *add_partition(struct gendisk *disk, int partno, - sector_t start, sector_t len, int flags, + sector_t start, sector_t len, + unsigned char flags, struct partition_meta_info *info) { dev_t devt = MKDEV(0, 0); From patchwork Wed Feb 24 03:58:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 12101231 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2D8BC433E0 for ; Wed, 24 Feb 2021 04:00:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8291E64E6F for ; Wed, 24 Feb 2021 04:00:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231960AbhBXEAa (ORCPT ); Tue, 23 Feb 2021 23:00:30 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:52756 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229999AbhBXEAX (ORCPT ); Tue, 23 Feb 2021 23:00:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614139136; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FtfQQCnSFSuFYurXQqBEBDrftjlvJqpZVtMEbRYONZo=; b=cOAINJmTSbjJilYedEet0X1F9Fcw4MNx0nnN75Ty6skPrxFvhzdNft65BjwChKBuAqZRZ8 +al41xmCfnH6gceOstQCkeFG8JrHYGZ3LrwrqvkTTcY6wrPS4MKWH2h907IJJbuqBO3BzL Ft5JZHbBz5OC46+XdmGlS3BwxHjT3o4= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-18-XPMZrcXzMa2r_0PLJNnPEA-1; Tue, 23 Feb 2021 22:58:52 -0500 X-MC-Unique: XPMZrcXzMa2r_0PLJNnPEA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 413488799E0; Wed, 24 Feb 2021 03:58:51 +0000 (UTC) Received: from localhost (ovpn-13-84.pek2.redhat.com [10.72.13.84]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8060610016F0; Wed, 24 Feb 2021 03:58:50 +0000 (UTC) From: Ming Lei To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Ming Lei , Ewan Milne Subject: [PATCH V2 2/4] block: store partition flags into block_device Date: Wed, 24 Feb 2021 11:58:28 +0800 Message-Id: <20210224035830.990123-3-ming.lei@redhat.com> In-Reply-To: <20210224035830.990123-1-ming.lei@redhat.com> References: <20210224035830.990123-1-ming.lei@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org Prepare for checking if partition is changed. Cc: Ewan Milne Signed-off-by: Ming Lei --- block/partitions/core.c | 1 + include/linux/blk_types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/block/partitions/core.c b/block/partitions/core.c index 430ff7863556..07981f663f66 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -352,6 +352,7 @@ static struct block_device *add_partition(struct gendisk *disk, int partno, bdev->bd_start_sect = start; bdev_set_nr_sectors(bdev, len); + bdev->bd_part_flags = flags; if (info) { err = -ENOMEM; diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index db026b6ec15a..4d43b80cb9e9 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -40,6 +40,7 @@ struct block_device { #endif struct kobject *bd_holder_dir; u8 bd_partno; + u8 bd_part_flags; /* number of times partitions within this device have been opened. */ unsigned bd_part_count; From patchwork Wed Feb 24 03:58:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 12101233 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49B38C433DB for ; Wed, 24 Feb 2021 04:00:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0BBA064E6F for ; Wed, 24 Feb 2021 04:00:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229999AbhBXEAa (ORCPT ); Tue, 23 Feb 2021 23:00:30 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:32001 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231818AbhBXEA0 (ORCPT ); Tue, 23 Feb 2021 23:00:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614139139; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DHSXDo9mD4eH/G723x6kBQManvhXFhnAHnvz/FOMDGk=; b=d0ZcQ3o3THyaofFWS436E9FVsllE4GVH5wRmxKrKL8c3GFanY2/f/pfNySfBibyincDhs+ f4ftB9fTiYXs6MeeA3VR6vRsW2JUQUqCdILFFAfPcGdaXIdUMQbwAfoX7VtNVZUKNKHZRb ldjeWHyo2y9wkZ3TzCID4lHUsAE/Fxc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-410-ICN5jDvcPLel_wvGmugy5g-1; Tue, 23 Feb 2021 22:58:57 -0500 X-MC-Unique: ICN5jDvcPLel_wvGmugy5g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ACF51107ACE4; Wed, 24 Feb 2021 03:58:56 +0000 (UTC) Received: from localhost (ovpn-13-84.pek2.redhat.com [10.72.13.84]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3113D5D9D3; Wed, 24 Feb 2021 03:58:52 +0000 (UTC) From: Ming Lei To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Ming Lei , "Ewan D . Milne" Subject: [PATCH V2 3/4] block: re-organize blk_add_partitions Date: Wed, 24 Feb 2021 11:58:29 +0800 Message-Id: <20210224035830.990123-4-ming.lei@redhat.com> In-Reply-To: <20210224035830.990123-1-ming.lei@redhat.com> References: <20210224035830.990123-1-ming.lei@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org No functional change, make code more readable, just split blk_add_partitions() into two helpers. Cc: Ewan D. Milne Signed-off-by: Ming Lei --- block/partitions/core.c | 50 +++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/block/partitions/core.c b/block/partitions/core.c index 07981f663f66..288ca362ccbd 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -603,17 +603,19 @@ static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev, return true; } -int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) +static int __blk_check_partitions(struct gendisk *disk, + struct block_device *bdev, struct parsed_partitions **s) { - struct parsed_partitions *state; - int ret = -EAGAIN, p; + struct parsed_partitions *state = NULL; + int ret = -EAGAIN; if (!disk_part_scan_enabled(disk)) - return 0; + goto out; state = check_partition(disk, bdev); if (!state) - return 0; + goto out; + if (IS_ERR(state)) { /* * I/O error reading the partition table. If we tried to read @@ -651,15 +653,45 @@ int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) goto out_free_state; } +out: + *s = state; + return 0; + +out_free_state: + free_partitions(state); + *s = NULL; + return ret; +} + +static int __blk_add_partitions(struct gendisk *disk, + struct block_device *bdev, struct parsed_partitions *state) +{ + int p; + /* tell userspace that the media / partition table may have changed */ kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); - for (p = 1; p < state->limit; p++) + for (p = 1; p < state->limit; p++) { if (!blk_add_partition(disk, bdev, state, p)) - goto out_free_state; + return -EAGAIN; + } + + return 0; +} + +int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) +{ + struct parsed_partitions *state; + int ret; + + ret = __blk_check_partitions(disk, bdev, &state); + if (ret != 0) + return ret; + if (!state) + return 0; + + ret = __blk_add_partitions(disk, bdev, state); - ret = 0; -out_free_state: free_partitions(state); return ret; } From patchwork Wed Feb 24 03:58:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 12101235 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9451FC433DB for ; Wed, 24 Feb 2021 04:00:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4FEAD64E6F for ; Wed, 24 Feb 2021 04:00:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231818AbhBXEAb (ORCPT ); Tue, 23 Feb 2021 23:00:31 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:26647 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231830AbhBXEAa (ORCPT ); Tue, 23 Feb 2021 23:00:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614139143; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LHBknFIt+0/1Hpcw0tAEzIAQQFK/DWozhqXdCgJetS8=; b=Le61oUkou88eMTfWEg7J+SVv77r/3DQCmaWLq+Xhr4zkJz5B1qFg96//nvE9y3eb85Azlm ZOhKcFOBa5zy65ZtqFifXp2rqfXV1lGSwPrX6UgXJDUjYDj0wgXTO2PePECof+RDlxQMiF 1zVz20weELZE7/HR7iz3rPFAmCZ6grA= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-63-E5Xjj68rNKyfkVeAxQ-P5A-1; Tue, 23 Feb 2021 22:59:01 -0500 X-MC-Unique: E5Xjj68rNKyfkVeAxQ-P5A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0DF6B8799EB; Wed, 24 Feb 2021 03:59:00 +0000 (UTC) Received: from localhost (ovpn-13-84.pek2.redhat.com [10.72.13.84]) by smtp.corp.redhat.com (Postfix) with ESMTP id 371D57095A; Wed, 24 Feb 2021 03:58:58 +0000 (UTC) From: Ming Lei To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Ming Lei , "Ewan D . Milne" Subject: [PATCH V2 4/4] block: avoid to drop & re-add partitions if partitions aren't changed Date: Wed, 24 Feb 2021 11:58:30 +0800 Message-Id: <20210224035830.990123-5-ming.lei@redhat.com> In-Reply-To: <20210224035830.990123-1-ming.lei@redhat.com> References: <20210224035830.990123-1-ming.lei@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org block ioctl(BLKRRPART) always drops current partitions and adds partitions again, even though there isn't any change in partitions table. ioctl(BLKRRPART) is called by systemd-udevd and some disk utilities not unusually. When it is run, partitions disk node are dropped and added back, this way may confuse userspace or users, for example, one normal workable partition device node may disappear any time. Fix this issue by checking if there is real change in partitions, and only drop & re-add them when partitions state is really changed. Cc: Ewan D. Milne Signed-off-by: Ming Lei --- block/partitions/core.c | 76 ++++++++++++++++++++++++++++++++++++++--- fs/block_dev.c | 30 ++++++++-------- include/linux/genhd.h | 1 + 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/block/partitions/core.c b/block/partitions/core.c index 288ca362ccbd..901a00fed3c9 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -123,7 +123,7 @@ static void free_partitions(struct parsed_partitions *state) } static struct parsed_partitions *check_partition(struct gendisk *hd, - struct block_device *bdev) + struct block_device *bdev, bool show_part) { struct parsed_partitions *state; int i, res, err; @@ -159,7 +159,8 @@ static struct parsed_partitions *check_partition(struct gendisk *hd, } if (res > 0) { - printk(KERN_INFO "%s", state->pp_buf); + if (show_part) + printk(KERN_INFO "%s", state->pp_buf); free_page((unsigned long)state->pp_buf); return state; @@ -604,7 +605,8 @@ static bool blk_add_partition(struct gendisk *disk, struct block_device *bdev, } static int __blk_check_partitions(struct gendisk *disk, - struct block_device *bdev, struct parsed_partitions **s) + struct block_device *bdev, struct parsed_partitions **s, + bool show_part) { struct parsed_partitions *state = NULL; int ret = -EAGAIN; @@ -612,7 +614,7 @@ static int __blk_check_partitions(struct gendisk *disk, if (!disk_part_scan_enabled(disk)) goto out; - state = check_partition(disk, bdev); + state = check_partition(disk, bdev, show_part); if (!state) goto out; @@ -679,12 +681,76 @@ static int __blk_add_partitions(struct gendisk *disk, return 0; } +static bool partition_changed(struct block_device *part, + struct parsed_partitions *state) +{ + int p = part->bd_partno; + + if (part->bd_start_sect != state->parts[p].from) + return true; + + if (bdev_nr_sectors(part) != state->parts[p].size) + return true; + + if (part->bd_part_flags != state->parts[p].flags) + return true; + + if (bcmp(part->bd_meta_info, &state->parts[p].info, + sizeof(struct partition_meta_info))) + return true; + + return false; +} + +static int partition_count(struct parsed_partitions *state) +{ + int p; + int cnt = 0; + + for (p = 1; p < state->limit; p++) { + if (state->parts[p].size || state->parts[p].from) + cnt++; + } + return cnt; +} + +bool blk_partition_changed(struct gendisk *disk, struct block_device *bdev) +{ + struct disk_part_iter piter; + struct block_device *part; + struct parsed_partitions *state = NULL; + bool changed = true; + int nr_parts = 0; + + if (!get_capacity(disk)) + goto out; + + if (__blk_check_partitions(disk, bdev, &state, false) != 0 || !state) + goto out; + + changed = false; + disk_part_iter_init(&piter, disk, 0); + while ((part = disk_part_iter_next(&piter))) { + if (partition_changed(part, state)) + changed = true; + nr_parts++; + } + disk_part_iter_exit(&piter); + + if (nr_parts != partition_count(state)) + changed = true; + out: + if (state) + free_partitions(state); + return changed; +} + int blk_add_partitions(struct gendisk *disk, struct block_device *bdev) { struct parsed_partitions *state; int ret; - ret = __blk_check_partitions(disk, bdev, &state); + ret = __blk_check_partitions(disk, bdev, &state, true); if (ret != 0) return ret; if (!state) diff --git a/fs/block_dev.c b/fs/block_dev.c index ec26179c8062..b279649ba532 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1234,10 +1234,6 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) clear_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state); rescan: - ret = blk_drop_partitions(bdev); - if (ret) - return ret; - /* * Historically we only set the capacity to zero for devices that * support partitions (independ of actually having partitions created). @@ -1255,16 +1251,22 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) disk->fops->revalidate_disk(disk); } - if (get_capacity(disk)) { - ret = blk_add_partitions(disk, bdev); - if (ret == -EAGAIN) - goto rescan; - } else if (invalidate) { - /* - * Tell userspace that the media / partition table may have - * changed. - */ - kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + if (blk_partition_changed(disk, bdev)) { + ret = blk_drop_partitions(bdev); + if (ret) + return ret; + + if (get_capacity(disk)) { + ret = blk_add_partitions(disk, bdev); + if (ret == -EAGAIN) + goto rescan; + } else if (invalidate) { + /* + * Tell userspace that the media / partition table may have + * changed. + */ + kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE); + } } return ret; diff --git a/include/linux/genhd.h b/include/linux/genhd.h index f364619092cc..ae9ebfb9a8e1 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -274,6 +274,7 @@ static inline sector_t get_capacity(struct gendisk *disk) int bdev_disk_changed(struct block_device *bdev, bool invalidate); int blk_add_partitions(struct gendisk *disk, struct block_device *bdev); int blk_drop_partitions(struct block_device *bdev); +bool blk_partition_changed(struct gendisk *disk, struct block_device *bdev); extern struct gendisk *__alloc_disk_node(int minors, int node_id); extern void put_disk(struct gendisk *disk);