#include <linux/buffer_head.h>
#include <linux/mutex.h>
-struct kset block_subsys;
+struct kset *block_kset;
+static struct kset_uevent_ops block_uevent_ops;
static DEFINE_MUTEX(block_subsys_lock);
/*
EXPORT_SYMBOL(register_blkdev);
-/* todo: make void - error printk here */
-int unregister_blkdev(unsigned int major, const char *name)
+void unregister_blkdev(unsigned int major, const char *name)
{
struct blk_major_name **n;
struct blk_major_name *p = NULL;
int index = major_to_index(major);
- int ret = 0;
mutex_lock(&block_subsys_lock);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
- if (!*n || strcmp((*n)->name, name))
- ret = -EINVAL;
- else {
+ if (!*n || strcmp((*n)->name, name)) {
+ WARN_ON(1);
+ } else {
p = *n;
*n = p->next;
}
mutex_unlock(&block_subsys_lock);
kfree(p);
-
- return ret;
}
EXPORT_SYMBOL(unregister_blkdev);
mutex_lock(&block_subsys_lock);
/* For each block device... */
- list_for_each_entry(sgp, &block_subsys.list, kobj.entry) {
+ list_for_each_entry(sgp, &block_kset->list, kobj.entry) {
char buf[BDEVNAME_SIZE];
/*
* Don't show empty devices or things that have been surpressed
loff_t l = *pos;
mutex_lock(&block_subsys_lock);
- list_for_each(p, &block_subsys.list)
+ list_for_each(p, &block_kset->list)
if (!l--)
return list_entry(p, struct gendisk, kobj.entry);
return NULL;
{
struct list_head *p = ((struct gendisk *)v)->kobj.entry.next;
++*pos;
- return p==&block_subsys.list ? NULL :
+ return p==&block_kset->list ? NULL :
list_entry(p, struct gendisk, kobj.entry);
}
int n;
char buf[BDEVNAME_SIZE];
- if (&sgp->kobj.entry == block_subsys.list.next)
+ if (&sgp->kobj.entry == block_kset->list.next)
seq_puts(part, "major minor #blocks name\n\n");
/* Don't show non-partitionable removeable devices or empty devices */
static int __init genhd_device_init(void)
{
- int err;
-
bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
blk_dev_init();
- err = subsystem_register(&block_subsys);
- if (err < 0)
- printk(KERN_WARNING "%s: subsystem_register error: %d\n",
- __FUNCTION__, err);
- return err;
+ block_kset = kset_create_and_add("block", &block_uevent_ops, NULL);
+ if (!block_kset) {
+ printk(KERN_WARNING "%s: kset_create error\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+ return 0;
}
subsys_initcall(genhd_device_init);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
-static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int block_uevent(struct kset *kset, struct kobject *kobj,
+ struct kobj_uevent_env *env)
{
struct kobj_type *ktype = get_ktype(kobj);
struct device *physdev;
struct gendisk *disk;
struct hd_struct *part;
- int length = 0;
- int i = 0;
if (ktype == &ktype_block) {
disk = container_of(kobj, struct gendisk, kobj);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "MINOR=%u", disk->first_minor);
+ add_uevent_var(env, "MINOR=%u", disk->first_minor);
} else if (ktype == &ktype_part) {
disk = container_of(kobj->parent, struct gendisk, kobj);
part = container_of(kobj, struct hd_struct, kobj);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "MINOR=%u",
+ add_uevent_var(env, "MINOR=%u",
disk->first_minor + part->partno);
} else
return 0;
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "MAJOR=%u", disk->major);
+ add_uevent_var(env, "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_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "PHYSDEVPATH=%s", path);
+ add_uevent_var(env, "PHYSDEVPATH=%s", path);
kfree(path);
if (physdev->bus)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVBUS=%s",
- physdev->bus->name);
+ add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name);
if (physdev->driver)
- add_uevent_var(envp, num_envp, &i,
- buffer, buffer_size, &length,
- "PHYSDEVDRIVER=%s",
- physdev->driver->name);
+ add_uevent_var(env, 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;
}
.uevent = block_uevent,
};
-decl_subsys(block, &ktype_block, &block_uevent_ops);
-
/*
* aggregate disk stat collector. Uses the same stats that the sysfs
* entries do, above, but makes them available through one seq_file.
struct list_head *p;
mutex_lock(&block_subsys_lock);
- list_for_each(p, &block_subsys.list)
+ list_for_each(p, &block_kset->list)
if (!k--)
return list_entry(p, struct gendisk, kobj.entry);
return NULL;
{
struct list_head *p = ((struct gendisk *)v)->kobj.entry.next;
++*pos;
- return p==&block_subsys.list ? NULL :
+ return p==&block_kset->list ? NULL :
list_entry(p, struct gendisk, kobj.entry);
}
int n = 0;
/*
- if (&sgp->kobj.entry == block_subsys.kset.list.next)
+ if (&sgp->kobj.entry == block_kset->list.next)
seq_puts(s, "major minor name"
" rio rmerge rsect ruse wio wmerge "
"wsect wuse running use aveq"
{
struct gendisk *disk;
- disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
+ disk = kmalloc_node(sizeof(struct gendisk),
+ GFP_KERNEL | __GFP_ZERO, node_id);
if (disk) {
- memset(disk, 0, sizeof(struct gendisk));
if (!init_disk_stats(disk)) {
kfree(disk);
return NULL;
}
if (minors > 1) {
int size = (minors - 1) * sizeof(struct hd_struct *);
- disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
+ disk->part = kmalloc_node(size,
+ GFP_KERNEL | __GFP_ZERO, node_id);
if (!disk->part) {
+ free_disk_stats(disk);
kfree(disk);
return NULL;
}
- memset(disk->part, 0, size);
}
disk->minors = minors;
- kobj_set_kset_s(disk,block_subsys);
+ disk->kobj.kset = block_kset;
+ disk->kobj.ktype = &ktype_block;
kobject_init(&disk->kobj);
rand_initialize_disk(disk);
INIT_WORK(&disk->async_notify,