diff options
Diffstat (limited to 'fs/partitions/check.c')
-rw-r--r-- | fs/partitions/check.c | 106 |
1 files changed, 16 insertions, 90 deletions
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 0a8b0ad0c7e2..9c21119512b9 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -237,6 +237,13 @@ ssize_t part_size_show(struct device *dev, | |||
237 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); | 237 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); |
238 | } | 238 | } |
239 | 239 | ||
240 | ssize_t part_ro_show(struct device *dev, | ||
241 | struct device_attribute *attr, char *buf) | ||
242 | { | ||
243 | struct hd_struct *p = dev_to_part(dev); | ||
244 | return sprintf(buf, "%d\n", p->policy ? 1 : 0); | ||
245 | } | ||
246 | |||
240 | ssize_t part_alignment_offset_show(struct device *dev, | 247 | ssize_t part_alignment_offset_show(struct device *dev, |
241 | struct device_attribute *attr, char *buf) | 248 | struct device_attribute *attr, char *buf) |
242 | { | 249 | { |
@@ -312,6 +319,7 @@ ssize_t part_fail_store(struct device *dev, | |||
312 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); | 319 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); |
313 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | 320 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); |
314 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 321 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
322 | static DEVICE_ATTR(ro, S_IRUGO, part_ro_show, NULL); | ||
315 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 323 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
316 | static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, | 324 | static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, |
317 | NULL); | 325 | NULL); |
@@ -326,6 +334,7 @@ static struct attribute *part_attrs[] = { | |||
326 | &dev_attr_partition.attr, | 334 | &dev_attr_partition.attr, |
327 | &dev_attr_start.attr, | 335 | &dev_attr_start.attr, |
328 | &dev_attr_size.attr, | 336 | &dev_attr_size.attr, |
337 | &dev_attr_ro.attr, | ||
329 | &dev_attr_alignment_offset.attr, | 338 | &dev_attr_alignment_offset.attr, |
330 | &dev_attr_discard_alignment.attr, | 339 | &dev_attr_discard_alignment.attr, |
331 | &dev_attr_stat.attr, | 340 | &dev_attr_stat.attr, |
@@ -372,6 +381,11 @@ static void delete_partition_rcu_cb(struct rcu_head *head) | |||
372 | put_device(part_to_dev(part)); | 381 | put_device(part_to_dev(part)); |
373 | } | 382 | } |
374 | 383 | ||
384 | void __delete_partition(struct hd_struct *part) | ||
385 | { | ||
386 | call_rcu(&part->rcu_head, delete_partition_rcu_cb); | ||
387 | } | ||
388 | |||
375 | void delete_partition(struct gendisk *disk, int partno) | 389 | void delete_partition(struct gendisk *disk, int partno) |
376 | { | 390 | { |
377 | struct disk_part_tbl *ptbl = disk->part_tbl; | 391 | struct disk_part_tbl *ptbl = disk->part_tbl; |
@@ -390,7 +404,7 @@ void delete_partition(struct gendisk *disk, int partno) | |||
390 | kobject_put(part->holder_dir); | 404 | kobject_put(part->holder_dir); |
391 | device_del(part_to_dev(part)); | 405 | device_del(part_to_dev(part)); |
392 | 406 | ||
393 | call_rcu(&part->rcu_head, delete_partition_rcu_cb); | 407 | hd_struct_put(part); |
394 | } | 408 | } |
395 | 409 | ||
396 | static ssize_t whole_disk_show(struct device *dev, | 410 | static ssize_t whole_disk_show(struct device *dev, |
@@ -489,6 +503,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
489 | if (!dev_get_uevent_suppress(ddev)) | 503 | if (!dev_get_uevent_suppress(ddev)) |
490 | kobject_uevent(&pdev->kobj, KOBJ_ADD); | 504 | kobject_uevent(&pdev->kobj, KOBJ_ADD); |
491 | 505 | ||
506 | hd_ref_init(p); | ||
492 | return p; | 507 | return p; |
493 | 508 | ||
494 | out_free_info: | 509 | out_free_info: |
@@ -507,65 +522,6 @@ out_put: | |||
507 | return ERR_PTR(err); | 522 | return ERR_PTR(err); |
508 | } | 523 | } |
509 | 524 | ||
510 | /* Not exported, helper to add_disk(). */ | ||
511 | void register_disk(struct gendisk *disk) | ||
512 | { | ||
513 | struct device *ddev = disk_to_dev(disk); | ||
514 | struct block_device *bdev; | ||
515 | struct disk_part_iter piter; | ||
516 | struct hd_struct *part; | ||
517 | int err; | ||
518 | |||
519 | ddev->parent = disk->driverfs_dev; | ||
520 | |||
521 | dev_set_name(ddev, disk->disk_name); | ||
522 | |||
523 | /* delay uevents, until we scanned partition table */ | ||
524 | dev_set_uevent_suppress(ddev, 1); | ||
525 | |||
526 | if (device_add(ddev)) | ||
527 | return; | ||
528 | if (!sysfs_deprecated) { | ||
529 | err = sysfs_create_link(block_depr, &ddev->kobj, | ||
530 | kobject_name(&ddev->kobj)); | ||
531 | if (err) { | ||
532 | device_del(ddev); | ||
533 | return; | ||
534 | } | ||
535 | } | ||
536 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); | ||
537 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); | ||
538 | |||
539 | /* No minors to use for partitions */ | ||
540 | if (!disk_partitionable(disk)) | ||
541 | goto exit; | ||
542 | |||
543 | /* No such device (e.g., media were just removed) */ | ||
544 | if (!get_capacity(disk)) | ||
545 | goto exit; | ||
546 | |||
547 | bdev = bdget_disk(disk, 0); | ||
548 | if (!bdev) | ||
549 | goto exit; | ||
550 | |||
551 | bdev->bd_invalidated = 1; | ||
552 | err = blkdev_get(bdev, FMODE_READ); | ||
553 | if (err < 0) | ||
554 | goto exit; | ||
555 | blkdev_put(bdev, FMODE_READ); | ||
556 | |||
557 | exit: | ||
558 | /* announce disk after possible partitions are created */ | ||
559 | dev_set_uevent_suppress(ddev, 0); | ||
560 | kobject_uevent(&ddev->kobj, KOBJ_ADD); | ||
561 | |||
562 | /* announce possible partitions */ | ||
563 | disk_part_iter_init(&piter, disk, 0); | ||
564 | while ((part = disk_part_iter_next(&piter))) | ||
565 | kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); | ||
566 | disk_part_iter_exit(&piter); | ||
567 | } | ||
568 | |||
569 | static bool disk_unlock_native_capacity(struct gendisk *disk) | 525 | static bool disk_unlock_native_capacity(struct gendisk *disk) |
570 | { | 526 | { |
571 | const struct block_device_operations *bdops = disk->fops; | 527 | const struct block_device_operations *bdops = disk->fops; |
@@ -728,33 +684,3 @@ fail: | |||
728 | } | 684 | } |
729 | 685 | ||
730 | EXPORT_SYMBOL(read_dev_sector); | 686 | EXPORT_SYMBOL(read_dev_sector); |
731 | |||
732 | void del_gendisk(struct gendisk *disk) | ||
733 | { | ||
734 | struct disk_part_iter piter; | ||
735 | struct hd_struct *part; | ||
736 | |||
737 | /* invalidate stuff */ | ||
738 | disk_part_iter_init(&piter, disk, | ||
739 | DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); | ||
740 | while ((part = disk_part_iter_next(&piter))) { | ||
741 | invalidate_partition(disk, part->partno); | ||
742 | delete_partition(disk, part->partno); | ||
743 | } | ||
744 | disk_part_iter_exit(&piter); | ||
745 | |||
746 | invalidate_partition(disk, 0); | ||
747 | blk_free_devt(disk_to_dev(disk)->devt); | ||
748 | set_capacity(disk, 0); | ||
749 | disk->flags &= ~GENHD_FL_UP; | ||
750 | unlink_gendisk(disk); | ||
751 | part_stat_set_all(&disk->part0, 0); | ||
752 | disk->part0.stamp = 0; | ||
753 | |||
754 | kobject_put(disk->part0.holder_dir); | ||
755 | kobject_put(disk->slave_dir); | ||
756 | disk->driverfs_dev = NULL; | ||
757 | if (!sysfs_deprecated) | ||
758 | sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | ||
759 | device_del(disk_to_dev(disk)); | ||
760 | } | ||