void delete_partition(struct gendisk *disk, int partno)
{
+ struct disk_part_tbl *ptbl = disk->part_tbl;
struct hd_struct *part;
- part = disk->__part[partno];
+ if (partno >= ptbl->len)
+ return;
+
+ part = ptbl->part[partno];
if (!part)
return;
blk_free_devt(part_devt(part));
- rcu_assign_pointer(disk->__part[partno], NULL);
+ rcu_assign_pointer(ptbl->part[partno], NULL);
kobject_put(part->holder_dir);
device_del(part_to_dev(part));
dev_t devt = MKDEV(0, 0);
struct device *ddev = disk_to_dev(disk);
struct device *pdev;
+ struct disk_part_tbl *ptbl;
const char *dname;
int err;
- if (disk->__part[partno])
+ err = disk_expand_part_tbl(disk, partno);
+ if (err)
+ return err;
+ ptbl = disk->part_tbl;
+
+ if (ptbl->part[partno])
return -EBUSY;
p = kzalloc(sizeof(*p), GFP_KERNEL);
/* everything is up and running, commence */
INIT_RCU_HEAD(&p->rcu_head);
- rcu_assign_pointer(disk->__part[partno], p);
+ rcu_assign_pointer(ptbl->part[partno], p);
/* suppress uevent if the disk supresses it */
if (!ddev->uevent_suppress)
struct disk_part_iter piter;
struct hd_struct *part;
struct parsed_partitions *state;
- int p, res;
+ int p, highest, res;
if (bdev->bd_part_count)
return -EBUSY;
res = invalidate_partition(disk, 0);
if (res)
return res;
- bdev->bd_invalidated = 0;
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
while ((part = disk_part_iter_next(&piter)))
if (disk->fops->revalidate_disk)
disk->fops->revalidate_disk(disk);
+ check_disk_size_change(disk, bdev);
+ bdev->bd_invalidated = 0;
if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
return 0;
if (IS_ERR(state)) /* I/O error reading the partition table */
/* tell userspace that the media / partition table may have changed */
kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
+ /* Detect the highest partition number and preallocate
+ * disk->part_tbl. This is an optimization and not strictly
+ * necessary.
+ */
+ for (p = 1, highest = 0; p < state->limit; p++)
+ if (state->parts[p].size)
+ highest = p;
+
+ disk_expand_part_tbl(disk, highest);
+
+ /* add partitions */
for (p = 1; p < state->limit; p++) {
sector_t size = state->parts[p].size;
sector_t from = state->parts[p].from;
disk_part_iter_exit(&piter);
invalidate_partition(disk, 0);
+ blk_free_devt(disk_to_dev(disk)->devt);
set_capacity(disk, 0);
disk->flags &= ~GENHD_FL_UP;
unlink_gendisk(disk);