diff --git a/block/genhd.c b/block/genhd.c index 7efa8bb25da931af28e98d4040dc2f5ca2d26535..863a8c0623ed824e27d85f32a52cf10ea39d1c02 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -696,6 +696,27 @@ struct seq_operations diskstats_op = { .show = diskstats_show }; +static void media_change_notify_thread(struct work_struct *work) +{ + struct gendisk *gd = container_of(work, struct gendisk, async_notify); + char event[] = "MEDIA_CHANGE=1"; + char *envp[] = { event, NULL }; + + /* + * set enviroment vars to indicate which event this is for + * so that user space will know to go check the media status. + */ + kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); + put_device(gd->driverfs_dev); +} + +void genhd_media_change_notify(struct gendisk *disk) +{ + get_device(disk->driverfs_dev); + schedule_work(&disk->async_notify); +} +EXPORT_SYMBOL_GPL(genhd_media_change_notify); + struct gendisk *alloc_disk(int minors) { return alloc_disk_node(minors, -1); @@ -725,6 +746,8 @@ struct gendisk *alloc_disk_node(int minors, int node_id) kobj_set_kset_s(disk,block_subsys); kobject_init(&disk->kobj); rand_initialize_disk(disk); + INIT_WORK(&disk->async_notify, + media_change_notify_thread); } return disk; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3fcfed2168a770bf2a96aa11c528c998687e2f98..9756fc102a83f284a1040386bd076d6acca81cff 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -66,6 +66,7 @@ struct partition { #include #include #include +#include struct partition { unsigned char boot_ind; /* 0x80 - active */ @@ -139,6 +140,7 @@ struct gendisk { #else struct disk_stats dkstats; #endif + struct work_struct async_notify; }; /* Structure for sysfs attributes on block devices */ @@ -420,7 +422,7 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id); extern struct gendisk *alloc_disk(int minors); extern struct kobject *get_disk(struct gendisk *disk); extern void put_disk(struct gendisk *disk); - +extern void genhd_media_change_notify(struct gendisk *disk); extern void blk_register_region(dev_t dev, unsigned long range, struct module *module, struct kobject *(*probe)(dev_t, int *, void *),