diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-08-14 09:15:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:51:01 -0400 |
commit | 7eff2e7a8b65c25920207324e56611150eb1cd9a (patch) | |
tree | 02a0eeba9d25d996233e30c18f258dfae0ae2139 /block | |
parent | 8380770c842faef3001e44662953d64ad9a93663 (diff) |
Driver core: change add_uevent_var to use a struct
This changes the uevent buffer functions to use a struct instead of a
long list of parameters. It does no longer require the caller to do the
proper buffer termination and size accounting, which is currently wrong
in some places. It fixes a known bug where parts of the uevent
environment are overwritten because of wrong index calculations.
Many thanks to Mathieu Desnoyers for finding bugs and improving the
error handling.
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'block')
-rw-r--r-- | block/genhd.c | 35 |
1 files changed, 8 insertions, 27 deletions
diff --git a/block/genhd.c b/block/genhd.c index 3af1e7a378d4..e609996f2e76 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -540,61 +540,42 @@ static int block_uevent_filter(struct kset *kset, struct kobject *kobj) | |||
540 | return ((ktype == &ktype_block) || (ktype == &ktype_part)); | 540 | return ((ktype == &ktype_block) || (ktype == &ktype_part)); |
541 | } | 541 | } |
542 | 542 | ||
543 | static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp, | 543 | static int block_uevent(struct kset *kset, struct kobject *kobj, |
544 | int num_envp, char *buffer, int buffer_size) | 544 | struct kobj_uevent_env *env) |
545 | { | 545 | { |
546 | struct kobj_type *ktype = get_ktype(kobj); | 546 | struct kobj_type *ktype = get_ktype(kobj); |
547 | struct device *physdev; | 547 | struct device *physdev; |
548 | struct gendisk *disk; | 548 | struct gendisk *disk; |
549 | struct hd_struct *part; | 549 | struct hd_struct *part; |
550 | int length = 0; | ||
551 | int i = 0; | ||
552 | 550 | ||
553 | if (ktype == &ktype_block) { | 551 | if (ktype == &ktype_block) { |
554 | disk = container_of(kobj, struct gendisk, kobj); | 552 | disk = container_of(kobj, struct gendisk, kobj); |
555 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 553 | add_uevent_var(env, "MINOR=%u", disk->first_minor); |
556 | &length, "MINOR=%u", disk->first_minor); | ||
557 | } else if (ktype == &ktype_part) { | 554 | } else if (ktype == &ktype_part) { |
558 | disk = container_of(kobj->parent, struct gendisk, kobj); | 555 | disk = container_of(kobj->parent, struct gendisk, kobj); |
559 | part = container_of(kobj, struct hd_struct, kobj); | 556 | part = container_of(kobj, struct hd_struct, kobj); |
560 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 557 | add_uevent_var(env, "MINOR=%u", |
561 | &length, "MINOR=%u", | ||
562 | disk->first_minor + part->partno); | 558 | disk->first_minor + part->partno); |
563 | } else | 559 | } else |
564 | return 0; | 560 | return 0; |
565 | 561 | ||
566 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, | 562 | add_uevent_var(env, "MAJOR=%u", disk->major); |
567 | "MAJOR=%u", disk->major); | ||
568 | 563 | ||
569 | /* add physical device, backing this device */ | 564 | /* add physical device, backing this device */ |
570 | physdev = disk->driverfs_dev; | 565 | physdev = disk->driverfs_dev; |
571 | if (physdev) { | 566 | if (physdev) { |
572 | char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); | 567 | char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); |
573 | 568 | ||
574 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | 569 | add_uevent_var(env, "PHYSDEVPATH=%s", path); |
575 | &length, "PHYSDEVPATH=%s", path); | ||
576 | kfree(path); | 570 | kfree(path); |
577 | 571 | ||
578 | if (physdev->bus) | 572 | if (physdev->bus) |
579 | add_uevent_var(envp, num_envp, &i, | 573 | add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name); |
580 | buffer, buffer_size, &length, | ||
581 | "PHYSDEVBUS=%s", | ||
582 | physdev->bus->name); | ||
583 | 574 | ||
584 | if (physdev->driver) | 575 | if (physdev->driver) |
585 | add_uevent_var(envp, num_envp, &i, | 576 | add_uevent_var(env, physdev->driver->name); |
586 | buffer, buffer_size, &length, | ||
587 | "PHYSDEVDRIVER=%s", | ||
588 | physdev->driver->name); | ||
589 | } | 577 | } |
590 | 578 | ||
591 | /* terminate, set to next free slot, shrink available space */ | ||
592 | envp[i] = NULL; | ||
593 | envp = &envp[i]; | ||
594 | num_envp -= i; | ||
595 | buffer = &buffer[length]; | ||
596 | buffer_size -= length; | ||
597 | |||
598 | return 0; | 579 | return 0; |
599 | } | 580 | } |
600 | 581 | ||