aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristen Carlson Accardi <kristen.c.accardi@intel.com>2007-05-23 16:57:38 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-23 23:14:12 -0400
commit8ce7ad7b2d11fae2c3d285a6a0caea9322c0b8fc (patch)
tree87d7423635821dae9f26d14c62f3314ec7bb3b17
parent86ce18d7b7925bfd6b64c061828ca2a857ee83b8 (diff)
genhd: send async notification on media change
Send an uevent to user space to indicate that a media change event has occurred. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--block/genhd.c23
-rw-r--r--include/linux/genhd.h4
2 files changed, 26 insertions, 1 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 7efa8bb25da..863a8c0623e 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
699static 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
713void genhd_media_change_notify(struct gendisk *disk)
714{
715 get_device(disk->driverfs_dev);
716 schedule_work(&disk->async_notify);
717}
718EXPORT_SYMBOL_GPL(genhd_media_change_notify);
719
699struct gendisk *alloc_disk(int minors) 720struct 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 3fcfed2168a..9756fc102a8 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
70struct partition { 71struct 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);
420extern struct gendisk *alloc_disk(int minors); 422extern struct gendisk *alloc_disk(int minors);
421extern struct kobject *get_disk(struct gendisk *disk); 423extern struct kobject *get_disk(struct gendisk *disk);
422extern void put_disk(struct gendisk *disk); 424extern void put_disk(struct gendisk *disk);
423 425extern void genhd_media_change_notify(struct gendisk *disk);
424extern void blk_register_region(dev_t dev, unsigned long range, 426extern 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 *),