From 6853152689d47b4a1eb9f38a25a18f3f8b7a60de Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 20 Aug 2013 16:48:54 -0700 Subject: sysfs.h: fix __BIN_ATTR_RW() __BIN_ATTR_RW() wasn't passing in the _size field. As it would break the build if this macro was ever used, it's obvious no one had ever tried to use it before. Fix it so that it can be used. Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/sysfs.h') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 9e8a9b555ad..0f04958623d 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -153,7 +153,7 @@ struct bin_attribute { #define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \ (S_IWUSR | S_IRUGO), _name##_read, \ - _name##_write) + _name##_write, _size) #define __BIN_ATTR_NULL __ATTR_NULL -- cgit v1.2.3-70-g09d2 From 3e9b2bae8369661070622d05570cbcdfa01770e6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 Aug 2013 13:47:50 -0700 Subject: sysfs: add sysfs_create/remove_groups() These functions are being open-coded in 3 different places in the driver core, and other driver subsystems will want to start doing this as well, so move it to the sysfs core to keep it all in one place, where we know it is written properly. Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 23 ++-------------------- drivers/base/core.c | 22 ++------------------- drivers/base/driver.c | 22 ++------------------- fs/sysfs/group.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sysfs.h | 4 ++++ 5 files changed, 64 insertions(+), 61 deletions(-) (limited to 'include/linux/sysfs.h') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 5ee5d3c1d74..f099af0b41a 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -884,32 +884,13 @@ static void bus_remove_attrs(struct bus_type *bus) static int bus_add_groups(struct bus_type *bus, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&bus->p->subsys.kobj, - groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&bus->p->subsys.kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&bus->p->subsys.kobj, groups); } static void bus_remove_groups(struct bus_type *bus, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&bus->p->subsys.kobj, groups[i]); + sysfs_remove_groups(&bus->p->subsys.kobj, groups); } static void klist_devices_get(struct klist_node *n) diff --git a/drivers/base/core.c b/drivers/base/core.c index af646afa5b7..d743dcee1e7 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -493,31 +493,13 @@ static void device_remove_bin_attributes(struct device *dev, int device_add_groups(struct device *dev, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&dev->kobj, groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&dev->kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&dev->kobj, groups); } void device_remove_groups(struct device *dev, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&dev->kobj, groups[i]); + sysfs_remove_groups(&dev->kobj, groups); } static int device_add_attrs(struct device *dev) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 89db726ebb9..c7efccb6f3b 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -126,31 +126,13 @@ EXPORT_SYMBOL_GPL(driver_remove_file); int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups) { - int error = 0; - int i; - - if (groups) { - for (i = 0; groups[i]; i++) { - error = sysfs_create_group(&drv->p->kobj, groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&drv->p->kobj, - groups[i]); - break; - } - } - } - return error; + return sysfs_create_groups(&drv->p->kobj, groups); } void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups) { - int i; - - if (groups) - for (i = 0; groups[i]; i++) - sysfs_remove_group(&drv->p->kobj, groups[i]); + sysfs_remove_groups(&drv->p->kobj, groups); } /** diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 09a1a25cd14..68baf850155 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -130,6 +130,40 @@ int sysfs_create_group(struct kobject *kobj, return internal_create_group(kobj, 0, grp); } +/** + * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups + * @kobj: The kobject to create the group on + * @groups: The attribute groups to create, NULL terminated + * + * This function creates a bunch of attribute groups. If an error occurs when + * creating a group, all previously created groups will be removed, unwinding + * everything back to the original state when this function was called. + * It will explicitly warn and error if any of the attribute files being + * created already exist. + * + * Returns 0 on success or error code from sysfs_create_groups on error. + */ +int sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ + int error = 0; + int i; + + if (!groups) + return 0; + + for (i = 0; groups[i]; i++) { + error = sysfs_create_group(kobj, groups[i]); + if (error) { + while (--i >= 0) + sysfs_remove_group(kobj, groups[i]); + break; + } + } + return error; +} +EXPORT_SYMBOL_GPL(sysfs_create_groups); + /** * sysfs_update_group - given a directory kobject, update an attribute group * @kobj: The kobject to update the group on @@ -178,6 +212,26 @@ void sysfs_remove_group(struct kobject * kobj, sysfs_put(sd); } +/** + * sysfs_remove_groups - remove a list of groups + * + * kobj: The kobject for the groups to be removed from + * groups: NULL terminated list of groups to be removed + * + * If groups is not NULL, the all groups will be removed from the kobject + */ +void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ + int i; + + if (!groups) + return; + for (i = 0; groups[i]; i++) + sysfs_remove_group(kobj, groups[i]); +} +EXPORT_SYMBOL_GPL(sysfs_remove_groups); + /** * sysfs_merge_group - merge files into a pre-existing attribute group. * @kobj: The kobject containing the group. diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 0f04958623d..4dbb9d31daa 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -215,10 +215,14 @@ void sysfs_delete_link(struct kobject *dir, struct kobject *targ, int __must_check sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); +int __must_check sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp); void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); +void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups); int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group); void sysfs_remove_file_from_group(struct kobject *kobj, -- cgit v1.2.3-70-g09d2 From 5da5c9c899dc456d6eb43aae3e8d4e853b7f5306 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 Aug 2013 17:47:05 -0700 Subject: sysfs: fix up minor coding style issues in sysfs.h As long as we are cleaning up sysfs coding style issues, don't forget the main sysfs.h file, so fix up the space issues there as well. Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux/sysfs.h') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 4dbb9d31daa..a864b8d918e 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -51,9 +51,9 @@ do { \ static struct lock_class_key __key; \ \ (attr)->key = &__key; \ -} while(0) +} while (0) #else -#define sysfs_attr_init(attr) do {} while(0) +#define sysfs_attr_init(attr) do {} while (0) #endif struct attribute_group { @@ -69,7 +69,7 @@ struct attribute_group { * for examples.. */ -#define __ATTR(_name,_mode,_show,_store) { \ +#define __ATTR(_name, _mode, _show, _store) { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ @@ -119,7 +119,7 @@ struct bin_attribute { void *private; ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); - ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *, + ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, char *, loff_t, size_t); int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, struct vm_area_struct *vma); @@ -168,8 +168,8 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size) struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) struct sysfs_ops { - ssize_t (*show)(struct kobject *, struct attribute *,char *); - ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); + ssize_t (*show)(struct kobject *, struct attribute *, char *); + ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t); const void *(*namespace)(struct kobject *, const struct attribute *); }; -- cgit v1.2.3-70-g09d2 From 3e1026b3fa2f61d33ce6a9e42a22398cc4ab8e58 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 22 Aug 2013 10:25:34 -0700 Subject: sysfs.h: remove attr_name() macro Gotta love a macro that doesn't reduce the typing you have to do. Also, only the driver core, and one network driver uses this. The driver core functions will be going away soon, and I'll convert the network driver soon to not need this as well, so delete it for now before anyone else gets some bright ideas and wants to use it. Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 12 ++++++------ drivers/base/class.c | 4 ++-- drivers/base/core.c | 8 ++++---- drivers/net/ethernet/sun/niu.c | 2 +- include/linux/sysfs.h | 2 -- 5 files changed, 13 insertions(+), 15 deletions(-) (limited to 'include/linux/sysfs.h') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index f099af0b41a..235e2b06ac0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -460,7 +460,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) if (!bus->dev_attrs) return 0; - for (i = 0; attr_name(bus->dev_attrs[i]); i++) { + for (i = 0; bus->dev_attrs[i].attr.name; i++) { error = device_create_file(dev, &bus->dev_attrs[i]); if (error) { while (--i >= 0) @@ -476,7 +476,7 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) int i; if (bus->dev_attrs) { - for (i = 0; attr_name(bus->dev_attrs[i]); i++) + for (i = 0; bus->dev_attrs[i].attr.name; i++) device_remove_file(dev, &bus->dev_attrs[i]); } } @@ -596,7 +596,7 @@ static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) int i; if (bus->drv_attrs) { - for (i = 0; attr_name(bus->drv_attrs[i]); i++) { + for (i = 0; bus->drv_attrs[i].attr.name; i++) { error = driver_create_file(drv, &bus->drv_attrs[i]); if (error) goto err; @@ -616,7 +616,7 @@ static void driver_remove_attrs(struct bus_type *bus, int i; if (bus->drv_attrs) { - for (i = 0; attr_name(bus->drv_attrs[i]); i++) + for (i = 0; bus->drv_attrs[i].attr.name; i++) driver_remove_file(drv, &bus->drv_attrs[i]); } } @@ -857,7 +857,7 @@ static int bus_add_attrs(struct bus_type *bus) int i; if (bus->bus_attrs) { - for (i = 0; attr_name(bus->bus_attrs[i]); i++) { + for (i = 0; bus->bus_attrs[i].attr.name; i++) { error = bus_create_file(bus, &bus->bus_attrs[i]); if (error) goto err; @@ -876,7 +876,7 @@ static void bus_remove_attrs(struct bus_type *bus) int i; if (bus->bus_attrs) { - for (i = 0; attr_name(bus->bus_attrs[i]); i++) + for (i = 0; bus->bus_attrs[i].attr.name; i++) bus_remove_file(bus, &bus->bus_attrs[i]); } } diff --git a/drivers/base/class.c b/drivers/base/class.c index 3ce84547132..8b7818b8005 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -135,7 +135,7 @@ static int add_class_attrs(struct class *cls) int error = 0; if (cls->class_attrs) { - for (i = 0; attr_name(cls->class_attrs[i]); i++) { + for (i = 0; cls->class_attrs[i].attr.name; i++) { error = class_create_file(cls, &cls->class_attrs[i]); if (error) goto error; @@ -154,7 +154,7 @@ static void remove_class_attrs(struct class *cls) int i; if (cls->class_attrs) { - for (i = 0; attr_name(cls->class_attrs[i]); i++) + for (i = 0; cls->class_attrs[i].attr.name; i++) class_remove_file(cls, &cls->class_attrs[i]); } } diff --git a/drivers/base/core.c b/drivers/base/core.c index d743dcee1e7..ae1acdf21bd 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -440,7 +440,7 @@ static int device_add_attributes(struct device *dev, int i; if (attrs) { - for (i = 0; attr_name(attrs[i]); i++) { + for (i = 0; attrs[i].attr.name; i++) { error = device_create_file(dev, &attrs[i]); if (error) break; @@ -458,7 +458,7 @@ static void device_remove_attributes(struct device *dev, int i; if (attrs) - for (i = 0; attr_name(attrs[i]); i++) + for (i = 0; attrs[i].attr.name; i++) device_remove_file(dev, &attrs[i]); } @@ -469,7 +469,7 @@ static int device_add_bin_attributes(struct device *dev, int i; if (attrs) { - for (i = 0; attr_name(attrs[i]); i++) { + for (i = 0; attrs[i].attr.name; i++) { error = device_create_bin_file(dev, &attrs[i]); if (error) break; @@ -487,7 +487,7 @@ static void device_remove_bin_attributes(struct device *dev, int i; if (attrs) - for (i = 0; attr_name(attrs[i]); i++) + for (i = 0; attrs[i].attr.name; i++) device_remove_bin_file(dev, &attrs[i]); } diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index fa322409bff..52b2adf63cb 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9478,7 +9478,7 @@ static struct niu_parent *niu_new_parent(struct niu *np, if (IS_ERR(plat_dev)) return NULL; - for (i = 0; attr_name(niu_parent_attributes[i]); i++) { + for (i = 0; niu_parent_attributes[i].attr.name; i++) { int err = device_create_file(&plat_dev->dev, &niu_parent_attributes[i]); if (err) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index a864b8d918e..b5a9d9b26bd 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -108,8 +108,6 @@ static const struct attribute_group _name##_group = { \ }; \ __ATTRIBUTE_GROUPS(_name) -#define attr_name(_attr) (_attr).attr.name - struct file; struct vm_area_struct; -- cgit v1.2.3-70-g09d2 From a65fcce75a75c0d41b938f86d09d42b6f1733309 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 23 Aug 2013 15:02:01 -0700 Subject: sysfs: create __ATTR_WO() This creates the macro __ATTR_WO() for write-only attributes, instead of having to "open define" them. Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux/sysfs.h') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b5a9d9b26bd..69c1ff00362 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -80,6 +80,11 @@ struct attribute_group { .show = _name##_show, \ } +#define __ATTR_WO(_name) { \ + .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ + .store = _name##_store, \ +} + #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ _name##_show, _name##_store) -- cgit v1.2.3-70-g09d2 From f799878000c5a9a1e6a311dfd4faa50601dcb1f8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 27 Aug 2013 17:24:49 -0700 Subject: sysfs: add sysfs_create/remove_groups for when SYSFS is not enabled We need these functions for when CONFIG_SYSFS=n. Reported-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux/sysfs.h') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 69c1ff00362..e647a1aa072 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -350,6 +350,11 @@ static inline int sysfs_create_group(struct kobject *kobj, return 0; } +static inline int sysfs_create_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ +} + static inline int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp) { @@ -361,6 +366,11 @@ static inline void sysfs_remove_group(struct kobject *kobj, { } +static inline void sysfs_remove_groups(struct kobject *kobj, + const struct attribute_group **groups) +{ +} + static inline int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group) { -- cgit v1.2.3-70-g09d2 From 574979c617eb9593f8dfbb804da3f0e00f8bf28e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 Aug 2013 09:51:41 -0700 Subject: sysfs: sysfs_create_groups returns a value. When I included the "empty" function for sysfs_create_groups() when CONFIG_SYSFS=n, I forgot to return a value for it, so things blew up the build. This patch fixes that, stupid me. Reported-by: kbuild test robot Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/sysfs.h') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index e647a1aa072..11baec7c9b2 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -353,6 +353,7 @@ static inline int sysfs_create_group(struct kobject *kobj, static inline int sysfs_create_groups(struct kobject *kobj, const struct attribute_group **groups) { + return 0; } static inline int sysfs_update_group(struct kobject *kobj, -- cgit v1.2.3-70-g09d2