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,
*/
void del_gendisk(struct gendisk *disk)
{
- struct disk_part_iter piter;
struct block_device *part;
might_sleep();
*/
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);
}
}
+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)
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;
}