Skip to content

Commit

Permalink
sysfs: Add sysfs_merge_group() and sysfs_unmerge_group()
Browse files Browse the repository at this point in the history
This patch (as1420) adds sysfs_merge_group() and sysfs_unmerge_group()
functions, allowing drivers easily to add and remove sets of
attributes to a pre-existing attribute group directory.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
  • Loading branch information
Alan Stern authored and Rafael J. Wysocki committed Oct 16, 2010
1 parent 098dff7 commit 69d44ff
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
59 changes: 59 additions & 0 deletions fs/sysfs/group.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,65 @@ void sysfs_remove_group(struct kobject * kobj,
sysfs_put(sd);
}

/**
* sysfs_merge_group - merge files into a pre-existing attribute group.
* @kobj: The kobject containing the group.
* @grp: The files to create and the attribute group they belong to.
*
* This function returns an error if the group doesn't exist or any of the
* files already exist in that group, in which case none of the new files
* are created.
*/
int sysfs_merge_group(struct kobject *kobj,
const struct attribute_group *grp)
{
struct sysfs_dirent *dir_sd;
int error = 0;
struct attribute *const *attr;
int i;

if (grp)
dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
else
dir_sd = sysfs_get(kobj->sd);
if (!dir_sd)
return -ENOENT;

for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
if (error) {
while (--i >= 0)
sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name);
}
sysfs_put(dir_sd);

return error;
}
EXPORT_SYMBOL_GPL(sysfs_merge_group);

/**
* sysfs_unmerge_group - remove files from a pre-existing attribute group.
* @kobj: The kobject containing the group.
* @grp: The files to remove and the attribute group they belong to.
*/
void sysfs_unmerge_group(struct kobject *kobj,
const struct attribute_group *grp)
{
struct sysfs_dirent *dir_sd;
struct attribute *const *attr;

if (grp)
dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
else
dir_sd = sysfs_get(kobj->sd);
if (dir_sd) {
for (attr = grp->attrs; *attr; ++attr)
sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
sysfs_put(dir_sd);
}
}
EXPORT_SYMBOL_GPL(sysfs_unmerge_group);


EXPORT_SYMBOL_GPL(sysfs_create_group);
EXPORT_SYMBOL_GPL(sysfs_update_group);
Expand Down
15 changes: 15 additions & 0 deletions include/linux/sysfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ 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,
const struct attribute *attr, const char *group);
int sysfs_merge_group(struct kobject *kobj,
const struct attribute_group *grp);
void sysfs_unmerge_group(struct kobject *kobj,
const struct attribute_group *grp);

void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
void sysfs_notify_dirent(struct sysfs_dirent *sd);
Expand Down Expand Up @@ -302,6 +306,17 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
{
}

static inline int sysfs_merge_group(struct kobject *kobj,
const struct attribute_group *grp)
{
return 0;
}

static inline void sysfs_unmerge_group(struct kobject *kobj,
const struct attribute_group *grp)
{
}

static inline void sysfs_notify(struct kobject *kobj, const char *dir,
const char *attr)
{
Expand Down

0 comments on commit 69d44ff

Please sign in to comment.