cregit-Linux how code gets into the kernel

Release 4.10 fs/sysfs/group.c

Directory: fs/sysfs
/*
 * fs/sysfs/group.c - Operations for adding/removing multiple files at once.
 *
 * Copyright (c) 2003 Patrick Mochel
 * Copyright (c) 2003 Open Source Development Lab
 * Copyright (c) 2013 Greg Kroah-Hartman
 * Copyright (c) 2013 The Linux Foundation
 *
 * This file is released undert the GPL v2.
 *
 */

#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/err.h>
#include "sysfs.h"



static void remove_files(struct kernfs_node *parent, const struct attribute_group *grp) { struct attribute *const *attr; struct bin_attribute *const *bin_attr; if (grp->attrs) for (attr = grp->attrs; *attr; attr++) kernfs_remove_by_name(parent, (*attr)->name); if (grp->bin_attrs) for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) kernfs_remove_by_name(parent, (*bin_attr)->attr.name); }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel4647.42%337.50%
greg kroah-hartmangreg kroah-hartman3839.18%112.50%
robert abelrobert abel88.25%112.50%
tejun heotejun heo44.12%225.00%
james bottomleyjames bottomley11.03%112.50%
Total97100.00%8100.00%


static int create_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const *attr; struct bin_attribute *const *bin_attr; int error = 0, i; if (grp->attrs) { for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { umode_t mode = (*attr)->mode; /* * In update mode, we're changing the permissions or * visibility. Do this by first removing then * re-adding (if required) the file. */ if (update) kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } WARN(mode & ~(SYSFS_PREALLOC | 0664), "Attribute %s: Invalid permissions 0%o\n", (*attr)->name, mode); mode &= SYSFS_PREALLOC | 0664; error = sysfs_add_file_mode_ns(parent, *attr, false, mode, NULL); if (unlikely(error)) break; } if (error) { remove_files(parent, grp); goto exit; } } if (grp->bin_attrs) { for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) { umode_t mode = (*bin_attr)->attr.mode; if (update) kernfs_remove_by_name(parent, (*bin_attr)->attr.name); if (grp->is_bin_visible) { mode = grp->is_bin_visible(kobj, *bin_attr, i); if (!mode) continue; } WARN(mode & ~(SYSFS_PREALLOC | 0664), "Attribute %s: Invalid permissions 0%o\n", (*bin_attr)->attr.name, mode); mode &= SYSFS_PREALLOC | 0664; error = sysfs_add_file_mode_ns(parent, &(*bin_attr)->attr, true, mode, NULL); if (error) break; } if (error) remove_files(parent, grp); } exit: return error; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman7921.58%16.25%
emilio lopezemilio lopez7620.77%16.25%
james bottomleyjames bottomley7520.49%212.50%
patrick mochelpatrick mochel6417.49%318.75%
vivien didelotvivien didelot297.92%16.25%
cody p schafercody p schafer246.56%16.25%
tejun heotejun heo113.01%425.00%
guenter roeckguenter roeck61.64%16.25%
andrew mortonandrew morton10.27%16.25%
al viroal viro10.27%16.25%
Total366100.00%16100.00%


static int internal_create_group(struct kobject *kobj, int update, const struct attribute_group *grp) { struct kernfs_node *kn; int error; BUG_ON(!kobj || (!update && !kobj->sd)); /* Updates may happen before the object has been instantiated */ if (unlikely(update && !kobj->sd)) return -EINVAL; if (!grp->attrs && !grp->bin_attrs) { WARN(1, "sysfs: (bin_)attrs not set by subsystem for group: %s/%s\n", kobj->name, grp->name ?: ""); return -EINVAL; } if (grp->name) { kn = kernfs_create_dir(kobj->sd, grp->name, S_IRWXU | S_IRUGO | S_IXUGO, kobj); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(kobj->sd, grp->name); return PTR_ERR(kn); } } else kn = kobj->sd; kernfs_get(kn); error = create_files(kn, kobj, grp, update); if (error) { if (grp->name) kernfs_remove(kn); } kernfs_put(kn); return error; }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel7635.85%318.75%
tejun heotejun heo5827.36%637.50%
james bottomleyjames bottomley3114.62%212.50%
bruno premontbruno premont2913.68%16.25%
andrew mortonandrew morton115.19%212.50%
oliver schinagloliver schinagl62.83%16.25%
javi merinojavi merino10.47%16.25%
Total212100.00%16100.00%

/** * sysfs_create_group - given a directory kobject, create an attribute group * @kobj: The kobject to create the group on * @grp: The attribute group to create * * This function creates a group for the first time. It will explicitly * warn and error if any of the attribute files being created already exist. * * Returns 0 on success or error code on failure. */
int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) { return internal_create_group(kobj, 0, grp); }

Contributors

PersonTokensPropCommitsCommitProp
james bottomleyjames bottomley26100.00%1100.00%
Total26100.00%1100.00%

EXPORT_SYMBOL_GPL(sysfs_create_group); /** * 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_group on failure. */
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; }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman88100.00%1100.00%
Total88100.00%1100.00%

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 * @grp: The attribute group to update * * This function updates an attribute group. Unlike * sysfs_create_group(), it will explicitly not warn or error if any * of the attribute files being created already exist. Furthermore, * if the visibility of the files has changed through the is_visible() * callback, it will update the permissions and add or remove the * relevant files. * * The primary use for this function is to call it after making a change * that affects group visibility. * * Returns 0 on success or error code on failure. */
int sysfs_update_group(struct kobject *kobj, const struct attribute_group *grp) { return internal_create_group(kobj, 1, grp); }

Contributors

PersonTokensPropCommitsCommitProp
james bottomleyjames bottomley26100.00%1100.00%
Total26100.00%1100.00%

EXPORT_SYMBOL_GPL(sysfs_update_group); /** * sysfs_remove_group: remove a group from a kobject * @kobj: kobject to remove the group from * @grp: group to remove * * This function removes a group of attributes from a kobject. The attributes * previously have to have been created for this group, otherwise it will fail. */
void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) { struct kernfs_node *parent = kobj->sd; struct kernfs_node *kn; if (grp->name) { kn = kernfs_find_and_get(parent, grp->name); if (!kn) { WARN(!kn, KERN_WARNING "sysfs group '%s' not found for kobject '%s'\n", grp->name, kobject_name(kobj)); return; } } else { kn = parent; kernfs_get(kn); } remove_files(kn, grp); if (grp->name) kernfs_remove(kn); kernfs_put(kn); }

Contributors

PersonTokensPropCommitsCommitProp
patrick mochelpatrick mochel5146.36%218.18%
tejun heotejun heo2926.36%436.36%
greg kroah-hartmangreg kroah-hartman1816.36%19.09%
andrew mortonandrew morton43.64%19.09%
johannes thumshirnjohannes thumshirn32.73%19.09%
arjan van de venarjan van de ven32.73%19.09%
james morrisjames morris21.82%19.09%
Total110100.00%11100.00%

EXPORT_SYMBOL_GPL(sysfs_remove_group); /** * 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, remove the specified groups 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]); }

Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman50100.00%1100.00%
Total50100.00%1100.00%

EXPORT_SYMBOL_GPL(sysfs_remove_groups); /** * 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 kernfs_node *parent; int error = 0; struct attribute *const *attr; int i; parent = kernfs_find_and_get(kobj->sd, grp->name); if (!parent) return -ENOENT; for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) error = sysfs_add_file(parent, *attr, false); if (error) { while (--i >= 0) kernfs_remove_by_name(parent, (*--attr)->name); } kernfs_put(parent); return error; }

Contributors

PersonTokensPropCommitsCommitProp
alan sternalan stern12191.67%120.00%
tejun heotejun heo118.33%480.00%
Total132100.00%5100.00%

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 kernfs_node *parent; struct attribute *const *attr; parent = kernfs_find_and_get(kobj->sd, grp->name); if (parent) { for (attr = grp->attrs; *attr; ++attr) kernfs_remove_by_name(parent, (*attr)->name); kernfs_put(parent); } }

Contributors

PersonTokensPropCommitsCommitProp
alan sternalan stern6988.46%125.00%
tejun heotejun heo911.54%375.00%
Total78100.00%4100.00%

EXPORT_SYMBOL_GPL(sysfs_unmerge_group); /** * sysfs_add_link_to_group - add a symlink to an attribute group. * @kobj: The kobject containing the group. * @group_name: The name of the group. * @target: The target kobject of the symlink to create. * @link_name: The name of the symlink to create. */
int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, struct kobject *target, const char *link_name) { struct kernfs_node *parent; int error = 0; parent = kernfs_find_and_get(kobj->sd, group_name); if (!parent) return -ENOENT; error = sysfs_create_link_sd(parent, target, link_name); kernfs_put(parent); return error; }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki6689.19%133.33%
tejun heotejun heo810.81%266.67%
Total74100.00%3100.00%

EXPORT_SYMBOL_GPL(sysfs_add_link_to_group); /** * sysfs_remove_link_from_group - remove a symlink from an attribute group. * @kobj: The kobject containing the group. * @group_name: The name of the group. * @link_name: The name of the symlink to remove. */
void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, const char *link_name) { struct kernfs_node *parent; parent = kernfs_find_and_get(kobj->sd, group_name); if (parent) { kernfs_remove_by_name(parent, link_name); kernfs_put(parent); } }

Contributors

PersonTokensPropCommitsCommitProp
rafael j. wysockirafael j. wysocki4583.33%125.00%
tejun heotejun heo916.67%375.00%
Total54100.00%4100.00%

EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); /** * __compat_only_sysfs_link_entry_to_kobj - add a symlink to a kobject pointing * to a group or an attribute * @kobj: The kobject containing the group. * @target_kobj: The target kobject. * @target_name: The name of the target group or attribute. */
int __compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj, struct kobject *target_kobj, const char *target_name) { struct kernfs_node *target; struct kernfs_node *entry; struct kernfs_node *link; /* * We don't own @target_kobj and it may be removed at any time. * Synchronize using sysfs_symlink_target_lock. See sysfs_remove_dir() * for details. */ spin_lock(&sysfs_symlink_target_lock); target = target_kobj->sd; if (target) kernfs_get(target); spin_unlock(&sysfs_symlink_target_lock); if (!target) return -ENOENT; entry = kernfs_find_and_get(target_kobj->sd, target_name); if (!entry) { kernfs_put(target); return -ENOENT; } link = kernfs_create_link(kobj->sd, target_name, entry); if (IS_ERR(link) && PTR_ERR(link) == -EEXIST) sysfs_warn_dup(kobj->sd, target_name); kernfs_put(entry); kernfs_put(target); return IS_ERR(link) ? PTR_ERR(link) : 0; }

Contributors

PersonTokensPropCommitsCommitProp
jarkko sakkinenjarkko sakkinen159100.00%1100.00%
Total159100.00%1100.00%

EXPORT_SYMBOL_GPL(__compat_only_sysfs_link_entry_to_kobj);

Overall Contributors

PersonTokensPropCommitsCommitProp
greg kroah-hartmangreg kroah-hartman30119.41%717.50%
patrick mochelpatrick mochel25216.25%410.00%
alan sternalan stern20213.02%12.50%
jarkko sakkinenjarkko sakkinen16510.64%12.50%
james bottomleyjames bottomley15910.25%25.00%
tejun heotejun heo1398.96%820.00%
rafael j. wysockirafael j. wysocki1237.93%12.50%
emilio lopezemilio lopez764.90%12.50%
bruno premontbruno premont291.87%12.50%
vivien didelotvivien didelot291.87%12.50%
cody p schafercody p schafer241.55%12.50%
andrew mortonandrew morton161.03%25.00%
robert abelrobert abel80.52%12.50%
guenter roeckguenter roeck60.39%12.50%
oliver schinagloliver schinagl60.39%12.50%
antonio ospiteantonio ospite30.19%12.50%
johannes thumshirnjohannes thumshirn30.19%12.50%
arjan van de venarjan van de ven30.19%12.50%
christoph hellwigchristoph hellwig30.19%12.50%
james morrisjames morris20.13%12.50%
al viroal viro10.06%12.50%
javi merinojavi merino10.06%12.50%
Total1551100.00%40100.00%
Directory: fs/sysfs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.