diff options
| -rw-r--r-- | block/genhd.c | 23 | ||||
| -rw-r--r-- | include/linux/genhd.h | 4 |
2 files changed, 26 insertions, 1 deletions
diff --git a/block/genhd.c b/block/genhd.c index 7efa8bb25da9..863a8c0623ed 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -696,6 +696,27 @@ struct seq_operations diskstats_op = { | |||
| 696 | .show = diskstats_show | 696 | .show = diskstats_show |
| 697 | }; | 697 | }; |
| 698 | 698 | ||
| 699 | static void media_change_notify_thread(struct work_struct *work) | ||
| 700 | { | ||
| 701 | struct gendisk *gd = container_of(work, struct gendisk, async_notify); | ||
| 702 | char event[] = "MEDIA_CHANGE=1"; | ||
| 703 | char *envp[] = { event, NULL }; | ||
| 704 | |||
| 705 | /* | ||
| 706 | * set enviroment vars to indicate which event this is for | ||
| 707 | * so that user space will know to go check the media status. | ||
| 708 | */ | ||
| 709 | kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); | ||
| 710 | put_device(gd->driverfs_dev); | ||
| 711 | } | ||
| 712 | |||
| 713 | void genhd_media_change_notify(struct gendisk *disk) | ||
| 714 | { | ||
| 715 | get_device(disk->driverfs_dev); | ||
| 716 | schedule_work(&disk->async_notify); | ||
| 717 | } | ||
| 718 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); | ||
| 719 | |||
| 699 | struct gendisk *alloc_disk(int minors) | 720 | struct gendisk *alloc_disk(int minors) |
| 700 | { | 721 | { |
| 701 | return alloc_disk_node(minors, -1); | 722 | return alloc_disk_node(minors, -1); |
| @@ -725,6 +746,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id) | |||
| 725 | kobj_set_kset_s(disk,block_subsys); | 746 | kobj_set_kset_s(disk,block_subsys); |
| 726 | kobject_init(&disk->kobj); | 747 | kobject_init(&disk->kobj); |
| 727 | rand_initialize_disk(disk); | 748 | rand_initialize_disk(disk); |
| 749 | INIT_WORK(&disk->async_notify, | ||
| 750 | media_change_notify_thread); | ||
| 728 | } | 751 | } |
| 729 | return disk; | 752 | return disk; |
| 730 | } | 753 | } |
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3fcfed2168a7..9756fc102a83 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h | |||
| @@ -66,6 +66,7 @@ struct partition { | |||
| 66 | #include <linux/smp.h> | 66 | #include <linux/smp.h> |
| 67 | #include <linux/string.h> | 67 | #include <linux/string.h> |
| 68 | #include <linux/fs.h> | 68 | #include <linux/fs.h> |
| 69 | #include <linux/workqueue.h> | ||
| 69 | 70 | ||
| 70 | struct partition { | 71 | struct partition { |
| 71 | unsigned char boot_ind; /* 0x80 - active */ | 72 | unsigned char boot_ind; /* 0x80 - active */ |
| @@ -139,6 +140,7 @@ struct gendisk { | |||
| 139 | #else | 140 | #else |
| 140 | struct disk_stats dkstats; | 141 | struct disk_stats dkstats; |
| 141 | #endif | 142 | #endif |
| 143 | struct work_struct async_notify; | ||
| 142 | }; | 144 | }; |
| 143 | 145 | ||
| 144 | /* Structure for sysfs attributes on block devices */ | 146 | /* Structure for sysfs attributes on block devices */ |
| @@ -420,7 +422,7 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id); | |||
| 420 | extern struct gendisk *alloc_disk(int minors); | 422 | extern struct gendisk *alloc_disk(int minors); |
| 421 | extern struct kobject *get_disk(struct gendisk *disk); | 423 | extern struct kobject *get_disk(struct gendisk *disk); |
| 422 | extern void put_disk(struct gendisk *disk); | 424 | extern void put_disk(struct gendisk *disk); |
| 423 | 425 | extern void genhd_media_change_notify(struct gendisk *disk); | |
| 424 | extern void blk_register_region(dev_t dev, unsigned long range, | 426 | extern void blk_register_region(dev_t dev, unsigned long range, |
| 425 | struct module *module, | 427 | struct module *module, |
| 426 | struct kobject *(*probe)(dev_t, int *, void *), | 428 | struct kobject *(*probe)(dev_t, int *, void *), |
