aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/core.c9
-rw-r--r--fs/sysfs/dir.c37
-rw-r--r--fs/sysfs/symlink.c41
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--include/linux/sysfs.h10
5 files changed, 84 insertions, 14 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index c05b1159023e..7d5c63c81a59 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1345,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name)
1345 if (old_class_name) { 1345 if (old_class_name) {
1346 new_class_name = make_class_name(dev->class->name, &dev->kobj); 1346 new_class_name = make_class_name(dev->class->name, &dev->kobj);
1347 if (new_class_name) { 1347 if (new_class_name) {
1348 error = sysfs_create_link(&dev->parent->kobj, 1348 error = sysfs_create_link_nowarn(&dev->parent->kobj,
1349 &dev->kobj, new_class_name); 1349 &dev->kobj,
1350 new_class_name);
1350 if (error) 1351 if (error)
1351 goto out; 1352 goto out;
1352 sysfs_remove_link(&dev->parent->kobj, old_class_name); 1353 sysfs_remove_link(&dev->parent->kobj, old_class_name);
@@ -1354,8 +1355,8 @@ int device_rename(struct device *dev, char *new_name)
1354 } 1355 }
1355#else 1356#else
1356 if (dev->class) { 1357 if (dev->class) {
1357 error = sysfs_create_link(&dev->class->p->class_subsys.kobj, 1358 error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
1358 &dev->kobj, dev->bus_id); 1359 &dev->kobj, dev->bus_id);
1359 if (error) 1360 if (error)
1360 goto out; 1361 goto out;
1361 sysfs_remove_link(&dev->class->p->class_subsys.kobj, 1362 sysfs_remove_link(&dev->class->p->class_subsys.kobj,
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 8c0e4b92574f..c1a7efb310bf 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
398} 398}
399 399
400/** 400/**
401 * sysfs_add_one - add sysfs_dirent to parent 401 * __sysfs_add_one - add sysfs_dirent to parent without warning
402 * @acxt: addrm context to use 402 * @acxt: addrm context to use
403 * @sd: sysfs_dirent to be added 403 * @sd: sysfs_dirent to be added
404 * 404 *
@@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
417 * 0 on success, -EEXIST if entry with the given name already 417 * 0 on success, -EEXIST if entry with the given name already
418 * exists. 418 * exists.
419 */ 419 */
420int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 420int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
421{ 421{
422 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) 422 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
423 return -EEXIST; 423 return -EEXIST;
@@ -435,6 +435,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
435} 435}
436 436
437/** 437/**
438 * sysfs_add_one - add sysfs_dirent to parent
439 * @acxt: addrm context to use
440 * @sd: sysfs_dirent to be added
441 *
442 * Get @acxt->parent_sd and set sd->s_parent to it and increment
443 * nlink of parent inode if @sd is a directory and link into the
444 * children list of the parent.
445 *
446 * This function should be called between calls to
447 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
448 * passed the same @acxt as passed to sysfs_addrm_start().
449 *
450 * LOCKING:
451 * Determined by sysfs_addrm_start().
452 *
453 * RETURNS:
454 * 0 on success, -EEXIST if entry with the given name already
455 * exists.
456 */
457int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
458{
459 int ret;
460
461 ret = __sysfs_add_one(acxt, sd);
462 if (ret == -EEXIST) {
463 printk(KERN_WARNING "sysfs: duplicate filename '%s' "
464 "can not be created\n", sd->s_name);
465 WARN_ON(1);
466 }
467 return ret;
468}
469
470/**
438 * sysfs_remove_one - remove sysfs_dirent from parent 471 * sysfs_remove_one - remove sysfs_dirent from parent
439 * @acxt: addrm context to use 472 * @acxt: addrm context to use
440 * @sd: sysfs_dirent to be removed 473 * @sd: sysfs_dirent to be removed
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 817f5966edca..a3ba217fbe74 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -19,13 +19,8 @@
19 19
20#include "sysfs.h" 20#include "sysfs.h"
21 21
22/** 22static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
23 * sysfs_create_link - create symlink between two objects. 23 const char *name, int warn)
24 * @kobj: object whose directory we're creating the link in.
25 * @target: object we're pointing to.
26 * @name: name of the symlink.
27 */
28int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
29{ 24{
30 struct sysfs_dirent *parent_sd = NULL; 25 struct sysfs_dirent *parent_sd = NULL;
31 struct sysfs_dirent *target_sd = NULL; 26 struct sysfs_dirent *target_sd = NULL;
@@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
65 target_sd = NULL; /* reference is now owned by the symlink */ 60 target_sd = NULL; /* reference is now owned by the symlink */
66 61
67 sysfs_addrm_start(&acxt, parent_sd); 62 sysfs_addrm_start(&acxt, parent_sd);
68 error = sysfs_add_one(&acxt, sd); 63 if (warn)
64 error = sysfs_add_one(&acxt, sd);
65 else
66 error = __sysfs_add_one(&acxt, sd);
69 sysfs_addrm_finish(&acxt); 67 sysfs_addrm_finish(&acxt);
70 68
71 if (error) 69 if (error)
@@ -80,6 +78,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
80} 78}
81 79
82/** 80/**
81 * sysfs_create_link - create symlink between two objects.
82 * @kobj: object whose directory we're creating the link in.
83 * @target: object we're pointing to.
84 * @name: name of the symlink.
85 */
86int sysfs_create_link(struct kobject *kobj, struct kobject *target,
87 const char *name)
88{
89 return sysfs_do_create_link(kobj, target, name, 1);
90}
91
92/**
93 * sysfs_create_link_nowarn - create symlink between two objects.
94 * @kobj: object whose directory we're creating the link in.
95 * @target: object we're pointing to.
96 * @name: name of the symlink.
97 *
98 * This function does the same as sysf_create_link(), but it
99 * doesn't warn if the link already exists.
100 */
101int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,
102 const char *name)
103{
104 return sysfs_do_create_link(kobj, target, name, 0);
105}
106
107/**
83 * sysfs_remove_link - remove symlink in object's directory. 108 * sysfs_remove_link - remove symlink in object's directory.
84 * @kobj: object we're acting for. 109 * @kobj: object we're acting for.
85 * @name: name of the symlink to remove. 110 * @name: name of the symlink to remove.
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index ce4e15f8aaeb..a5db496f71c7 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
107void sysfs_put_active_two(struct sysfs_dirent *sd); 107void sysfs_put_active_two(struct sysfs_dirent *sd);
108void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt, 108void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
109 struct sysfs_dirent *parent_sd); 109 struct sysfs_dirent *parent_sd);
110int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
110int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 111int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
111void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); 112void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
112void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); 113void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 7858eac40aa7..37fa24152bd8 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -101,6 +101,9 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
101 101
102int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target, 102int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
103 const char *name); 103 const char *name);
104int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
105 struct kobject *target,
106 const char *name);
104void sysfs_remove_link(struct kobject *kobj, const char *name); 107void sysfs_remove_link(struct kobject *kobj, const char *name);
105 108
106int __must_check sysfs_create_group(struct kobject *kobj, 109int __must_check sysfs_create_group(struct kobject *kobj,
@@ -180,6 +183,13 @@ static inline int sysfs_create_link(struct kobject *kobj,
180 return 0; 183 return 0;
181} 184}
182 185
186static inline int sysfs_create_link_nowarn(struct kobject *kobj,
187 struct kobject *target,
188 const char *name)
189{
190 return 0;
191}
192
183static inline void sysfs_remove_link(struct kobject *kobj, const char *name) 193static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
184{ 194{
185} 195}