diff mbox series

[10/10] md: simplify md_open

Message ID 20220718063410.338626-11-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [01/10] md: fix mddev->kobj lifetime | expand

Commit Message

Christoph Hellwig July 18, 2022, 6:34 a.m. UTC
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 <hch@lst.de>
---
 drivers/md/md.c | 42 +++++++++++++++---------------------------
 1 file changed, 15 insertions(+), 27 deletions(-)

Comments

Hannes Reinecke July 18, 2022, 7:19 a.m. UTC | #1
On 7/18/22 08:34, Christoph Hellwig wrote:
> 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 <hch@lst.de>
> ---
>   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 08cf21ad4c2d7..9b1e61b4bac8b 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -7785,45 +7785,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;
>   }
>   

Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
diff mbox series

Patch

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 08cf21ad4c2d7..9b1e61b4bac8b 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7785,45 +7785,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;
 }