Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756501AbYGDBYT (ORCPT ); Thu, 3 Jul 2008 21:24:19 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757679AbYGDBWO (ORCPT ); Thu, 3 Jul 2008 21:22:14 -0400 Received: from out01.mta.xmission.com ([166.70.13.231]:57995 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755610AbYGDBVz (ORCPT ); Thu, 3 Jul 2008 21:21:55 -0400 From: ebiederm@xmission.com (Eric W. Biederman) To: Greg Kroah-Hartman , Andrew Morton Cc: Tejun Heo , Daniel Lezcano , linux-kernel@vger.kernel.org, Al Viro , Linux Containers , Benjamin Thery , References: <20080618170729.808539948@theryb.frec.bull.fr> <486B060C.7030607@gmail.com> <486C4515.1070007@gmail.com> <486CB051.5000507@fr.ibm.com> <486CF71F.5090405@gmail.com> Date: Thu, 03 Jul 2008 18:20:09 -0700 In-Reply-To: (Eric W. Biederman's message of "Thu, 03 Jul 2008 18:18:29 -0700") Message-ID: User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SA-Exim-Connect-IP: 24.130.11.59 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-DCC: XMission; sa02 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: ;Greg Kroah-Hartman , Andrew Morton X-Spam-Relay-Country: X-Spam-Report: * -1.8 ALL_TRUSTED Passed through trusted hosts only via SMTP * -2.6 BAYES_00 BODY: Bayesian spam probability is 0 to 1% * [score: 0.0001] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa02 1397; Body=1 Fuz1=1 Fuz2=1] * 0.0 XM_SPF_Neutral SPF-Neutral Subject: [PATCH 12/15] driver core: Implement tagged directory support for device classes. X-SA-Exim-Version: 4.2 (built Thu, 03 Mar 2005 10:44:12 +0100) X-SA-Exim-Scanned: Yes (on mgr1.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6101 Lines: 211 This patch enables tagging on every class directory if struct class has a tag_type. In addition device_del and device_rename were modified to uses sysfs_delete_link and sysfs_rename_link respectively to ensure when these operations happen on devices whose classes have tag_ops that they work properly. Signed-off-by: Eric W. Biederman Signed-off-by: Benjamin Thery --- drivers/base/class.c | 30 ++++++++++++++++++++++--- drivers/base/core.c | 56 +++++++++++++++++++++++++++++++++-------------- include/linux/device.h | 3 ++ 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 839d27c..cf4e03f 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -135,6 +135,17 @@ static void remove_class_attrs(struct class *cls) } } +static int class_setup_tagging(struct class *cls) +{ + enum sysfs_tag_type type; + + type = cls->tag_type; + if (type == SYSFS_TAG_TYPE_NONE) + return 0; + + return sysfs_make_tagged_dir(&cls->p->class_subsys.kobj, type); +} + int __class_register(struct class *cls, struct lock_class_key *key) { struct class_private *cp; @@ -171,13 +182,24 @@ int __class_register(struct class *cls, struct lock_class_key *key) cls->p = cp; error = kset_register(&cp->class_subsys); - if (error) { - kfree(cp); - return error; - } + if (error) + goto out_free_cp; + + error = class_setup_tagging(cls); + if (error) + goto out_unregister; + error = add_class_attrs(class_get(cls)); class_put(cls); + if (error) + goto out_unregister; +out: return error; +out_unregister: + kset_unregister(&cp->class_subsys); +out_free_cp: + kfree(cp); + goto out; } EXPORT_SYMBOL_GPL(__class_register); diff --git a/drivers/base/core.c b/drivers/base/core.c index 90621a4..b009d5b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -124,9 +124,21 @@ static void device_release(struct kobject *kobj) } } +static const void *device_sysfs_tag(struct kobject *kobj) +{ + struct device *dev = to_dev(kobj); + const void *tag = NULL; + + if (dev->class && dev->class->tag_type) + tag = dev->class->sysfs_tag(dev); + + return tag; +} + static struct kobj_type device_ktype = { .release = device_release, .sysfs_ops = &dev_sysfs_ops, + .sysfs_tag = device_sysfs_tag, }; @@ -619,6 +631,10 @@ static struct kobject *get_device_parent(struct device *dev, kobject_put(k); return NULL; } + /* If we created a new class-directory setup tagging */ + if (dev->class->tag_type) + sysfs_make_tagged_dir(k, dev->class->tag_type); + /* do not emit an uevent for this simple "glue" directory */ return k; } @@ -709,7 +725,7 @@ out_device: out_busid: if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->p->class_subsys.kobj, + sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); #else /* link in the class directory pointing to the device */ @@ -727,7 +743,7 @@ out_busid: return 0; out_busid: - sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); + sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); #endif out_subsys: @@ -755,13 +771,13 @@ static void device_remove_class_symlinks(struct device *dev) if (dev->kobj.parent != &dev->class->p->class_subsys.kobj && device_is_not_partition(dev)) - sysfs_remove_link(&dev->class->p->class_subsys.kobj, + sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); #else if (dev->parent && device_is_not_partition(dev)) sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id); + sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev->bus_id); #endif sysfs_remove_link(&dev->kobj, "subsystem"); @@ -1344,6 +1360,16 @@ int device_rename(struct device *dev, char *new_name) strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE); strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); +#ifndef CONFIG_SYSFS_DEPRECATED + if (dev->class && + (dev->kobj.parent != &dev->class->p->class_subsys.kobj)) { + error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, + &dev->kobj, old_device_name, new_name); + if (error) + goto out; + } +#endif + error = kobject_rename(&dev->kobj, new_name); if (error) { strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE); @@ -1352,23 +1378,19 @@ int device_rename(struct device *dev, char *new_name) #ifdef CONFIG_SYSFS_DEPRECATED if (old_class_name) { + error = -ENOMEM; new_class_name = make_class_name(dev->class->name, &dev->kobj); - if (new_class_name) { - error = sysfs_create_link(&dev->parent->kobj, - &dev->kobj, new_class_name); - if (error) - goto out; - sysfs_remove_link(&dev->parent->kobj, old_class_name); - } + if (new_class_name) + error = sysfs_rename_link(&dev->parent->kobj, + &dev->kobj, + old_class_name, + new_class_name); } #else if (dev->class) { - error = sysfs_create_link(&dev->class->p->class_subsys.kobj, - &dev->kobj, dev->bus_id); - if (error) - goto out; - sysfs_remove_link(&dev->class->p->class_subsys.kobj, - old_device_name); + error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, + &dev->kobj, old_device_name, + dev->bus_id); } #endif diff --git a/include/linux/device.h b/include/linux/device.h index d9886a6..8e84539 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -191,6 +191,9 @@ struct class { int (*suspend)(struct device *dev, pm_message_t state); int (*resume)(struct device *dev); + enum sysfs_tag_type tag_type; + const void *(*sysfs_tag)(struct device *dev); + struct class_private *p; }; -- 1.5.3.rc6.17.g1911 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/