diff options
author | Andi Kleen <ak@linux.intel.com> | 2010-09-08 10:54:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:16:43 -0400 |
commit | e52eec13cd6b7f30ab19081b387813e03e592ae5 (patch) | |
tree | 7b327e0b9283c578fb10922edcf6e10b3b8fd943 /drivers/base/core.c | |
parent | 39aba963d937edb20db7d9d93e6dda5d2adfdcdd (diff) |
SYSFS: Allow boot time switching between deprecated and modern sysfs layout
I have some systems which need legacy sysfs due to old tools that are
making assumptions that a directory can never be a symlink to another
directory, and it's a big hazzle to compile separate kernels for them.
This patch turns CONFIG_SYSFS_DEPRECATED into a run time option
that can be switched on/off the kernel command line. This way
the same binary can be used in both cases with just a option
on the command line.
The old CONFIG_SYSFS_DEPRECATED_V2 option is still there to set
the default. I kept the weird name to not break existing
config files.
Also the compat code can be still completely disabled by undefining
CONFIG_SYSFS_DEPRECATED_SWITCH -- just the optimizer takes
care of this now instead of lots of ifdefs. This makes the code
look nicer.
v2: This is an updated version on top of Kay's patch to only
handle the block devices. I tested it on my old systems
and that seems to work.
Cc: axboe@kernel.dk
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 6cf9069f3150..f7f906f0a2f2 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -26,6 +26,19 @@ | |||
26 | #include "base.h" | 26 | #include "base.h" |
27 | #include "power/power.h" | 27 | #include "power/power.h" |
28 | 28 | ||
29 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
30 | #ifdef CONFIG_SYSFS_DEPRECATED_V2 | ||
31 | long sysfs_deprecated = 1; | ||
32 | #else | ||
33 | long sysfs_deprecated = 0; | ||
34 | #endif | ||
35 | static __init int sysfs_deprecated_setup(char *arg) | ||
36 | { | ||
37 | return strict_strtol(arg, 10, &sysfs_deprecated); | ||
38 | } | ||
39 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | ||
40 | #endif | ||
41 | |||
29 | int (*platform_notify)(struct device *dev) = NULL; | 42 | int (*platform_notify)(struct device *dev) = NULL; |
30 | int (*platform_notify_remove)(struct device *dev) = NULL; | 43 | int (*platform_notify_remove)(struct device *dev) = NULL; |
31 | static struct kobject *dev_kobj; | 44 | static struct kobject *dev_kobj; |
@@ -617,14 +630,13 @@ static struct kobject *get_device_parent(struct device *dev, | |||
617 | struct kobject *parent_kobj; | 630 | struct kobject *parent_kobj; |
618 | struct kobject *k; | 631 | struct kobject *k; |
619 | 632 | ||
620 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
621 | /* block disks show up in /sys/block */ | 633 | /* block disks show up in /sys/block */ |
622 | if (dev->class == &block_class) { | 634 | if (sysfs_deprecated && dev->class == &block_class) { |
623 | if (parent && parent->class == &block_class) | 635 | if (parent && parent->class == &block_class) |
624 | return &parent->kobj; | 636 | return &parent->kobj; |
625 | return &block_class.p->class_subsys.kobj; | 637 | return &block_class.p->class_subsys.kobj; |
626 | } | 638 | } |
627 | #endif | 639 | |
628 | /* | 640 | /* |
629 | * If we have no parent, we live in "virtual". | 641 | * If we have no parent, we live in "virtual". |
630 | * Class-devices with a non class-device as parent, live | 642 | * Class-devices with a non class-device as parent, live |
@@ -707,11 +719,9 @@ static int device_add_class_symlinks(struct device *dev) | |||
707 | goto out_subsys; | 719 | goto out_subsys; |
708 | } | 720 | } |
709 | 721 | ||
710 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
711 | /* /sys/block has directories and does not need symlinks */ | 722 | /* /sys/block has directories and does not need symlinks */ |
712 | if (dev->class == &block_class) | 723 | if (sysfs_deprecated && dev->class == &block_class) |
713 | return 0; | 724 | return 0; |
714 | #endif | ||
715 | 725 | ||
716 | /* link in the class directory pointing to the device */ | 726 | /* link in the class directory pointing to the device */ |
717 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, | 727 | error = sysfs_create_link(&dev->class->p->class_subsys.kobj, |
@@ -738,10 +748,8 @@ static void device_remove_class_symlinks(struct device *dev) | |||
738 | if (dev->parent && device_is_not_partition(dev)) | 748 | if (dev->parent && device_is_not_partition(dev)) |
739 | sysfs_remove_link(&dev->kobj, "device"); | 749 | sysfs_remove_link(&dev->kobj, "device"); |
740 | sysfs_remove_link(&dev->kobj, "subsystem"); | 750 | sysfs_remove_link(&dev->kobj, "subsystem"); |
741 | #ifdef CONFIG_SYSFS_DEPRECATED | 751 | if (sysfs_deprecated && dev->class == &block_class) |
742 | if (dev->class == &block_class) | ||
743 | return; | 752 | return; |
744 | #endif | ||
745 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); | 753 | sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); |
746 | } | 754 | } |
747 | 755 | ||