vserver 2.0 rc7
[linux-2.6.git] / drivers / block / genhd.c
index 80da358..8bbe01d 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/kobj_map.h>
+#include <linux/buffer_head.h>
 
 #define MAX_PROBE_HASH 255     /* random */
 
@@ -302,7 +303,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
 
 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;
@@ -430,43 +431,58 @@ static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
 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;
 }
 
@@ -661,7 +677,8 @@ int invalidate_partition(struct gendisk *disk, int index)
        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;