diff mbox series

[3/8] block: grab a device model reference in blkdev_get_no_open

Message ID 20210721153523.103818-4-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [1/8] block: delay freeing the gendisk | expand

Commit Message

Christoph Hellwig July 21, 2021, 3:35 p.m. UTC
Opening a block device needs to ensure it is fully present instead of
just the allocated memory.  Switch from an inode reference as obtained
by bdget to a full device model reference.

In fact we should not use inode references for anything in the block
layer.  There are three users left, two can be trivially removed
and the third (xen-blkfront) is a complete mess that needs more
attention.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/block_dev.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Ming Lei July 22, 2021, 2:47 a.m. UTC | #1
On Wed, Jul 21, 2021 at 05:35:18PM +0200, Christoph Hellwig wrote:
> Opening a block device needs to ensure it is fully present instead of
> just the allocated memory.  Switch from an inode reference as obtained
> by bdget to a full device model reference.
> 
> In fact we should not use inode references for anything in the block
> layer.  There are three users left, two can be trivially removed
> and the third (xen-blkfront) is a complete mess that needs more
> attention.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/block_dev.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/block_dev.c b/fs/block_dev.c
> index 9ef4f1fc2cb0..24a6970f3623 100644
> --- a/fs/block_dev.c
> +++ b/fs/block_dev.c
> @@ -1342,9 +1342,16 @@ struct block_device *blkdev_get_no_open(dev_t dev)
>  		goto bdput;
>  	if ((disk->flags & (GENHD_FL_UP | GENHD_FL_HIDDEN)) != GENHD_FL_UP)
>  		goto put_disk;
> -	if (!try_module_get(bdev->bd_disk->fops->owner))
> +	if (!try_module_get(disk->fops->owner))
>  		goto put_disk;
> +
> +	/* switch to a device model reference instead of the inode one: */
> +	if (!kobject_get_unless_zero(&bdev->bd_device.kobj))

If bdev->bd_device.kobj is grabbed in every open, getting disk reference might
be moved into add_partition, and drop it in part_release(). Then we can avoid
extra disk reference in open/close().

Not mention two disk references are actually grabbed in case of opening disk.

Thanks,
Ming
diff mbox series

Patch

diff --git a/fs/block_dev.c b/fs/block_dev.c
index 9ef4f1fc2cb0..24a6970f3623 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1342,9 +1342,16 @@  struct block_device *blkdev_get_no_open(dev_t dev)
 		goto bdput;
 	if ((disk->flags & (GENHD_FL_UP | GENHD_FL_HIDDEN)) != GENHD_FL_UP)
 		goto put_disk;
-	if (!try_module_get(bdev->bd_disk->fops->owner))
+	if (!try_module_get(disk->fops->owner))
 		goto put_disk;
+
+	/* switch to a device model reference instead of the inode one: */
+	if (!kobject_get_unless_zero(&bdev->bd_device.kobj))
+		goto put_module;
+	bdput(bdev);
 	return bdev;
+put_module:
+	module_put(disk->fops->owner);
 put_disk:
 	put_disk(disk);
 bdput:
@@ -1356,7 +1363,7 @@  void blkdev_put_no_open(struct block_device *bdev)
 {
 	module_put(bdev->bd_disk->fops->owner);
 	put_disk(bdev->bd_disk);
-	bdput(bdev);
+	put_device(&bdev->bd_device);
 }
 
 /**