|
@@ -502,6 +502,64 @@ static int exact_lock(dev_t devt, void *data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void register_disk(struct gendisk *disk)
|
|
|
+{
|
|
|
+ struct device *ddev = disk_to_dev(disk);
|
|
|
+ struct block_device *bdev;
|
|
|
+ struct disk_part_iter piter;
|
|
|
+ struct hd_struct *part;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ ddev->parent = disk->driverfs_dev;
|
|
|
+
|
|
|
+ dev_set_name(ddev, disk->disk_name);
|
|
|
+
|
|
|
+ /* delay uevents, until we scanned partition table */
|
|
|
+ dev_set_uevent_suppress(ddev, 1);
|
|
|
+
|
|
|
+ if (device_add(ddev))
|
|
|
+ return;
|
|
|
+ if (!sysfs_deprecated) {
|
|
|
+ err = sysfs_create_link(block_depr, &ddev->kobj,
|
|
|
+ kobject_name(&ddev->kobj));
|
|
|
+ if (err) {
|
|
|
+ device_del(ddev);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
|
|
|
+ disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
|
|
|
+
|
|
|
+ /* No minors to use for partitions */
|
|
|
+ if (!disk_partitionable(disk))
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ /* No such device (e.g., media were just removed) */
|
|
|
+ if (!get_capacity(disk))
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ bdev = bdget_disk(disk, 0);
|
|
|
+ if (!bdev)
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ bdev->bd_invalidated = 1;
|
|
|
+ err = blkdev_get(bdev, FMODE_READ, NULL);
|
|
|
+ if (err < 0)
|
|
|
+ goto exit;
|
|
|
+ blkdev_put(bdev, FMODE_READ);
|
|
|
+
|
|
|
+exit:
|
|
|
+ /* announce disk after possible partitions are created */
|
|
|
+ dev_set_uevent_suppress(ddev, 0);
|
|
|
+ kobject_uevent(&ddev->kobj, KOBJ_ADD);
|
|
|
+
|
|
|
+ /* announce possible partitions */
|
|
|
+ disk_part_iter_init(&piter, disk, 0);
|
|
|
+ while ((part = disk_part_iter_next(&piter)))
|
|
|
+ kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
|
|
|
+ disk_part_iter_exit(&piter);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* add_disk - add partitioning information to kernel list
|
|
|
* @disk: per-device partitioning information
|
|
@@ -552,17 +610,43 @@ void add_disk(struct gendisk *disk)
|
|
|
"bdi");
|
|
|
WARN_ON(retval);
|
|
|
}
|
|
|
-
|
|
|
EXPORT_SYMBOL(add_disk);
|
|
|
-EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */
|
|
|
|
|
|
-void unlink_gendisk(struct gendisk *disk)
|
|
|
+void del_gendisk(struct gendisk *disk)
|
|
|
{
|
|
|
+ struct disk_part_iter piter;
|
|
|
+ struct hd_struct *part;
|
|
|
+
|
|
|
+ /* invalidate stuff */
|
|
|
+ disk_part_iter_init(&piter, disk,
|
|
|
+ DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE);
|
|
|
+ while ((part = disk_part_iter_next(&piter))) {
|
|
|
+ invalidate_partition(disk, part->partno);
|
|
|
+ delete_partition(disk, part->partno);
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+
|
|
|
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
|
|
|
bdi_unregister(&disk->queue->backing_dev_info);
|
|
|
blk_unregister_queue(disk);
|
|
|
blk_unregister_region(disk_devt(disk), disk->minors);
|
|
|
+
|
|
|
+ part_stat_set_all(&disk->part0, 0);
|
|
|
+ disk->part0.stamp = 0;
|
|
|
+
|
|
|
+ kobject_put(disk->part0.holder_dir);
|
|
|
+ kobject_put(disk->slave_dir);
|
|
|
+ disk->driverfs_dev = NULL;
|
|
|
+ if (!sysfs_deprecated)
|
|
|
+ sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
|
|
|
+ device_del(disk_to_dev(disk));
|
|
|
}
|
|
|
+EXPORT_SYMBOL(del_gendisk);
|
|
|
|
|
|
/**
|
|
|
* get_gendisk - get partitioning information for a given device
|