From 7b595756ec1f49e0049a9e01a1298d53a7faaa15 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 14 Jun 2007 03:45:17 +0900 Subject: sysfs: kill unnecessary attribute->owner sysfs is now completely out of driver/module lifetime game. After deletion, a sysfs node doesn't access anything outside sysfs proper, so there's no reason to hold onto the attribute owners. Note that often the wrong modules were accounted for as owners leading to accessing removed modules. This patch kills now unnecessary attribute->owner. Note that with this change, userland holding a sysfs node does not prevent the backing module from being unloaded. For more info regarding lifetime rule cleanup, please read the following message. http://article.gmane.org/gmane.linux.kernel/510293 (tweaked by Greg to not delete the field just yet, to make it easier to merge things properly.) Signed-off-by: Tejun Heo Cc: Cornelia Huck Cc: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/base/class.c') diff --git a/drivers/base/class.c b/drivers/base/class.c index 8c506dbe3913..9cbfde23b9e3 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -605,7 +605,6 @@ int class_device_add(struct class_device *class_dev) goto out3; class_dev->uevent_attr.attr.name = "uevent"; class_dev->uevent_attr.attr.mode = S_IWUSR; - class_dev->uevent_attr.attr.owner = parent_class->owner; class_dev->uevent_attr.store = store_uevent; error = class_device_create_file(class_dev, &class_dev->uevent_attr); if (error) @@ -620,7 +619,6 @@ int class_device_add(struct class_device *class_dev) } attr->attr.name = "dev"; attr->attr.mode = S_IRUGO; - attr->attr.owner = parent_class->owner; attr->show = show_dev; error = class_device_create_file(class_dev, attr); if (error) { -- cgit v1.2.3 From ad6a1e1c66009ba9dcd2f5c90ffa1fb4ce72fce0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 14 Jun 2007 03:45:17 +0900 Subject: driver-core: make devt_attr and uevent_attr static devt_attr and uevent_attr are either allocated dynamically with or embedded in device and class_device as they needed their owner field set to the module implementing the driver. Now that sysfs implements immediate disconnect and owner field removed from struct attribute, there is no reason to do this. Remove these attributes from [class_]device and use static attribute structures instead. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) (limited to 'drivers/base/class.c') diff --git a/drivers/base/class.c b/drivers/base/class.c index 9cbfde23b9e3..4d2222618b78 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -312,9 +312,6 @@ static void class_dev_release(struct kobject * kobj) pr_debug("device class '%s': release.\n", cd->class_id); - kfree(cd->devt_attr); - cd->devt_attr = NULL; - if (cd->release) cd->release(cd); else if (cls->release) @@ -547,6 +544,9 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf) return print_dev_t(buf, class_dev->devt); } +static struct class_device_attribute class_devt_attr = + __ATTR(dev, S_IRUGO, show_dev, NULL); + static ssize_t store_uevent(struct class_device *class_dev, const char *buf, size_t count) { @@ -554,6 +554,9 @@ static ssize_t store_uevent(struct class_device *class_dev, return count; } +static struct class_device_attribute class_uevent_attr = + __ATTR(uevent, S_IWUSR, NULL, store_uevent); + void class_device_initialize(struct class_device *class_dev) { kobj_set_kset_s(class_dev, class_obj_subsys); @@ -603,30 +606,15 @@ int class_device_add(struct class_device *class_dev) &parent_class->subsys.kobj, "subsystem"); if (error) goto out3; - class_dev->uevent_attr.attr.name = "uevent"; - class_dev->uevent_attr.attr.mode = S_IWUSR; - class_dev->uevent_attr.store = store_uevent; - error = class_device_create_file(class_dev, &class_dev->uevent_attr); + + error = class_device_create_file(class_dev, &class_uevent_attr); if (error) goto out3; if (MAJOR(class_dev->devt)) { - struct class_device_attribute *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); - if (!attr) { - error = -ENOMEM; - goto out4; - } - attr->attr.name = "dev"; - attr->attr.mode = S_IRUGO; - attr->show = show_dev; - error = class_device_create_file(class_dev, attr); - if (error) { - kfree(attr); + error = class_device_create_file(class_dev, &class_devt_attr); + if (error) goto out4; - } - - class_dev->devt_attr = attr; } error = class_device_add_attrs(class_dev); @@ -669,10 +657,10 @@ int class_device_add(struct class_device *class_dev) out6: class_device_remove_attrs(class_dev); out5: - if (class_dev->devt_attr) - class_device_remove_file(class_dev, class_dev->devt_attr); + if (MAJOR(class_dev->devt)) + class_device_remove_file(class_dev, &class_devt_attr); out4: - class_device_remove_file(class_dev, &class_dev->uevent_attr); + class_device_remove_file(class_dev, &class_uevent_attr); out3: kobject_del(&class_dev->kobj); out2: @@ -772,9 +760,9 @@ void class_device_del(struct class_device *class_dev) sysfs_remove_link(&class_dev->kobj, "device"); } sysfs_remove_link(&class_dev->kobj, "subsystem"); - class_device_remove_file(class_dev, &class_dev->uevent_attr); - if (class_dev->devt_attr) - class_device_remove_file(class_dev, class_dev->devt_attr); + class_device_remove_file(class_dev, &class_uevent_attr); + if (MAJOR(class_dev->devt)) + class_device_remove_file(class_dev, &class_devt_attr); class_device_remove_attrs(class_dev); class_device_remove_groups(class_dev); -- cgit v1.2.3