aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-09-11 22:29:05 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 18:30:22 -0400
commite34ff4906199d2ebd248ae897ae34f52bea151c9 (patch)
tree2ae9507f68e08651b3f960de51b77a1d84e21453
parent58292cbe6669d74498a5f08db13e57cb3bcfb81d (diff)
sysfs: remove ktype->namespace() invocations in directory code
For some unrecognizable reason, namespace information is communicated to sysfs through ktype->namespace() callback when there's *nothing* which needs the use of a callback. The whole sequence of operations is completely synchronous and sysfs operations simply end up calling back into the layer which just invoked it in order to find out the namespace information, which is completely backwards, obfuscates what's going on and unnecessarily tangles two separate layers. This patch doesn't remove ktype->namespace() but shifts its handling to kobject layer. We probably want to get rid of the callback in the long term. This patch adds an explicit param to sysfs_{create|rename|move}_dir() and renames them to sysfs_{create|rename|move}_dir_ns(), respectively. ktype->namespace() invocations are moved to the calling sites of the above functions. A new helper kboject_namespace() is introduced which directly tests kobj_ns_type_operations->type which should give the same result as testing sysfs_fs_type(parent_sd) and returns @kobj's namespace tag as necessary. kobject_namespace() is extern as it will be used from another file in the following patches. This patch should be an equivalent conversion without any functional difference. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Kay Sievers <kay@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/sysfs/dir.c23
-rw-r--r--include/linux/kobject.h1
-rw-r--r--include/linux/sysfs.h20
-rw-r--r--lib/kobject.c28
4 files changed, 45 insertions, 27 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 834c64cb7f88..878ac3afe1b8 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -730,14 +730,14 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
730} 730}
731 731
732/** 732/**
733 * sysfs_create_dir - create a directory for an object. 733 * sysfs_create_dir_ns - create a directory for an object with a namespace tag
734 * @kobj: object we're creating directory for. 734 * @kobj: object we're creating directory for
735 * @ns: the namespace tag to use
735 */ 736 */
736int sysfs_create_dir(struct kobject *kobj) 737int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
737{ 738{
738 enum kobj_ns_type type; 739 enum kobj_ns_type type;
739 struct sysfs_dirent *parent_sd, *sd; 740 struct sysfs_dirent *parent_sd, *sd;
740 const void *ns = NULL;
741 int error = 0; 741 int error = 0;
742 742
743 BUG_ON(!kobj); 743 BUG_ON(!kobj);
@@ -750,8 +750,6 @@ int sysfs_create_dir(struct kobject *kobj)
750 if (!parent_sd) 750 if (!parent_sd)
751 return -ENOENT; 751 return -ENOENT;
752 752
753 if (sysfs_ns_type(parent_sd))
754 ns = kobj->ktype->namespace(kobj);
755 type = sysfs_read_ns_type(kobj); 753 type = sysfs_read_ns_type(kobj);
756 754
757 error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd); 755 error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
@@ -909,26 +907,21 @@ int sysfs_rename(struct sysfs_dirent *sd,
909 return error; 907 return error;
910} 908}
911 909
912int sysfs_rename_dir(struct kobject *kobj, const char *new_name) 910int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
911 const void *new_ns)
913{ 912{
914 struct sysfs_dirent *parent_sd = kobj->sd->s_parent; 913 struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
915 const void *new_ns = NULL;
916
917 if (sysfs_ns_type(parent_sd))
918 new_ns = kobj->ktype->namespace(kobj);
919 914
920 return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name); 915 return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
921} 916}
922 917
923int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) 918int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
919 const void *new_ns)
924{ 920{
925 struct sysfs_dirent *sd = kobj->sd; 921 struct sysfs_dirent *sd = kobj->sd;
926 struct sysfs_dirent *new_parent_sd; 922 struct sysfs_dirent *new_parent_sd;
927 const void *new_ns = NULL;
928 923
929 BUG_ON(!sd->s_parent); 924 BUG_ON(!sd->s_parent);
930 if (sysfs_ns_type(sd->s_parent))
931 new_ns = kobj->ktype->namespace(kobj);
932 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? 925 new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
933 new_parent_kobj->sd : &sysfs_root; 926 new_parent_kobj->sd : &sysfs_root;
934 927
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index de6dcbcc6ef7..e7ba650086ce 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -107,6 +107,7 @@ extern int __must_check kobject_move(struct kobject *, struct kobject *);
107extern struct kobject *kobject_get(struct kobject *kobj); 107extern struct kobject *kobject_get(struct kobject *kobj);
108extern void kobject_put(struct kobject *kobj); 108extern void kobject_put(struct kobject *kobj);
109 109
110extern const void *kobject_namespace(struct kobject *kobj);
110extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); 111extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
111 112
112struct kobj_type { 113struct kobj_type {
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 82f7fac78e77..7f56bad3be82 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -182,11 +182,13 @@ struct sysfs_dirent;
182int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), 182int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
183 void *data, struct module *owner); 183 void *data, struct module *owner);
184 184
185int __must_check sysfs_create_dir(struct kobject *kobj); 185int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
186void sysfs_remove_dir(struct kobject *kobj); 186void sysfs_remove_dir(struct kobject *kobj);
187int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name); 187int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
188int __must_check sysfs_move_dir(struct kobject *kobj, 188 const void *new_ns);
189 struct kobject *new_parent_kobj); 189int __must_check sysfs_move_dir_ns(struct kobject *kobj,
190 struct kobject *new_parent_kobj,
191 const void *new_ns);
190 192
191int __must_check sysfs_create_file_ns(struct kobject *kobj, 193int __must_check sysfs_create_file_ns(struct kobject *kobj,
192 const struct attribute *attr, 194 const struct attribute *attr,
@@ -258,7 +260,7 @@ static inline int sysfs_schedule_callback(struct kobject *kobj,
258 return -ENOSYS; 260 return -ENOSYS;
259} 261}
260 262
261static inline int sysfs_create_dir(struct kobject *kobj) 263static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
262{ 264{
263 return 0; 265 return 0;
264} 266}
@@ -267,13 +269,15 @@ static inline void sysfs_remove_dir(struct kobject *kobj)
267{ 269{
268} 270}
269 271
270static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name) 272static inline int sysfs_rename_dir_ns(struct kobject *kobj,
273 const char *new_name, const void *new_ns)
271{ 274{
272 return 0; 275 return 0;
273} 276}
274 277
275static inline int sysfs_move_dir(struct kobject *kobj, 278static inline int sysfs_move_dir_ns(struct kobject *kobj,
276 struct kobject *new_parent_kobj) 279 struct kobject *new_parent_kobj,
280 const void *new_ns)
277{ 281{
278 return 0; 282 return 0;
279} 283}
diff --git a/lib/kobject.c b/lib/kobject.c
index 962175134702..85fb3a161b21 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -18,6 +18,24 @@
18#include <linux/stat.h> 18#include <linux/stat.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20 20
21/**
22 * kobject_namespace - return @kobj's namespace tag
23 * @kobj: kobject in question
24 *
25 * Returns namespace tag of @kobj if its parent has namespace ops enabled
26 * and thus @kobj should have a namespace tag associated with it. Returns
27 * %NULL otherwise.
28 */
29const void *kobject_namespace(struct kobject *kobj)
30{
31 const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
32
33 if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
34 return NULL;
35
36 return kobj->ktype->namespace(kobj);
37}
38
21/* 39/*
22 * populate_dir - populate directory with attributes. 40 * populate_dir - populate directory with attributes.
23 * @kobj: object we're working on. 41 * @kobj: object we're working on.
@@ -46,8 +64,9 @@ static int populate_dir(struct kobject *kobj)
46 64
47static int create_dir(struct kobject *kobj) 65static int create_dir(struct kobject *kobj)
48{ 66{
49 int error = 0; 67 int error;
50 error = sysfs_create_dir(kobj); 68
69 error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
51 if (!error) { 70 if (!error) {
52 error = populate_dir(kobj); 71 error = populate_dir(kobj);
53 if (error) 72 if (error)
@@ -428,7 +447,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
428 goto out; 447 goto out;
429 } 448 }
430 449
431 error = sysfs_rename_dir(kobj, new_name); 450 error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
432 if (error) 451 if (error)
433 goto out; 452 goto out;
434 453
@@ -472,6 +491,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
472 if (kobj->kset) 491 if (kobj->kset)
473 new_parent = kobject_get(&kobj->kset->kobj); 492 new_parent = kobject_get(&kobj->kset->kobj);
474 } 493 }
494
475 /* old object path */ 495 /* old object path */
476 devpath = kobject_get_path(kobj, GFP_KERNEL); 496 devpath = kobject_get_path(kobj, GFP_KERNEL);
477 if (!devpath) { 497 if (!devpath) {
@@ -486,7 +506,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
486 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); 506 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
487 envp[0] = devpath_string; 507 envp[0] = devpath_string;
488 envp[1] = NULL; 508 envp[1] = NULL;
489 error = sysfs_move_dir(kobj, new_parent); 509 error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
490 if (error) 510 if (error)
491 goto out; 511 goto out;
492 old_parent = kobj->parent; 512 old_parent = kobj->parent;