block: unhash the whole device inode earlier
authorChristoph Hellwig <hch@lst.de>
Thu, 22 Jul 2021 07:53:56 +0000 (09:53 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 2 Aug 2021 19:37:28 +0000 (13:37 -0600)
Unhash the whole device inode early in del_gendisk.  This allows to
remove the first GENHD_FL_UP check in the open path as we simply
won't find a just removed inode.  The second non-racy check after
taking open_mutex is still kept.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210722075402.983367-4-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/genhd.c
fs/block_dev.c

index 298ee78..716f5ca 100644 (file)
@@ -585,6 +585,7 @@ void del_gendisk(struct gendisk *disk)
        disk_del_events(disk);
 
        mutex_lock(&disk->open_mutex);
+       remove_inode_hash(disk->part0->bd_inode);
        disk->flags &= ~GENHD_FL_UP;
        blk_drop_partitions(disk);
        mutex_unlock(&disk->open_mutex);
@@ -592,12 +593,6 @@ void del_gendisk(struct gendisk *disk)
        fsync_bdev(disk->part0);
        __invalidate_device(disk->part0, true);
 
-       /*
-        * Unhash the bdev inode for this device so that it can't be looked
-        * up any more even if openers still hold references to it.
-        */
-       remove_inode_hash(disk->part0->bd_inode);
-
        set_capacity(disk, 0);
 
        if (!(disk->flags & GENHD_FL_HIDDEN)) {
index 9ef4f1f..932f403 100644 (file)
@@ -1340,7 +1340,7 @@ struct block_device *blkdev_get_no_open(dev_t dev)
        disk = bdev->bd_disk;
        if (!kobject_get_unless_zero(&disk_to_dev(disk)->kobj))
                goto bdput;
-       if ((disk->flags & (GENHD_FL_UP | GENHD_FL_HIDDEN)) != GENHD_FL_UP)
+       if (disk->flags & GENHD_FL_HIDDEN)
                goto put_disk;
        if (!try_module_get(bdev->bd_disk->fops->owner))
                goto put_disk;