OSDN Git Service

block: split __blkdev_put
authorChristoph Hellwig <hch@lst.de>
Tue, 25 May 2021 06:12:58 +0000 (08:12 +0200)
committerJens Axboe <axboe@kernel.dk>
Tue, 1 Jun 2021 13:44:56 +0000 (07:44 -0600)
Split __blkdev_put into one helper for the whole device, and one for
partitions as well as another shared helper for flushing the block
device inode mapping.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20210525061301.2242282-6-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/block_dev.c

index 43dce92..cd45b54 100644 (file)
@@ -1234,7 +1234,13 @@ void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk)
 EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
 #endif
 
-static void __blkdev_put(struct block_device *bdev, fmode_t mode);
+static void blkdev_flush_mapping(struct block_device *bdev)
+{
+       WARN_ON_ONCE(bdev->bd_holders);
+       sync_blockdev(bdev);
+       kill_bdev(bdev);
+       bdev_write_inode(bdev);
+}
 
 int bdev_disk_changed(struct block_device *bdev, bool invalidate)
 {
@@ -1316,6 +1322,14 @@ static int blkdev_get_whole(struct block_device *bdev, fmode_t mode)
        return 0;;
 }
 
+static void blkdev_put_whole(struct block_device *bdev, fmode_t mode)
+{
+       if (!--bdev->bd_openers)
+               blkdev_flush_mapping(bdev);
+       if (bdev->bd_disk->fops->release)
+               bdev->bd_disk->fops->release(bdev->bd_disk, mode);
+}
+
 static int blkdev_get_part(struct block_device *part, fmode_t mode)
 {
        struct gendisk *disk = part->bd_disk;
@@ -1343,12 +1357,24 @@ done:
        return 0;
 
 out_blkdev_put:
-       __blkdev_put(whole, mode);
+       blkdev_put_whole(whole, mode);
 out_put_whole:
        bdput(whole);
        return ret;
 }
 
+static void blkdev_put_part(struct block_device *part, fmode_t mode)
+{
+       struct block_device *whole = bdev_whole(part);
+
+       if (--part->bd_openers)
+               return;
+       blkdev_flush_mapping(part);
+       whole->bd_part_count--;
+       blkdev_put_whole(whole, mode);
+       bdput(whole);
+}
+
 struct block_device *blkdev_get_no_open(dev_t dev)
 {
        struct block_device *bdev;
@@ -1542,29 +1568,6 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        return 0;
 }
 
-static void __blkdev_put(struct block_device *bdev, fmode_t mode)
-{
-       struct gendisk *disk = bdev->bd_disk;
-       struct block_device *victim = NULL;
-
-       if (!--bdev->bd_openers) {
-               WARN_ON_ONCE(bdev->bd_holders);
-               sync_blockdev(bdev);
-               kill_bdev(bdev);
-               bdev_write_inode(bdev);
-               if (bdev_is_partition(bdev))
-                       victim = bdev_whole(bdev);
-       }
-
-       if (!bdev_is_partition(bdev) && disk->fops->release)
-               disk->fops->release(disk, mode);
-       if (victim) {
-               victim->bd_part_count--;
-               __blkdev_put(victim, mode);
-               bdput(victim);
-       }
-}
-
 void blkdev_put(struct block_device *bdev, fmode_t mode)
 {
        struct gendisk *disk = bdev->bd_disk;
@@ -1618,7 +1621,10 @@ void blkdev_put(struct block_device *bdev, fmode_t mode)
         */
        disk_flush_events(disk, DISK_EVENT_MEDIA_CHANGE);
 
-       __blkdev_put(bdev, mode);
+       if (bdev_is_partition(bdev))
+               blkdev_put_part(bdev, mode);
+       else
+               blkdev_put_whole(bdev, mode);
        mutex_unlock(&disk->open_mutex);
 
        blkdev_put_no_open(bdev);