]> www.infradead.org Git - users/hch/block.git/commitdiff
block: simplify partition removal
authorChristoph Hellwig <hch@lst.de>
Wed, 24 Mar 2021 09:27:52 +0000 (10:27 +0100)
committerChristoph Hellwig <hch@lst.de>
Wed, 24 Mar 2021 09:47:12 +0000 (10:47 +0100)
Always look up the first available entry instead of the complicated
stateful traversal.

Signed-off-by: Christoph Hellwig <hch@lst.de>
block/blk.h
block/genhd.c
block/partitions/core.c

index 3b53e44b967e4ec638d86fb7578bb60ea29db138..07fe6220b9a093c62f0e1f79941e94e0bdd31e70 100644 (file)
@@ -352,6 +352,7 @@ int bdev_add_partition(struct block_device *bdev, int partno,
 int bdev_del_partition(struct block_device *bdev, int partno);
 int bdev_resize_partition(struct block_device *bdev, int partno,
                sector_t start, sector_t length);
+struct block_device *first_partition(struct gendisk *disk);
 
 int bio_add_hw_page(struct request_queue *q, struct bio *bio,
                struct page *page, unsigned int len, unsigned int offset,
index fcc530164b5ab4d06dac4175f03b79949e92d280..6f94e8fdab30ccfbc4c2eeab1c9680663d78a9c3 100644 (file)
@@ -682,7 +682,6 @@ static void invalidate_partition(struct block_device *bdev)
  */
 void del_gendisk(struct gendisk *disk)
 {
-       struct disk_part_iter piter;
        struct block_device *part;
 
        might_sleep();
@@ -699,13 +698,11 @@ void del_gendisk(struct gendisk *disk)
         */
        down_write(&bdev_lookup_sem);
 
-       /* invalidate stuff */
-       disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
-       while ((part = disk_part_iter_next(&piter))) {
+       while ((part = first_partition(disk))) {
                invalidate_partition(part);
                delete_partition(part);
+               bdput(part);
        }
-       disk_part_iter_exit(&piter);
 
        invalidate_partition(disk->part0);
        set_capacity(disk, 0);
index f3d9ff2cafb6927c4d168d5271ae5645e48d4b3a..78eb20862edf4b6ac71b60ba0b600e20fc6a5b01 100644 (file)
@@ -528,9 +528,22 @@ static bool disk_unlock_native_capacity(struct gendisk *disk)
        }
 }
 
+struct block_device *first_partition(struct gendisk *disk)
+{
+       struct block_device *part;
+       unsigned long idx = 1; /* 0 is the whole device */
+
+       rcu_read_lock();
+       part = xa_find(&disk->part_tbl, &idx, ULONG_MAX, XA_PRESENT);
+       if (part && !bdgrab(part))
+               part = NULL;
+       rcu_read_unlock();
+
+       return part;
+}
+
 int blk_drop_partitions(struct block_device *bdev)
 {
-       struct disk_part_iter piter;
        struct block_device *part;
 
        if (bdev->bd_part_count)
@@ -539,10 +552,10 @@ int blk_drop_partitions(struct block_device *bdev)
        sync_blockdev(bdev);
        invalidate_bdev(bdev);
 
-       disk_part_iter_init(&piter, bdev->bd_disk, DISK_PITER_INCL_EMPTY);
-       while ((part = disk_part_iter_next(&piter)))
+       while ((part = first_partition(bdev->bd_disk))) {
                delete_partition(part);
-       disk_part_iter_exit(&piter);
+               bdput(part);
+       }
 
        return 0;
 }