Hi James: * James Bottomley <James.Bottomley@xxxxxxxxxxxx> [2007-10-30 13:25:43 -0500]: > On Mon, 2007-10-29 at 18:58 +0100, Stefan Richter wrote: > > James Bottomley wrote: > > >> > struct attribute_group { > > >> > const char *name; > > >> > + int (*filter_show)(struct kobject *, int); > > > > > Actually, it returns a true/false value indicating whether the given > > > attribute should be displayed. > > > > How about this: > > > > int (*is_visible)(...); > > OK, so is this latest revision acceptable to everyone? I've just been hacking around in this area a bit, for a completely different reason: there are literally 1000's of attributes in drivers/hwmon/*.c that really want to be const, but which cannot be due to the current API. I was about to propose some patches that move in a different direction... > Index: BUILD-2.6/fs/sysfs/group.c > =================================================================== > --- BUILD-2.6.orig/fs/sysfs/group.c 2007-10-28 17:27:04.000000000 -0500 > +++ BUILD-2.6/fs/sysfs/group.c 2007-10-30 12:35:47.000000000 -0500 > @@ -16,25 +16,31 @@ > #include "sysfs.h" > > > -static void remove_files(struct sysfs_dirent *dir_sd, > +static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, > const struct attribute_group *grp) > { > struct attribute *const* attr; > + int i; > > - for (attr = grp->attrs; *attr; attr++) > - sysfs_hash_and_remove(dir_sd, (*attr)->name); > + for (i = 0, attr = grp->attrs; *attr; i++, attr++) > + if (grp->is_visible && > + grp->is_visible(kobj, *attr, i)) > + sysfs_hash_and_remove(dir_sd, (*attr)->name); > } > > -static int create_files(struct sysfs_dirent *dir_sd, > +static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, > const struct attribute_group *grp) > { > struct attribute *const* attr; > - int error = 0; > + int error = 0, i; > > - for (attr = grp->attrs; *attr && !error; attr++) > - error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); > + for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) > + if (grp->is_visible && > + grp->is_visible(kobj, *attr, i)) > + error |= > + sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); > if (error) > - remove_files(dir_sd, grp); > + remove_files(dir_sd, kobj, grp); > return error; > } > > @@ -54,7 +60,7 @@ int sysfs_create_group(struct kobject * > } else > sd = kobj->sd; > sysfs_get(sd); > - error = create_files(sd, grp); > + error = create_files(sd, kobj, grp); > if (error) { > if (grp->name) > sysfs_remove_subdir(sd); > @@ -75,7 +81,7 @@ void sysfs_remove_group(struct kobject * > } else > sd = sysfs_get(dir_sd); > > - remove_files(sd, grp); > + remove_files(sd, kobj, grp); > if (grp->name) > sysfs_remove_subdir(sd); > > Index: BUILD-2.6/include/linux/sysfs.h > =================================================================== > --- BUILD-2.6.orig/include/linux/sysfs.h 2007-10-28 17:20:06.000000000 -0500 > +++ BUILD-2.6/include/linux/sysfs.h 2007-10-30 13:24:06.000000000 -0500 > @@ -32,6 +32,8 @@ struct attribute { > > struct attribute_group { > const char *name; > + int (*is_visible)(struct kobject *, > + struct attribute *, int); > struct attribute **attrs; > }; IMHO the fundamental problem is struct attribute_group itself. This structure is nothing but a convenience for packaging the arguments to sysfs_create_group and sysfs_remove_group. Those functions should take the contents of that struct as direct arguments. I haven't finished the patch series to implement this, but since I noticed your patch I thought I'd better speak up now. Here's the first... the idea is to eventually deprecate sysfs_[create|remove]_group() altogether. commit 5b5bc08ae31519b7012d7fc23ff73e0c6474de53 Author: Mark M. Hoffman <mhoffman@xxxxxxxxxxxxx> Date: Sun Oct 21 11:49:57 2007 -0400 sysfs: allow attribute (group) lists to be const The current declaration of struct attribute_group prevents long lists of attributes from being marked const. Ideally, the second argument to the sysfs_create_group() and sysfs_remove_group() functions would be marked "deep" const, but C has no such construct. This patch provides a parallel set of functions with the desired decoration. Signed-off-by: Mark M. Hoffman <mhoffman@xxxxxxxxxxxxx> diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index d197237..b217a8e 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -17,71 +17,84 @@ static void remove_files(struct sysfs_dirent *dir_sd, - const struct attribute_group *grp) + const struct attribute * const * attrs) { - struct attribute *const* attr; + const struct attribute *const* attr; - for (attr = grp->attrs; *attr; attr++) + for (attr = attrs; *attr; attr++) sysfs_hash_and_remove(dir_sd, (*attr)->name); } static int create_files(struct sysfs_dirent *dir_sd, - const struct attribute_group *grp) + const struct attribute * const * attrs) { - struct attribute *const* attr; + const struct attribute *const* attr; int error = 0; - for (attr = grp->attrs; *attr && !error; attr++) + for (attr = attrs; *attr && !error; attr++) error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); if (error) - remove_files(dir_sd, grp); + remove_files(dir_sd, attrs); return error; } - -int sysfs_create_group(struct kobject * kobj, - const struct attribute_group * grp) +int sysfs_create_attr_group(struct kobject * kobj, + const char *name, const struct attribute * const * attrs) { struct sysfs_dirent *sd; int error; BUG_ON(!kobj || !kobj->sd); - if (grp->name) { - error = sysfs_create_subdir(kobj, grp->name, &sd); + if (name) { + error = sysfs_create_subdir(kobj, name, &sd); if (error) return error; } else sd = kobj->sd; sysfs_get(sd); - error = create_files(sd, grp); - if (error) { - if (grp->name) - sysfs_remove_subdir(sd); - } + error = create_files(sd, attrs); + if (error && name) + sysfs_remove_subdir(sd); + sysfs_put(sd); return error; } -void sysfs_remove_group(struct kobject * kobj, - const struct attribute_group * grp) +int sysfs_create_group (struct kobject * kobj, + const struct attribute_group *grp) +{ + return sysfs_create_attr_group(kobj, grp->name, + (const struct attribute * const *)grp->attrs); +} + +void sysfs_remove_attr_group(struct kobject * kobj, + const char *name, const struct attribute * const * attrs) { struct sysfs_dirent *dir_sd = kobj->sd; struct sysfs_dirent *sd; - if (grp->name) { - sd = sysfs_get_dirent(dir_sd, grp->name); + if (name) { + sd = sysfs_get_dirent(dir_sd, name); BUG_ON(!sd); } else sd = sysfs_get(dir_sd); - remove_files(sd, grp); - if (grp->name) + remove_files(sd, attrs); + if (name) sysfs_remove_subdir(sd); sysfs_put(sd); } +void sysfs_remove_group(struct kobject *kobj, + const struct attribute_group *grp) +{ + return sysfs_remove_attr_group(kobj, grp->name, + (const struct attribute * const *)grp->attrs); +} +EXPORT_SYMBOL_GPL(sysfs_create_attr_group); +EXPORT_SYMBOL_GPL(sysfs_remove_attr_group); EXPORT_SYMBOL_GPL(sysfs_create_group); EXPORT_SYMBOL_GPL(sysfs_remove_group); diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 149ab62..5066d50 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -101,10 +101,18 @@ int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name); void sysfs_remove_link(struct kobject *kobj, const char *name); +int __must_check sysfs_create_attr_group(struct kobject *, + const char * name, const struct attribute * const * attrs); + int __must_check sysfs_create_group(struct kobject *kobj, - const struct attribute_group *grp); + const struct attribute_group *grp); + +void sysfs_remove_attr_group(struct kobject *, + const char * name, const struct attribute * const * attrs); + void sysfs_remove_group(struct kobject *kobj, - const struct attribute_group *grp); + const struct attribute_group *grp); + 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, @@ -190,8 +198,19 @@ static inline int sysfs_create_group(struct kobject *kobj, return 0; } -static inline void sysfs_remove_group(struct kobject *kobj, - const struct attribute_group *grp) +static inline int sysfs_create_attr_group(struct kobject *k, + const char * name, const struct attribute * const * attrs) +{ + return 0; +} + +static inline void sysfs_remove_group(struct kobject * k, const struct attribute_group * g) +{ + ; +} + +static inline void sysfs_remove_attr_group(struct kobject * k, + const char * name, const struct attribute * const * attrs) { ; } Regards, -- Mark M. Hoffman mhoffman@xxxxxxxxxxxxx - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html