From c84a3b27798dfce928b867fa1c9f3c3fd66f0a31 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 23 Nov 2013 18:01:46 -0500 Subject: sysfs: drop kobj_ns_type handling, take #2 The way namespace tags are implemented in sysfs is more complicated than necessary. As each tag is a pointer value and required to be non-NULL under a namespace enabled parent, there's no need to record separately what type each tag is. If multiple namespace types are needed, which currently aren't, we can simply compare the tag to a set of allowed tags in the superblock assuming that the tags, being pointers, won't have the same value across multiple types. This patch rips out kobj_ns_type handling from sysfs. sysfs now has an enable switch to turn on namespace under a node. If enabled, all children are required to have non-NULL namespace tags and filtered against the super_block's tag. kobject namespace determination is now performed in lib/kobject.c::create_dir() making sysfs_read_ns_type() unnecessary. The sanity checks are also moved. create_dir() is restructured to ease such addition. This removes most kobject namespace knowledge from sysfs proper which will enable proper separation and layering of sysfs. This is the second try. The first one was cb26a311578e ("sysfs: drop kobj_ns_type handling") which tried to automatically enable namespace if there are children with non-NULL namespace tags; however, it was broken for symlinks as they should inherit the target's tag iff namespace is enabled in the parent. This led to namespace filtering enabled incorrectly for wireless net class devices through phy80211 symlinks and thus network configuration failure. a1212d278c05 ("Revert "sysfs: drop kobj_ns_type handling"") reverted the commit. This shouldn't introduce any behavior changes, for real. v2: Dummy implementation of sysfs_enable_ns() for !CONFIG_SYSFS was missing and caused build failure. Reported by kbuild test robot. Signed-off-by: Tejun Heo Reported-by: Linus Torvalds Cc: Eric W. Biederman Cc: Kay Sievers Cc: Greg Kroah-Hartman Cc: kbuild test robot Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 3ae3f1bf1a09..c660363fdaea 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -28,7 +28,6 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, struct sysfs_dirent *target_sd = NULL; struct sysfs_dirent *sd = NULL; struct sysfs_addrm_cxt acxt; - enum kobj_ns_type ns_type; int error; BUG_ON(!name || !parent_sd); @@ -52,29 +51,16 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, if (!sd) goto out_put; - ns_type = sysfs_ns_type(parent_sd); - if (ns_type) + if (parent_sd->s_flags & SYSFS_FLAG_NS) sd->s_ns = target_sd->s_ns; sd->s_symlink.target_sd = target_sd; target_sd = NULL; /* reference is now owned by the symlink */ sysfs_addrm_start(&acxt); - /* Symlinks must be between directories with the same ns_type */ - if (!ns_type || - (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent))) { - if (warn) - error = sysfs_add_one(&acxt, sd, parent_sd); - else - error = __sysfs_add_one(&acxt, sd, parent_sd); - } else { - error = -EINVAL; - WARN(1, KERN_WARNING - "sysfs: symlink across ns_types %s/%s -> %s/%s\n", - parent_sd->s_name, - sd->s_name, - sd->s_symlink.target_sd->s_parent->s_name, - sd->s_symlink.target_sd->s_name); - } + if (warn) + error = sysfs_add_one(&acxt, sd, parent_sd); + else + error = __sysfs_add_one(&acxt, sd, parent_sd); sysfs_addrm_finish(&acxt); if (error) @@ -164,7 +150,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, * sysfs_remove_dir() for details. */ spin_lock(&sysfs_symlink_target_lock); - if (targ->sd && sysfs_ns_type(kobj->sd)) + if (targ->sd && (kobj->sd->s_flags & SYSFS_FLAG_NS)) ns = targ->sd->s_ns; spin_unlock(&sysfs_symlink_target_lock); sysfs_hash_and_remove(kobj->sd, name, ns); -- cgit v1.2.3 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/symlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index c660363fdaea..71583fc8100a 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -153,7 +153,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, if (targ->sd && (kobj->sd->s_flags & SYSFS_FLAG_NS)) ns = targ->sd->s_ns; spin_unlock(&sysfs_symlink_target_lock); - sysfs_hash_and_remove(kobj->sd, name, ns); + kernfs_remove_by_name_ns(kobj->sd, name, ns); } /** @@ -170,7 +170,7 @@ void sysfs_remove_link(struct kobject *kobj, const char *name) else parent_sd = kobj->sd; - sysfs_hash_and_remove(parent_sd, name, NULL); + kernfs_remove_by_name(parent_sd, name); } EXPORT_SYMBOL_GPL(sysfs_remove_link); -- cgit v1.2.3 From 5d0e26bb59a680a5d97db5b6629941603e8de229 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 23 Nov 2013 17:21:50 -0500 Subject: sysfs, kernfs: introduce kernfs_create_link() Separate out kernfs symlink interface - kernfs_create_link() - which takes and returns sysfs_dirents, from sysfs_do_create_link_sd(). sysfs_do_create_link_sd() now just determines the parent and target sysfs_dirents and invokes the new interface and handles dup warning. This patch doesn't introduce behavior changes. v2: Dummy implementation for !CONFIG_SYSFS updated to return -ENOSYS. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 76 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 71583fc8100a..41138e91947a 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -21,14 +21,48 @@ #include "sysfs.h" +/** + * kernfs_create_link - create a symlink + * @parent: directory to create the symlink in + * @name: name of the symlink + * @target: target node for the symlink to point to + * + * Returns the created node on success, ERR_PTR() value on error. + */ +struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, + const char *name, + struct sysfs_dirent *target) +{ + struct sysfs_dirent *sd; + struct sysfs_addrm_cxt acxt; + int error; + + sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); + if (!sd) + return ERR_PTR(-ENOMEM); + + if (parent->s_flags & SYSFS_FLAG_NS) + sd->s_ns = target->s_ns; + sd->s_symlink.target_sd = target; + sysfs_get(target); /* ref owned by symlink */ + + sysfs_addrm_start(&acxt); + error = __sysfs_add_one(&acxt, sd, parent); + sysfs_addrm_finish(&acxt); + + if (!error) + return sd; + + sysfs_put(sd); + return ERR_PTR(error); +} + + static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, struct kobject *target, const char *name, int warn) { - struct sysfs_dirent *target_sd = NULL; - struct sysfs_dirent *sd = NULL; - struct sysfs_addrm_cxt acxt; - int error; + struct sysfs_dirent *sd, *target_sd = NULL; BUG_ON(!name || !parent_sd); @@ -42,36 +76,18 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, target_sd = sysfs_get(target->sd); spin_unlock(&sysfs_symlink_target_lock); - error = -ENOENT; if (!target_sd) - goto out_put; + return -ENOENT; - error = -ENOMEM; - sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); - if (!sd) - goto out_put; - - if (parent_sd->s_flags & SYSFS_FLAG_NS) - sd->s_ns = target_sd->s_ns; - sd->s_symlink.target_sd = target_sd; - target_sd = NULL; /* reference is now owned by the symlink */ - - sysfs_addrm_start(&acxt); - if (warn) - error = sysfs_add_one(&acxt, sd, parent_sd); - else - error = __sysfs_add_one(&acxt, sd, parent_sd); - sysfs_addrm_finish(&acxt); - - if (error) - goto out_put; + sd = kernfs_create_link(parent_sd, name, target_sd); + sysfs_put(target_sd); - return 0; + if (!IS_ERR(sd)) + return 0; - out_put: - sysfs_put(target_sd); - sysfs_put(sd); - return error; + if (warn && PTR_ERR(sd) == -EEXIST) + sysfs_warn_dup(parent_sd, name); + return PTR_ERR(sd); } /** -- cgit v1.2.3 From 890ece160c6465b49c42975d529c3481d89da8f5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 23 Nov 2013 17:21:51 -0500 Subject: sysfs, kernfs: introduce kernfs_rename[_ns]() Introduce kernfs rename interface, krenfs_rename[_ns](). This is just rename of sysfs_rename(). No functional changes. Function comment is added to kernfs_rename_ns() and @new_parent_sd is renamed to @new_parent for consistency with other kernfs interfaces. v2: Dummy implementation for !CONFIG_SYSFS updated to return -ENOSYS. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 41138e91947a..0922c53bd757 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -226,7 +226,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, if (sd->s_symlink.target_sd->s_dir.kobj != targ) goto out; - result = sysfs_rename(sd, parent_sd, new, new_ns); + result = kernfs_rename_ns(sd, parent_sd, new, new_ns); out: sysfs_put(sd); -- cgit v1.2.3 From 7c6e2d362c19f01e6d6c8be59d83a89722032884 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:14 -0500 Subject: sysfs, kernfs: replace sysfs_dirent->s_dir.kobj and ->s_attr.[bin_]attr with ->priv A directory sysfs_dirent points to the associated kobj. A regular or bin file points to the associated [bin_]attribute. This patch replaces sysfs_dirent->s_dir.kobj and ->s_attr.[bin_]attr with void * ->priv. This is to prepare for kernfs interface so that sysfs can specify the private data in the same way for directories and files. This lower debuggability but not by much - the whole thing was overlaid in a union anyway. If debuggability becomes an issue, we can later add ->priv accessors which explicitly check for the sysfs_dirent type and performs casting. This patch doesn't introduce any behavior difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 0922c53bd757..352fbbbc0551 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -223,7 +223,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, result = -EINVAL; if (sysfs_type(sd) != SYSFS_KOBJ_LINK) goto out; - if (sd->s_symlink.target_sd->s_dir.kobj != targ) + if (sd->s_symlink.target_sd->priv != targ) goto out; result = kernfs_rename_ns(sd, parent_sd, new, new_ns); -- cgit v1.2.3 From 2d0cfbec2a95c16818960fda1dfa815fd1a62070 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:25 -0500 Subject: sysfs, kernfs: remove sysfs_add_one() sysfs_add_one() is a wrapper around __sysfs_add_one() which prints out duplicate name warning if __sysfs_add_one() fails with -EEXIST. The previous kernfs conversions moved all dup warnings to sysfs interface functions and sysfs_add_one() doesn't have any user left. Remove sysfs_add_one() and update __sysfs_add_one() to take its name. This patch doesn't make any functional changes. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 352fbbbc0551..76efeab6db4e 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -47,7 +47,7 @@ struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, sysfs_get(target); /* ref owned by symlink */ sysfs_addrm_start(&acxt); - error = __sysfs_add_one(&acxt, sd, parent); + error = sysfs_add_one(&acxt, sd, parent); sysfs_addrm_finish(&acxt); if (!error) -- 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/symlink.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 76efeab6db4e..b137aa3a486c 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -44,7 +44,7 @@ struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, if (parent->s_flags & SYSFS_FLAG_NS) sd->s_ns = target->s_ns; sd->s_symlink.target_sd = target; - sysfs_get(target); /* ref owned by symlink */ + kernfs_get(target); /* ref owned by symlink */ sysfs_addrm_start(&acxt); error = sysfs_add_one(&acxt, sd, parent); @@ -53,7 +53,7 @@ struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, if (!error) return sd; - sysfs_put(sd); + kernfs_put(sd); return ERR_PTR(error); } @@ -72,15 +72,17 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, * sysfs_remove_dir() for details. */ spin_lock(&sysfs_symlink_target_lock); - if (target->sd) - target_sd = sysfs_get(target->sd); + if (target->sd) { + target_sd = target->sd; + kernfs_get(target_sd); + } spin_unlock(&sysfs_symlink_target_lock); if (!target_sd) return -ENOENT; sd = kernfs_create_link(parent_sd, name, target_sd); - sysfs_put(target_sd); + kernfs_put(target_sd); if (!IS_ERR(sd)) return 0; @@ -216,7 +218,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, old_ns = targ->sd->s_ns; result = -ENOENT; - sd = sysfs_get_dirent_ns(parent_sd, old, old_ns); + sd = kernfs_find_and_get_ns(parent_sd, old, old_ns); if (!sd) goto out; @@ -229,7 +231,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, result = kernfs_rename_ns(sd, parent_sd, new, new_ns); out: - sysfs_put(sd); + kernfs_put(sd); return result; } EXPORT_SYMBOL_GPL(sysfs_rename_link_ns); -- cgit v1.2.3 From 2072f1afddfe9fa00c1c0c79f8986707324ec65b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:35 -0500 Subject: sysfs, kernfs: move symlink core code to fs/kernfs/symlink.c Move core symlink code to fs/kernfs/symlink.c. fs/sysfs/symlink.c now only contains sysfs wrappers around kernfs interfaces. The respective declarations in fs/sysfs/sysfs.h are moved to fs/kernfs/kernfs-internal.h. This is pure relocation. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 137 ----------------------------------------------------- 1 file changed, 137 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index b137aa3a486c..6797c9c2e43a 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -11,53 +11,13 @@ */ #include -#include -#include #include #include -#include #include #include #include "sysfs.h" -/** - * kernfs_create_link - create a symlink - * @parent: directory to create the symlink in - * @name: name of the symlink - * @target: target node for the symlink to point to - * - * Returns the created node on success, ERR_PTR() value on error. - */ -struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, - const char *name, - struct sysfs_dirent *target) -{ - struct sysfs_dirent *sd; - struct sysfs_addrm_cxt acxt; - int error; - - sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); - if (!sd) - return ERR_PTR(-ENOMEM); - - if (parent->s_flags & SYSFS_FLAG_NS) - sd->s_ns = target->s_ns; - sd->s_symlink.target_sd = target; - kernfs_get(target); /* ref owned by symlink */ - - sysfs_addrm_start(&acxt); - error = sysfs_add_one(&acxt, sd, parent); - sysfs_addrm_finish(&acxt); - - if (!error) - return sd; - - kernfs_put(sd); - return ERR_PTR(error); -} - - static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, struct kobject *target, const char *name, int warn) @@ -235,100 +195,3 @@ out: return result; } EXPORT_SYMBOL_GPL(sysfs_rename_link_ns); - -static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, - struct sysfs_dirent *target_sd, char *path) -{ - struct sysfs_dirent *base, *sd; - char *s = path; - int len = 0; - - /* go up to the root, stop at the base */ - base = parent_sd; - while (base->s_parent) { - sd = target_sd->s_parent; - while (sd->s_parent && base != sd) - sd = sd->s_parent; - - if (base == sd) - break; - - strcpy(s, "../"); - s += 3; - base = base->s_parent; - } - - /* determine end of target string for reverse fillup */ - sd = target_sd; - while (sd->s_parent && sd != base) { - len += strlen(sd->s_name) + 1; - sd = sd->s_parent; - } - - /* check limits */ - if (len < 2) - return -EINVAL; - len--; - if ((s - path) + len > PATH_MAX) - return -ENAMETOOLONG; - - /* reverse fillup of target string from target to base */ - sd = target_sd; - while (sd->s_parent && sd != base) { - int slen = strlen(sd->s_name); - - len -= slen; - strncpy(s + len, sd->s_name, slen); - if (len) - s[--len] = '/'; - - sd = sd->s_parent; - } - - return 0; -} - -static int sysfs_getlink(struct dentry *dentry, char *path) -{ - struct sysfs_dirent *sd = dentry->d_fsdata; - struct sysfs_dirent *parent_sd = sd->s_parent; - struct sysfs_dirent *target_sd = sd->s_symlink.target_sd; - int error; - - mutex_lock(&sysfs_mutex); - error = sysfs_get_target_path(parent_sd, target_sd, path); - mutex_unlock(&sysfs_mutex); - - return error; -} - -static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) -{ - int error = -ENOMEM; - unsigned long page = get_zeroed_page(GFP_KERNEL); - if (page) { - error = sysfs_getlink(dentry, (char *) page); - if (error < 0) - free_page((unsigned long)page); - } - nd_set_link(nd, error ? ERR_PTR(error) : (char *)page); - return NULL; -} - -static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, - void *cookie) -{ - char *page = nd_get_link(nd); - if (!IS_ERR(page)) - free_page((unsigned long)page); -} - -const struct inode_operations sysfs_symlink_inode_operations = { - .setxattr = sysfs_setxattr, - .readlink = generic_readlink, - .follow_link = sysfs_follow_link, - .put_link = sysfs_put_link, - .setattr = sysfs_setattr, - .getattr = sysfs_getattr, - .permission = sysfs_permission, -}; -- cgit v1.2.3 From 061447a496b915f1dc8f8c645c6825f856d2bbac Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 28 Nov 2013 14:54:39 -0500 Subject: sysfs, kernfs: introduce sysfs_root_sd Currently, it's assumed that there's a single kernfs hierarchy in the system anchored at sysfs_root which is defined as a global struct. To allow other users of kernfs, this will be made dynamic. Introduce a new global variable sysfs_root_sd which points to &sysfs_root and convert all &sysfs_root users. This patch doesn't introduce any behavior difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 6797c9c2e43a..62f0e014ec48 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -70,7 +70,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, struct sysfs_dirent *parent_sd = NULL; if (!kobj) - parent_sd = &sysfs_root; + parent_sd = sysfs_root_sd; else parent_sd = kobj->sd; @@ -144,7 +144,7 @@ void sysfs_remove_link(struct kobject *kobj, const char *name) struct sysfs_dirent *parent_sd = NULL; if (!kobj) - parent_sd = &sysfs_root; + parent_sd = sysfs_root_sd; else parent_sd = kobj->sd; @@ -170,7 +170,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, int result; if (!kobj) - parent_sd = &sysfs_root; + parent_sd = sysfs_root_sd; else parent_sd = kobj->sd; -- cgit v1.2.3 From ac9bba031001704a2339713cc12148857eccc5e5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 29 Nov 2013 17:19:09 -0500 Subject: sysfs, kernfs: implement kernfs_ns_enabled() fs/sysfs/symlink.c::sysfs_delete_link() tests @sd->s_flags for SYSFS_FLAG_NS. Let's add kernfs_ns_enabled() so that sysfs doesn't have to test sysfs_dirent flag directly. This makes things tidier for kernfs proper too. This is purely cosmetic. v2: To avoid possible NULL deref, use noop dummy implementation which always returns false when !CONFIG_SYSFS. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 62f0e014ec48..1b8c9ed8511a 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -128,7 +128,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, * sysfs_remove_dir() for details. */ spin_lock(&sysfs_symlink_target_lock); - if (targ->sd && (kobj->sd->s_flags & SYSFS_FLAG_NS)) + if (targ->sd && kernfs_ns_enabled(kobj->sd)) ns = targ->sd->s_ns; spin_unlock(&sysfs_symlink_target_lock); kernfs_remove_by_name_ns(kobj->sd, name, ns); -- 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/symlink.c | 72 +++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 1b8c9ed8511a..4ed3d49ad279 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -18,66 +18,66 @@ #include "sysfs.h" -static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, - struct kobject *target, +static int sysfs_do_create_link_sd(struct kernfs_node *parent, + struct kobject *target_kobj, const char *name, int warn) { - struct sysfs_dirent *sd, *target_sd = NULL; + struct kernfs_node *kn, *target = NULL; - BUG_ON(!name || !parent_sd); + BUG_ON(!name || !parent); /* - * We don't own @target and it may be removed at any time. + * 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); - if (target->sd) { - target_sd = target->sd; - kernfs_get(target_sd); + if (target_kobj->sd) { + target = target_kobj->sd; + kernfs_get(target); } spin_unlock(&sysfs_symlink_target_lock); - if (!target_sd) + if (!target) return -ENOENT; - sd = kernfs_create_link(parent_sd, name, target_sd); - kernfs_put(target_sd); + kn = kernfs_create_link(parent, name, target); + kernfs_put(target); - if (!IS_ERR(sd)) + if (!IS_ERR(kn)) return 0; - if (warn && PTR_ERR(sd) == -EEXIST) - sysfs_warn_dup(parent_sd, name); - return PTR_ERR(sd); + if (warn && PTR_ERR(kn) == -EEXIST) + sysfs_warn_dup(parent, name); + return PTR_ERR(kn); } /** * sysfs_create_link_sd - create symlink to a given object. - * @sd: directory we're creating the link in. + * @kn: directory we're creating the link in. * @target: object we're pointing to. * @name: name of the symlink. */ -int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target, +int sysfs_create_link_sd(struct kernfs_node *kn, struct kobject *target, const char *name) { - return sysfs_do_create_link_sd(sd, target, name, 1); + return sysfs_do_create_link_sd(kn, target, name, 1); } static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, const char *name, int warn) { - struct sysfs_dirent *parent_sd = NULL; + struct kernfs_node *parent = NULL; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; - if (!parent_sd) + if (!parent) return -EFAULT; - return sysfs_do_create_link_sd(parent_sd, target, name, warn); + return sysfs_do_create_link_sd(parent, target, name, warn); } /** @@ -141,14 +141,14 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, */ void sysfs_remove_link(struct kobject *kobj, const char *name) { - struct sysfs_dirent *parent_sd = NULL; + struct kernfs_node *parent = NULL; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; - kernfs_remove_by_name(parent_sd, name); + kernfs_remove_by_name(parent, name); } EXPORT_SYMBOL_GPL(sysfs_remove_link); @@ -165,33 +165,33 @@ EXPORT_SYMBOL_GPL(sysfs_remove_link); int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, const char *old, const char *new, const void *new_ns) { - struct sysfs_dirent *parent_sd, *sd = NULL; + struct kernfs_node *parent, *kn = NULL; const void *old_ns = NULL; int result; if (!kobj) - parent_sd = sysfs_root_sd; + parent = sysfs_root_kn; else - parent_sd = kobj->sd; + parent = kobj->sd; if (targ->sd) old_ns = targ->sd->s_ns; result = -ENOENT; - sd = kernfs_find_and_get_ns(parent_sd, old, old_ns); - if (!sd) + kn = kernfs_find_and_get_ns(parent, old, old_ns); + if (!kn) goto out; result = -EINVAL; - if (sysfs_type(sd) != SYSFS_KOBJ_LINK) + if (sysfs_type(kn) != SYSFS_KOBJ_LINK) goto out; - if (sd->s_symlink.target_sd->priv != targ) + if (kn->s_symlink.target_kn->priv != targ) goto out; - result = kernfs_rename_ns(sd, parent_sd, new, new_ns); + result = kernfs_rename_ns(kn, parent, new, new_ns); out: - kernfs_put(sd); + kernfs_put(kn); return result; } EXPORT_SYMBOL_GPL(sysfs_rename_link_ns); -- cgit v1.2.3 From adc5e8b58f4886d45f79f4ff41a09001a76a6b12 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:54 -0500 Subject: kernfs: drop s_ prefix from kernfs_node members 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. s_ prefix for kernfs members is used inconsistently and a misnomer now. It's not like kernfs_node is used widely across the kernel making the ability to grep for the members particularly useful. Let's just drop the prefix. This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 4ed3d49ad279..0d48ea911508 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -129,7 +129,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, */ spin_lock(&sysfs_symlink_target_lock); if (targ->sd && kernfs_ns_enabled(kobj->sd)) - ns = targ->sd->s_ns; + ns = targ->sd->ns; spin_unlock(&sysfs_symlink_target_lock); kernfs_remove_by_name_ns(kobj->sd, name, ns); } @@ -175,7 +175,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, parent = kobj->sd; if (targ->sd) - old_ns = targ->sd->s_ns; + old_ns = targ->sd->ns; result = -ENOENT; kn = kernfs_find_and_get_ns(parent, old, old_ns); @@ -185,7 +185,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, result = -EINVAL; if (sysfs_type(kn) != SYSFS_KOBJ_LINK) goto out; - if (kn->s_symlink.target_kn->priv != targ) + if (kn->symlink.target_kn->priv != targ) goto out; result = kernfs_rename_ns(kn, parent, new, new_ns); -- cgit v1.2.3 From df23fc39bce03bb26e63bea57fc5f5bf6882d74b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 11 Dec 2013 14:11:56 -0500 Subject: kernfs: s/sysfs/kernfs/ in constants 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_DIR/KERNFS_DIR/ * s/SYSFS_KOBJ_ATTR/KERNFS_FILE/ * s/SYSFS_KOBJ_LINK/KERNFS_LINK/ * s/SYSFS_{TYPE_FLAGS}/KERNFS_{TYPE_FLAGS}/ * s/SYSFS_FLAG_{FLAG}/KERNFS_{FLAG}/ * s/sysfs_type()/kernfs_type()/ * s/SD_DEACTIVATED_BIAS/KN_DEACTIVATED_BIAS/ This patch is strictly rename only and doesn't introduce any functional difference. Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/symlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/sysfs/symlink.c') diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 0d48ea911508..aecb15f84557 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c @@ -183,7 +183,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, goto out; result = -EINVAL; - if (sysfs_type(kn) != SYSFS_KOBJ_LINK) + if (kernfs_type(kn) != KERNFS_LINK) goto out; if (kn->symlink.target_kn->priv != targ) goto out; -- cgit v1.2.3