]> www.infradead.org Git - users/hch/block.git/commitdiff
block: grab a device model reference in blkdev_get_no_open
authorChristoph Hellwig <hch@lst.de>
Tue, 29 Jun 2021 12:08:59 +0000 (14:08 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 21 Jul 2021 06:32:06 +0000 (08:32 +0200)
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

index 9ef4f1fc2cb0186c43066826c130fac24e5cf4e1..24a6970f3623aa6f9647881b5c568e09065850ab 100644 (file)
@@ -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);
 }
 
 /**