#include <linux/slab.h>
#include <linux/kmod.h>
#include <linux/kobj_map.h>
+#include <linux/buffer_head.h>
#define MAX_PROBE_HASH 255 /* random */
static int __init genhd_device_init(void)
{
- bdev_map = kobj_map_init(base_probe, &block_subsys);
+ bdev_map = kobj_map_init(base_probe, &block_subsys_sem);
blk_dev_init();
subsystem_register(&block_subsys);
return 0;
static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
- struct device *dev = NULL;
struct kobj_type *ktype = get_ktype(kobj);
+ struct device *physdev;
+ struct gendisk *disk;
+ struct hd_struct *part;
int length = 0;
int i = 0;
- /* get physical device backing disk or partition */
if (ktype == &ktype_block) {
- struct gendisk *disk = container_of(kobj, struct gendisk, kobj);
- dev = disk->driverfs_dev;
+ disk = container_of(kobj, struct gendisk, kobj);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "MINOR=%u", disk->first_minor);
} else if (ktype == &ktype_part) {
- struct gendisk *disk = container_of(kobj->parent, struct gendisk, kobj);
- dev = disk->driverfs_dev;
- }
+ disk = container_of(kobj->parent, struct gendisk, kobj);
+ part = container_of(kobj, struct hd_struct, kobj);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+ &length, "MINOR=%u",
+ disk->first_minor + part->partno);
+ } else
+ return 0;
- if (dev) {
- /* add physical device, backing this device */
- char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
+ add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length,
+ "MAJOR=%u", disk->major);
+
+ /* add physical device, backing this device */
+ physdev = disk->driverfs_dev;
+ if (physdev) {
+ char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path);
kfree(path);
- /* add bus name of physical device */
- if (dev->bus)
+ if (physdev->bus)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
- "PHYSDEVBUS=%s", dev->bus->name);
+ "PHYSDEVBUS=%s",
+ physdev->bus->name);
- /* add driver name of physical device */
- if (dev->driver)
+ if (physdev->driver)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
- "PHYSDEVDRIVER=%s", dev->driver->name);
-
- envp[i] = NULL;
+ "PHYSDEVDRIVER=%s",
+ physdev->driver->name);
}
+ /* terminate, set to next free slot, shrink available space */
+ envp[i] = NULL;
+ envp = &envp[i];
+ num_envp -= i;
+ buffer = &buffer[length];
+ buffer_size -= length;
+
return 0;
}
int res = 0;
struct block_device *bdev = bdget_disk(disk, index);
if (bdev) {
- res = __invalidate_device(bdev, 1);
+ fsync_bdev(bdev);
+ res = __invalidate_device(bdev);
bdput(bdev);
}
return res;