From 879f40d193bb3c6c13930e88e3e9d5d7baf84d19 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 23 Nov 2013 17:21:49 -0500 Subject: sysfs, kernfs: introduce kernfs_remove[_by_name[_ns]]() Introduce kernfs removal interfaces - kernfs_remove() and kernfs_remove_by_name[_ns](). These are just renames of sysfs_remove() and sysfs_hash_and_remove(). No functional changes. v2: Dummy kernfs_remove_by_name_ns() for !CONFIG_SYSFS updated to return -ENOSYS instead of 0. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 1898a10e38ce..4bd997340830 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -26,7 +26,7 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, if (grp->attrs) for (attr = grp->attrs; *attr; attr++) - sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL); + kernfs_remove_by_name(dir_sd, (*attr)->name); if (grp->bin_attrs) for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) sysfs_remove_bin_file(kobj, *bin_attr); @@ -49,8 +49,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, * re-adding (if required) the file. */ if (update) - sysfs_hash_and_remove(dir_sd, (*attr)->name, - NULL); + kernfs_remove_by_name(dir_sd, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) @@ -111,7 +110,7 @@ static int internal_create_group(struct kobject *kobj, int update, error = create_files(sd, kobj, grp, update); if (error) { if (grp->name) - sysfs_remove(sd); + kernfs_remove(sd); } sysfs_put(sd); return error; @@ -219,7 +218,7 @@ void sysfs_remove_group(struct kobject *kobj, remove_files(sd, kobj, grp); if (grp->name) - sysfs_remove(sd); + kernfs_remove(sd); sysfs_put(sd); } @@ -270,7 +269,7 @@ int sysfs_merge_group(struct kobject *kobj, error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); if (error) { while (--i >= 0) - sysfs_hash_and_remove(dir_sd, (*--attr)->name, NULL); + kernfs_remove_by_name(dir_sd, (*--attr)->name); } sysfs_put(dir_sd); @@ -292,7 +291,7 @@ void sysfs_unmerge_group(struct kobject *kobj, dir_sd = sysfs_get_dirent(kobj->sd, grp->name); if (dir_sd) { for (attr = grp->attrs; *attr; ++attr) - sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL); + kernfs_remove_by_name(dir_sd, (*attr)->name); sysfs_put(dir_sd); } } @@ -335,7 +334,7 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, dir_sd = sysfs_get_dirent(kobj->sd, group_name); if (dir_sd) { - sysfs_hash_and_remove(dir_sd, link_name, NULL); + kernfs_remove_by_name(dir_sd, link_name); sysfs_put(dir_sd); } } -- cgit v1.2.3 From 93b2b8e4aa4317e3fe6414d117deb5f3c362e8bb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:15 -0500 Subject: sysfs, kernfs: introduce kernfs_create_dir[_ns]() Introduce kernfs interface to manipulate a directory which takes and returns sysfs_dirents. create_dir() is renamed to kernfs_create_dir_ns() and its argumantes and return value are updated. create_dir() usages are replaced with kernfs_create_dir_ns() and sysfs_create_subdir() usages are replaced with kernfs_create_dir(). Dup warnings are handled explicitly by sysfs users of the kernfs interface. sysfs_enable_ns() is renamed to kernfs_enable_ns(). This patch doesn't introduce any behavior changes. v2: Dummy implementation for !CONFIG_SYSFS updated to return -ENOSYS. v3: kernfs_enable_ns() added. v4: Refreshed on top of "sysfs: drop kobj_ns_type handling, take #2" so that this patch removes sysfs_enable_ns(). Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 4bd997340830..065689ddb4cb 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -101,9 +101,12 @@ static int internal_create_group(struct kobject *kobj, int update, return -EINVAL; } if (grp->name) { - error = sysfs_create_subdir(kobj, grp->name, &sd); - if (error) - return error; + sd = kernfs_create_dir(kobj->sd, grp->name, kobj); + if (IS_ERR(sd)) { + if (PTR_ERR(sd) == -EEXIST) + sysfs_warn_dup(kobj->sd, grp->name); + return PTR_ERR(sd); + } } else sd = kobj->sd; sysfs_get(sd); -- cgit v1.2.3 From a7dc66dfb4c6d6c1d7c14d5106ce467f1dbd4eba Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:23 -0500 Subject: sysfs, kernfs: remove SYSFS_KOBJ_BIN_ATTR After kernfs_ops and sysfs_dirent->s_attr.size addition, the distinction between SYSFS_KOBJ_BIN_ATTR and SYSFS_KOBJ_ATTR is only necessary while creating files to decide which kernfs_ops to use. Afterwards, they behave exactly the same. This patch removes SYSFS_KOBJ_BIN_ATTR along with sysfs_is_bin(). sysfs_add_file[_mode_ns]() are updated to take bool @is_bin instead of @type. This patch doesn't introduce any behavior changes. This completely isolates the distinction between the two sysfs file types in the sysfs layer proper. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 065689ddb4cb..9f65cd97a2d7 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -55,8 +55,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, if (!mode) continue; } - error = sysfs_add_file_mode_ns(dir_sd, *attr, - SYSFS_KOBJ_ATTR, + error = sysfs_add_file_mode_ns(dir_sd, *attr, false, (*attr)->mode | mode, NULL); if (unlikely(error)) @@ -269,7 +268,7 @@ int sysfs_merge_group(struct kobject *kobj, return -ENOENT; for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr)) - error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); + error = sysfs_add_file(dir_sd, *attr, false); if (error) { while (--i >= 0) kernfs_remove_by_name(dir_sd, (*--attr)->name); -- cgit v1.2.3 From ccf73cf336dc55bc52748205dee998d2fd4a8808 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:30 -0500 Subject: sysfs, kernfs: introduce kernfs[_find_and]_get() and kernfs_put() Introduce kernfs interface for finding, getting and putting sysfs_dirents. * sysfs_find_dirent() is renamed to kernfs_find_ns() and lockdep assertion for sysfs_mutex is added. * sysfs_get_dirent_ns() is renamed to kernfs_find_and_get(). * Macro inline dancing around __sysfs_get/put() are removed and kernfs_get/put() are made proper functions implemented in fs/sysfs/dir.c. While the conversions are mostly equivalent, there's one difference - kernfs_get() doesn't return the input param as its return value. This change is intentional. While passing through the input increases writability in some areas, it is unnecessary and has been shown to cause confusion regarding how the last ref is handled. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 9f65cd97a2d7..7177532b8f7b 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -108,13 +108,13 @@ static int internal_create_group(struct kobject *kobj, int update, } } else sd = kobj->sd; - sysfs_get(sd); + kernfs_get(sd); error = create_files(sd, kobj, grp, update); if (error) { if (grp->name) kernfs_remove(sd); } - sysfs_put(sd); + kernfs_put(sd); return error; } @@ -208,21 +208,23 @@ void sysfs_remove_group(struct kobject *kobj, struct sysfs_dirent *sd; if (grp->name) { - sd = sysfs_get_dirent(dir_sd, grp->name); + sd = kernfs_find_and_get(dir_sd, grp->name); if (!sd) { WARN(!sd, KERN_WARNING "sysfs group %p not found for kobject '%s'\n", grp, kobject_name(kobj)); return; } - } else - sd = sysfs_get(dir_sd); + } else { + sd = dir_sd; + kernfs_get(sd); + } remove_files(sd, kobj, grp); if (grp->name) kernfs_remove(sd); - sysfs_put(sd); + kernfs_put(sd); } EXPORT_SYMBOL_GPL(sysfs_remove_group); @@ -263,7 +265,7 @@ int sysfs_merge_group(struct kobject *kobj, struct attribute *const *attr; int i; - dir_sd = sysfs_get_dirent(kobj->sd, grp->name); + dir_sd = kernfs_find_and_get(kobj->sd, grp->name); if (!dir_sd) return -ENOENT; @@ -273,7 +275,7 @@ int sysfs_merge_group(struct kobject *kobj, while (--i >= 0) kernfs_remove_by_name(dir_sd, (*--attr)->name); } - sysfs_put(dir_sd); + kernfs_put(dir_sd); return error; } @@ -290,11 +292,11 @@ void sysfs_unmerge_group(struct kobject *kobj, struct sysfs_dirent *dir_sd; struct attribute *const *attr; - dir_sd = sysfs_get_dirent(kobj->sd, grp->name); + dir_sd = kernfs_find_and_get(kobj->sd, grp->name); if (dir_sd) { for (attr = grp->attrs; *attr; ++attr) kernfs_remove_by_name(dir_sd, (*attr)->name); - sysfs_put(dir_sd); + kernfs_put(dir_sd); } } EXPORT_SYMBOL_GPL(sysfs_unmerge_group); @@ -312,12 +314,12 @@ int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, struct sysfs_dirent *dir_sd; int error = 0; - dir_sd = sysfs_get_dirent(kobj->sd, group_name); + dir_sd = kernfs_find_and_get(kobj->sd, group_name); if (!dir_sd) return -ENOENT; error = sysfs_create_link_sd(dir_sd, target, link_name); - sysfs_put(dir_sd); + kernfs_put(dir_sd); return error; } @@ -334,10 +336,10 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, { struct sysfs_dirent *dir_sd; - dir_sd = sysfs_get_dirent(kobj->sd, group_name); + dir_sd = kernfs_find_and_get(kobj->sd, group_name); if (dir_sd) { kernfs_remove_by_name(dir_sd, link_name); - sysfs_put(dir_sd); + kernfs_put(dir_sd); } } EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); -- cgit v1.2.3 From 324a56e16e44baecac3ca799fd216154145c14bf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:53 -0500 Subject: kernfs: s/sysfs_dirent/kernfs_node/ and rename its friends accordingly kernfs has just been separated out from sysfs and we're already in full conflict mode. Nothing can make the situation any worse. Let's take the chance to name things properly. This patch performs the following renames. * s/sysfs_elem_dir/kernfs_elem_dir/ * s/sysfs_elem_symlink/kernfs_elem_symlink/ * s/sysfs_elem_attr/kernfs_elem_file/ * s/sysfs_dirent/kernfs_node/ * s/sd/kn/ in kernfs proper * s/parent_sd/parent/ * s/target_sd/target/ * s/dir_sd/parent/ * s/to_sysfs_dirent()/rb_to_kn()/ * misc renames of local vars when they conflict with the above Because md, mic and gpio dig into sysfs details, this patch ends up modifying them. All are sysfs_dirent renames and trivial. While we can avoid these by introducing a dummy wrapping struct sysfs_dirent around kernfs_node, given the limited usage outside kernfs and sysfs proper, I don't think such workaround is called for. This patch is strictly rename only and doesn't introduce any functional difference. - mic / gpio renames were missing. Spotted by kbuild test robot. Signed-off-by: Tejun Heo Cc: Neil Brown Cc: Linus Walleij Cc: Ashutosh Dixit Cc: kbuild test robot Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 96 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 7177532b8f7b..4d00d3996477 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -18,7 +18,7 @@ #include "sysfs.h" -static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, +static void remove_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp) { struct attribute *const *attr; @@ -26,13 +26,13 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, if (grp->attrs) for (attr = grp->attrs; *attr; attr++) - kernfs_remove_by_name(dir_sd, (*attr)->name); + kernfs_remove_by_name(parent, (*attr)->name); if (grp->bin_attrs) for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) sysfs_remove_bin_file(kobj, *bin_attr); } -static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, +static int create_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const *attr; @@ -49,20 +49,20 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, * re-adding (if required) the file. */ if (update) - kernfs_remove_by_name(dir_sd, (*attr)->name); + kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } - error = sysfs_add_file_mode_ns(dir_sd, *attr, false, + error = sysfs_add_file_mode_ns(parent, *attr, false, (*attr)->mode | mode, NULL); if (unlikely(error)) break; } if (error) { - remove_files(dir_sd, kobj, grp); + remove_files(parent, kobj, grp); goto exit; } } @@ -76,7 +76,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, break; } if (error) - remove_files(dir_sd, kobj, grp); + remove_files(parent, kobj, grp); } exit: return error; @@ -86,7 +86,7 @@ exit: static int internal_create_group(struct kobject *kobj, int update, const struct attribute_group *grp) { - struct sysfs_dirent *sd; + struct kernfs_node *kn; int error; BUG_ON(!kobj || (!update && !kobj->sd)); @@ -100,21 +100,21 @@ static int internal_create_group(struct kobject *kobj, int update, return -EINVAL; } if (grp->name) { - sd = kernfs_create_dir(kobj->sd, grp->name, kobj); - if (IS_ERR(sd)) { - if (PTR_ERR(sd) == -EEXIST) + kn = kernfs_create_dir(kobj->sd, grp->name, kobj); + if (IS_ERR(kn)) { + if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(kobj->sd, grp->name); - return PTR_ERR(sd); + return PTR_ERR(kn); } } else - sd = kobj->sd; - kernfs_get(sd); - error = create_files(sd, kobj, grp, update); + kn = kobj->sd; + kernfs_get(kn); + error = create_files(kn, kobj, grp, update); if (error) { if (grp->name) - kernfs_remove(sd); + kernfs_remove(kn); } - kernfs_put(sd); + kernfs_put(kn); return error; } @@ -204,27 +204,27 @@ EXPORT_SYMBOL_GPL(sysfs_update_group); void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd = kobj->sd; - struct sysfs_dirent *sd; + struct kernfs_node *parent = kobj->sd; + struct kernfs_node *kn; if (grp->name) { - sd = kernfs_find_and_get(dir_sd, grp->name); - if (!sd) { - WARN(!sd, KERN_WARNING + kn = kernfs_find_and_get(parent, grp->name); + if (!kn) { + WARN(!kn, KERN_WARNING "sysfs group %p not found for kobject '%s'\n", grp, kobject_name(kobj)); return; } } else { - sd = dir_sd; - kernfs_get(sd); + kn = parent; + kernfs_get(kn); } - remove_files(sd, kobj, grp); + remove_files(kn, kobj, grp); if (grp->name) - kernfs_remove(sd); + kernfs_remove(kn); - kernfs_put(sd); + kernfs_put(kn); } EXPORT_SYMBOL_GPL(sysfs_remove_group); @@ -260,22 +260,22 @@ EXPORT_SYMBOL_GPL(sysfs_remove_groups); int sysfs_merge_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; int error = 0; struct attribute *const *attr; int i; - dir_sd = kernfs_find_and_get(kobj->sd, grp->name); - if (!dir_sd) + 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(dir_sd, *attr, false); + error = sysfs_add_file(parent, *attr, false); if (error) { while (--i >= 0) - kernfs_remove_by_name(dir_sd, (*--attr)->name); + kernfs_remove_by_name(parent, (*--attr)->name); } - kernfs_put(dir_sd); + kernfs_put(parent); return error; } @@ -289,14 +289,14 @@ EXPORT_SYMBOL_GPL(sysfs_merge_group); void sysfs_unmerge_group(struct kobject *kobj, const struct attribute_group *grp) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; struct attribute *const *attr; - dir_sd = kernfs_find_and_get(kobj->sd, grp->name); - if (dir_sd) { + parent = kernfs_find_and_get(kobj->sd, grp->name); + if (parent) { for (attr = grp->attrs; *attr; ++attr) - kernfs_remove_by_name(dir_sd, (*attr)->name); - kernfs_put(dir_sd); + kernfs_remove_by_name(parent, (*attr)->name); + kernfs_put(parent); } } EXPORT_SYMBOL_GPL(sysfs_unmerge_group); @@ -311,15 +311,15 @@ EXPORT_SYMBOL_GPL(sysfs_unmerge_group); int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name, struct kobject *target, const char *link_name) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; int error = 0; - dir_sd = kernfs_find_and_get(kobj->sd, group_name); - if (!dir_sd) + parent = kernfs_find_and_get(kobj->sd, group_name); + if (!parent) return -ENOENT; - error = sysfs_create_link_sd(dir_sd, target, link_name); - kernfs_put(dir_sd); + error = sysfs_create_link_sd(parent, target, link_name); + kernfs_put(parent); return error; } @@ -334,12 +334,12 @@ EXPORT_SYMBOL_GPL(sysfs_add_link_to_group); void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name, const char *link_name) { - struct sysfs_dirent *dir_sd; + struct kernfs_node *parent; - dir_sd = kernfs_find_and_get(kobj->sd, group_name); - if (dir_sd) { - kernfs_remove_by_name(dir_sd, link_name); - kernfs_put(dir_sd); + parent = kernfs_find_and_get(kobj->sd, group_name); + if (parent) { + kernfs_remove_by_name(parent, link_name); + kernfs_put(parent); } } EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); -- cgit v1.2.3 From bb8b9d095c5c56cce99576cfef0cf9b989f7120d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 16:02:55 -0500 Subject: kernfs: add @mode to kernfs_create_dir[_ns]() sysfs assumed 0755 for all newly created directories and kernfs inherited it. This assumption is unnecessarily restrictive and inconsistent with kernfs_create_file[_ns](). This patch adds @mode parameter to kernfs_create_dir[_ns]() and update uses in sysfs accordingly. Among others, this will be useful for implementations of the planned ->mkdir() method. This patch doesn't introduce any behavior differences. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/sysfs/group.c') diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 4d00d3996477..6b579387c67a 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -100,7 +100,8 @@ static int internal_create_group(struct kobject *kobj, int update, return -EINVAL; } if (grp->name) { - kn = kernfs_create_dir(kobj->sd, grp->name, kobj); + 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); -- cgit v1.2.3