On Mon, 2011-07-25 at 16:22 +0200, Kay Sievers wrote: > On Mon, Jul 25, 2011 at 14:54, Zdenek Kabelac <zkabelac@xxxxxxxxxx> wrote: > > Dne 25.7.2011 14:17, Kay Sievers napsal(a): > > >>>> Then have 'dm_blk_dops' add '.uevent' and let the core call into the dm > >>>> code to the needed properties to the 'remove' event, instead of sending > >>>> its own, and see the duplication. > >>> > >>> Sounds like complex solution > >> > >> I don't think so, It's clean, ~30 lines long, and technically correct, I expect. > > In include/linux/blkdev.h add: > int (*uevent) (struct gendisk *, struct kobj_uevent_env *env); > to > struct block_device_operations > > In block/genhd.c add: > .uevent = block_uevent; > to > struct class block_class > and have the block_uevent() callback check for an existing uevent() in > the block_device_operations, call it when it's specified. > > In drivers/md/dm.c add: > .dm_uevent; > to > struct block_device_operations dm_blk_dops > and add all the needed variables there, instead of sending out a faked > device 'remove' event. Here is the code to illustrate, and fix the issue of needing to send any 'remove' for a device from a driver. Thanks, Kay diff --git a/block/genhd.c b/block/genhd.c index 6024b82..c2e9714 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1097,8 +1097,21 @@ static void disk_release(struct device *dev) free_part_info(&disk->part0); kfree(disk); } + +static int block_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct gendisk *disk = dev_to_disk(dev); + + if (!disk->fops) + return 0; + if (disk->fops->uevent) + return disk->fops->uevent(disk, env); + return 0; +} + struct class block_class = { .name = "block", + .dev_uevent = block_uevent, }; static char *block_devnode(struct device *dev, mode_t *mode) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0cf68b4..22e486e 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2682,11 +2682,17 @@ void dm_free_md_mempools(struct dm_md_mempools *pools) kfree(pools); } +static int dm_uevent(struct gendisk *disk, struct kobj_uevent_env *env) +{ + return add_uevent_var(env, "COOKIE_MONSTER=1"); +} + static const struct block_device_operations dm_blk_dops = { .open = dm_blk_open, .release = dm_blk_close, .ioctl = dm_blk_ioctl, .getgeo = dm_blk_getgeo, + .uevent = dm_uevent, .owner = THIS_MODULE }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1a23722..6dbd69e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1300,6 +1300,7 @@ struct block_device_operations { void **, unsigned long *); unsigned int (*check_events) (struct gendisk *disk, unsigned int clearing); + int (*uevent) (struct gendisk *, struct kobj_uevent_env *env); /* ->media_changed() is DEPRECATED, use ->check_events() instead */ int (*media_changed) (struct gendisk *); void (*unlock_native_capacity) (struct gendisk *); -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel