linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* fix a race between del_gendisk and BLKRRPART v2
@ 2021-05-14 13:18 Christoph Hellwig
  2021-05-14 13:18 ` [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk Christoph Hellwig
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Christoph Hellwig @ 2021-05-14 13:18 UTC (permalink / raw)
  To: axboe; +Cc: Gulam Mohamed, Ming Lei, linux-block

Hi all,

this is based of a patch from Gulam and suggestions from Ming and fixes a
race between del_gendisk and BLKRRPART while also removing a global lock.

Changes since v1:
 - fix the GENHD_FL_UP check in __blkdev_get
 - don't change where remove_inode_hash is called for now
 - improve the commit message

Diffstat:
 block/genhd.c         |   11 +----------
 fs/block_dev.c        |   18 ++++++++----------
 include/linux/genhd.h |    2 --
 3 files changed, 9 insertions(+), 22 deletions(-)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk
  2021-05-14 13:18 fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
@ 2021-05-14 13:18 ` Christoph Hellwig
  2021-05-15  6:34   ` Ming Lei
  2021-05-14 13:18 ` [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART Christoph Hellwig
  2021-05-20  8:14 ` fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
  2 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2021-05-14 13:18 UTC (permalink / raw)
  To: axboe; +Cc: Gulam Mohamed, Ming Lei, linux-block

As an artifact of how gendisk lookup used to work in earlier kernels,
GENHD_FL_UP is only cleared very late in del_gendisk, and a global lock
is used to prevent opens from succeeding while del_gendisk is tearing
down the gendisk.  Switch to clearing the flag early and under bd_mutex
so that callers can use bd_mutex to stabilize the flag, which removes
the need for the global mutex.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 block/genhd.c         | 11 +----------
 fs/block_dev.c        | 15 +++++----------
 include/linux/genhd.h |  2 --
 3 files changed, 6 insertions(+), 22 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 39ca97b0edc6..9f8cb7beaad1 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -29,8 +29,6 @@
 
 static struct kobject *block_depr;
 
-DECLARE_RWSEM(bdev_lookup_sem);
-
 /* for extended dynamic devt allocation, currently only one major is used */
 #define NR_EXT_DEVT		(1 << MINORBITS)
 static DEFINE_IDA(ext_devt_ida);
@@ -609,13 +607,8 @@ void del_gendisk(struct gendisk *disk)
 	blk_integrity_del(disk);
 	disk_del_events(disk);
 
-	/*
-	 * Block lookups of the disk until all bdevs are unhashed and the
-	 * disk is marked as dead (GENHD_FL_UP cleared).
-	 */
-	down_write(&bdev_lookup_sem);
-
 	mutex_lock(&disk->part0->bd_mutex);
+	disk->flags &= ~GENHD_FL_UP;
 	blk_drop_partitions(disk);
 	mutex_unlock(&disk->part0->bd_mutex);
 
@@ -629,8 +622,6 @@ void del_gendisk(struct gendisk *disk)
 	remove_inode_hash(disk->part0->bd_inode);
 
 	set_capacity(disk, 0);
-	disk->flags &= ~GENHD_FL_UP;
-	up_write(&bdev_lookup_sem);
 
 	if (!(disk->flags & GENHD_FL_HIDDEN)) {
 		sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
diff --git a/fs/block_dev.c b/fs/block_dev.c
index eb265d72fce8..580bae995b87 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1298,6 +1298,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode)
 	struct gendisk *disk = bdev->bd_disk;
 	int ret = 0;
 
+	if (!(disk->flags & GENHD_FL_UP))
+		return -ENXIO;
+
 	if (!bdev->bd_openers) {
 		if (!bdev_is_partition(bdev)) {
 			ret = 0;
@@ -1332,8 +1335,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode)
 			whole->bd_part_count++;
 			mutex_unlock(&whole->bd_mutex);
 
-			if (!(disk->flags & GENHD_FL_UP) ||
-			    !bdev_nr_sectors(bdev)) {
+			if (!bdev_nr_sectors(bdev)) {
 				__blkdev_put(whole, mode, 1);
 				bdput(whole);
 				return -ENXIO;
@@ -1364,16 +1366,12 @@ struct block_device *blkdev_get_no_open(dev_t dev)
 	struct block_device *bdev;
 	struct gendisk *disk;
 
-	down_read(&bdev_lookup_sem);
 	bdev = bdget(dev);
 	if (!bdev) {
-		up_read(&bdev_lookup_sem);
 		blk_request_module(dev);
-		down_read(&bdev_lookup_sem);
-
 		bdev = bdget(dev);
 		if (!bdev)
-			goto unlock;
+			return NULL;
 	}
 
 	disk = bdev->bd_disk;
@@ -1383,14 +1381,11 @@ struct block_device *blkdev_get_no_open(dev_t dev)
 		goto put_disk;
 	if (!try_module_get(bdev->bd_disk->fops->owner))
 		goto put_disk;
-	up_read(&bdev_lookup_sem);
 	return bdev;
 put_disk:
 	put_disk(disk);
 bdput:
 	bdput(bdev);
-unlock:
-	up_read(&bdev_lookup_sem);
 	return NULL;
 }
 
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 7e9660ea967d..6fc26f7bdf71 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -306,8 +306,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev,
 }
 #endif /* CONFIG_SYSFS */
 
-extern struct rw_semaphore bdev_lookup_sem;
-
 dev_t blk_lookup_devt(const char *name, int partno);
 void blk_request_module(dev_t devt);
 #ifdef CONFIG_BLOCK
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART
  2021-05-14 13:18 fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
  2021-05-14 13:18 ` [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk Christoph Hellwig
@ 2021-05-14 13:18 ` Christoph Hellwig
  2021-05-15  6:35   ` Ming Lei
  2021-05-20  8:14 ` fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
  2 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2021-05-14 13:18 UTC (permalink / raw)
  To: axboe; +Cc: Gulam Mohamed, Ming Lei, linux-block

From: Gulam Mohamed <gulam.mohamed@oracle.com>

When BLKRRPART is called concurrently with del_gendisk, the partitions
rescan can create a stale partition that will never be be cleaned up.

Fix this by checking the the disk is up before rescanning partitions
while under bd_mutex.

Signed-off-by: Gulam Mohamed <gulam.mohamed@oracle.com>
[hch: split from a larger patch]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/block_dev.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 580bae995b87..4494411fa4d3 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1244,6 +1244,9 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate)
 
 	lockdep_assert_held(&bdev->bd_mutex);
 
+	if (!(disk->flags & GENHD_FL_UP))
+		return -ENXIO;
+
 rescan:
 	if (bdev->bd_part_count)
 		return -EBUSY;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk
  2021-05-14 13:18 ` [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk Christoph Hellwig
@ 2021-05-15  6:34   ` Ming Lei
  2021-05-20 17:37     ` Gulam Mohamed
  0 siblings, 1 reply; 9+ messages in thread
From: Ming Lei @ 2021-05-15  6:34 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: axboe, Gulam Mohamed, linux-block

On Fri, May 14, 2021 at 03:18:41PM +0200, Christoph Hellwig wrote:
> As an artifact of how gendisk lookup used to work in earlier kernels,
> GENHD_FL_UP is only cleared very late in del_gendisk, and a global lock
> is used to prevent opens from succeeding while del_gendisk is tearing
> down the gendisk.  Switch to clearing the flag early and under bd_mutex
> so that callers can use bd_mutex to stabilize the flag, which removes
> the need for the global mutex.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Ming Lei <ming.lei@redhat.com>

-- 
Ming


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART
  2021-05-14 13:18 ` [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART Christoph Hellwig
@ 2021-05-15  6:35   ` Ming Lei
  2021-05-20 17:37     ` Gulam Mohamed
  0 siblings, 1 reply; 9+ messages in thread
From: Ming Lei @ 2021-05-15  6:35 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: axboe, Gulam Mohamed, linux-block

On Fri, May 14, 2021 at 03:18:42PM +0200, Christoph Hellwig wrote:
> From: Gulam Mohamed <gulam.mohamed@oracle.com>
> 
> When BLKRRPART is called concurrently with del_gendisk, the partitions
> rescan can create a stale partition that will never be be cleaned up.
> 
> Fix this by checking the the disk is up before rescanning partitions
> while under bd_mutex.
> 
> Signed-off-by: Gulam Mohamed <gulam.mohamed@oracle.com>
> [hch: split from a larger patch]
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/block_dev.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/block_dev.c b/fs/block_dev.c
> index 580bae995b87..4494411fa4d3 100644
> --- a/fs/block_dev.c
> +++ b/fs/block_dev.c
> @@ -1244,6 +1244,9 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate)
>  
>  	lockdep_assert_held(&bdev->bd_mutex);
>  
> +	if (!(disk->flags & GENHD_FL_UP))
> +		return -ENXIO;
> +
>  rescan:
>  	if (bdev->bd_part_count)
>  		return -EBUSY;

Reviewed-by: Ming Lei <ming.lei@redhat.com>

-- 
Ming


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fix a race between del_gendisk and BLKRRPART v2
  2021-05-14 13:18 fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
  2021-05-14 13:18 ` [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk Christoph Hellwig
  2021-05-14 13:18 ` [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART Christoph Hellwig
@ 2021-05-20  8:14 ` Christoph Hellwig
  2021-05-20 13:59   ` Jens Axboe
  2 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2021-05-20  8:14 UTC (permalink / raw)
  To: axboe; +Cc: Gulam Mohamed, Ming Lei, linux-block

Jens,

can you take a look at these?

On Fri, May 14, 2021 at 03:18:40PM +0200, Christoph Hellwig wrote:
> Hi all,
> 
> this is based of a patch from Gulam and suggestions from Ming and fixes a
> race between del_gendisk and BLKRRPART while also removing a global lock.
> 
> Changes since v1:
>  - fix the GENHD_FL_UP check in __blkdev_get
>  - don't change where remove_inode_hash is called for now
>  - improve the commit message
> 
> Diffstat:
>  block/genhd.c         |   11 +----------
>  fs/block_dev.c        |   18 ++++++++----------
>  include/linux/genhd.h |    2 --
>  3 files changed, 9 insertions(+), 22 deletions(-)
---end quoted text---

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fix a race between del_gendisk and BLKRRPART v2
  2021-05-20  8:14 ` fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
@ 2021-05-20 13:59   ` Jens Axboe
  0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2021-05-20 13:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Gulam Mohamed, Ming Lei, linux-block

On 5/20/21 2:14 AM, Christoph Hellwig wrote:
> Jens,
> 
> can you take a look at these?

Looks good to me, applied.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk
  2021-05-15  6:34   ` Ming Lei
@ 2021-05-20 17:37     ` Gulam Mohamed
  0 siblings, 0 replies; 9+ messages in thread
From: Gulam Mohamed @ 2021-05-20 17:37 UTC (permalink / raw)
  To: Ming Lei, Christoph Hellwig; +Cc: axboe, linux-block



-----Original Message-----
From: Ming Lei <ming.lei@redhat.com> 
Sent: Saturday, May 15, 2021 12:05 PM
To: Christoph Hellwig <hch@lst.de>
Cc: axboe@kernel.dk; Gulam Mohamed <gulam.mohamed@oracle.com>; linux-block@vger.kernel.org
Subject: Re: [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk

On Fri, May 14, 2021 at 03:18:41PM +0200, Christoph Hellwig wrote:
> As an artifact of how gendisk lookup used to work in earlier kernels, 
> GENHD_FL_UP is only cleared very late in del_gendisk, and a global 
> lock is used to prevent opens from succeeding while del_gendisk is 
> tearing down the gendisk.  Switch to clearing the flag early and under 
> bd_mutex so that callers can use bd_mutex to stabilize the flag, which 
> removes the need for the global mutex.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: Ming Lei <ming.lei@redhat.com>

I have tested these patches on latest kernel in our environment and didn't find any issue. The fix is working fine.

Tested-by: Gulam Mohamed <gulam.mohamed@oracle.com>

--
Ming


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART
  2021-05-15  6:35   ` Ming Lei
@ 2021-05-20 17:37     ` Gulam Mohamed
  0 siblings, 0 replies; 9+ messages in thread
From: Gulam Mohamed @ 2021-05-20 17:37 UTC (permalink / raw)
  To: Ming Lei, Christoph Hellwig; +Cc: axboe, linux-block



-----Original Message-----
From: Ming Lei <ming.lei@redhat.com> 
Sent: Saturday, May 15, 2021 12:05 PM
To: Christoph Hellwig <hch@lst.de>
Cc: axboe@kernel.dk; Gulam Mohamed <gulam.mohamed@oracle.com>; linux-block@vger.kernel.org
Subject: Re: [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART

On Fri, May 14, 2021 at 03:18:42PM +0200, Christoph Hellwig wrote:
> From: Gulam Mohamed <gulam.mohamed@oracle.com>
> 
> When BLKRRPART is called concurrently with del_gendisk, the partitions 
> rescan can create a stale partition that will never be be cleaned up.
> 
> Fix this by checking the the disk is up before rescanning partitions 
> while under bd_mutex.
> 
> Signed-off-by: Gulam Mohamed <gulam.mohamed@oracle.com>
> [hch: split from a larger patch]
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/block_dev.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/block_dev.c b/fs/block_dev.c index 
> 580bae995b87..4494411fa4d3 100644
> --- a/fs/block_dev.c
> +++ b/fs/block_dev.c
> @@ -1244,6 +1244,9 @@ int bdev_disk_changed(struct block_device *bdev, 
> bool invalidate)
>  
>  	lockdep_assert_held(&bdev->bd_mutex);
>  
> +	if (!(disk->flags & GENHD_FL_UP))
> +		return -ENXIO;
> +
>  rescan:
>  	if (bdev->bd_part_count)
>  		return -EBUSY;

Reviewed-by: Ming Lei <ming.lei@redhat.com>
Tested-by: Gulam Mohamed <gulam.mohamed@oracle.com>

--
Ming


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-05-20 17:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-14 13:18 fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
2021-05-14 13:18 ` [PATCH 1/2] block: prevent block device lookups at the beginning of del_gendisk Christoph Hellwig
2021-05-15  6:34   ` Ming Lei
2021-05-20 17:37     ` Gulam Mohamed
2021-05-14 13:18 ` [PATCH 2/2] block: fix a race between del_gendisk and BLKRRPART Christoph Hellwig
2021-05-15  6:35   ` Ming Lei
2021-05-20 17:37     ` Gulam Mohamed
2021-05-20  8:14 ` fix a race between del_gendisk and BLKRRPART v2 Christoph Hellwig
2021-05-20 13:59   ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).