aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/Kconfig1
-rw-r--r--fs/sysfs/dir.c44
-rw-r--r--fs/sysfs/file.c23
-rw-r--r--fs/sysfs/group.c7
-rw-r--r--fs/sysfs/mount.c2
5 files changed, 43 insertions, 34 deletions
diff --git a/fs/sysfs/Kconfig b/fs/sysfs/Kconfig
index 8c41feacbac5..b2756014508c 100644
--- a/fs/sysfs/Kconfig
+++ b/fs/sysfs/Kconfig
@@ -1,6 +1,7 @@
1config SYSFS 1config SYSFS
2 bool "sysfs file system support" if EXPERT 2 bool "sysfs file system support" if EXPERT
3 default y 3 default y
4 select KERNFS
4 help 5 help
5 The sysfs filesystem is a virtual filesystem that the kernel uses to 6 The sysfs filesystem is a virtual filesystem that the kernel uses to
6 export internal kernel objects, their attributes, and their 7 export internal kernel objects, their attributes, and their
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index ee0d761c3179..0b45ff42f374 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -19,39 +19,18 @@
19 19
20DEFINE_SPINLOCK(sysfs_symlink_target_lock); 20DEFINE_SPINLOCK(sysfs_symlink_target_lock);
21 21
22/**
23 * sysfs_pathname - return full path to sysfs dirent
24 * @kn: kernfs_node whose path we want
25 * @path: caller allocated buffer of size PATH_MAX
26 *
27 * Gives the name "/" to the sysfs_root entry; any path returned
28 * is relative to wherever sysfs is mounted.
29 */
30static char *sysfs_pathname(struct kernfs_node *kn, char *path)
31{
32 if (kn->parent) {
33 sysfs_pathname(kn->parent, path);
34 strlcat(path, "/", PATH_MAX);
35 }
36 strlcat(path, kn->name, PATH_MAX);
37 return path;
38}
39
40void sysfs_warn_dup(struct kernfs_node *parent, const char *name) 22void sysfs_warn_dup(struct kernfs_node *parent, const char *name)
41{ 23{
42 char *path; 24 char *buf, *path = NULL;
43 25
44 path = kzalloc(PATH_MAX, GFP_KERNEL); 26 buf = kzalloc(PATH_MAX, GFP_KERNEL);
45 if (path) { 27 if (buf)
46 sysfs_pathname(parent, path); 28 path = kernfs_path(parent, buf, PATH_MAX);
47 strlcat(path, "/", PATH_MAX);
48 strlcat(path, name, PATH_MAX);
49 }
50 29
51 WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s'\n", 30 WARN(1, KERN_WARNING "sysfs: cannot create duplicate filename '%s/%s'\n",
52 path ? path : name); 31 path, name);
53 32
54 kfree(path); 33 kfree(buf);
55} 34}
56 35
57/** 36/**
@@ -122,9 +101,13 @@ void sysfs_remove_dir(struct kobject *kobj)
122int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, 101int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
123 const void *new_ns) 102 const void *new_ns)
124{ 103{
125 struct kernfs_node *parent = kobj->sd->parent; 104 struct kernfs_node *parent;
105 int ret;
126 106
127 return kernfs_rename_ns(kobj->sd, parent, new_name, new_ns); 107 parent = kernfs_get_parent(kobj->sd);
108 ret = kernfs_rename_ns(kobj->sd, parent, new_name, new_ns);
109 kernfs_put(parent);
110 return ret;
128} 111}
129 112
130int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj, 113int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
@@ -133,7 +116,6 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
133 struct kernfs_node *kn = kobj->sd; 116 struct kernfs_node *kn = kobj->sd;
134 struct kernfs_node *new_parent; 117 struct kernfs_node *new_parent;
135 118
136 BUG_ON(!kn->parent);
137 new_parent = new_parent_kobj && new_parent_kobj->sd ? 119 new_parent = new_parent_kobj && new_parent_kobj->sd ?
138 new_parent_kobj->sd : sysfs_root_kn; 120 new_parent_kobj->sd : sysfs_root_kn;
139 121
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 810cf6e613e5..1b8b91b67fdb 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -372,6 +372,29 @@ void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
372} 372}
373EXPORT_SYMBOL_GPL(sysfs_remove_file_ns); 373EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
374 374
375/**
376 * sysfs_remove_file_self - remove an object attribute from its own method
377 * @kobj: object we're acting for
378 * @attr: attribute descriptor
379 *
380 * See kernfs_remove_self() for details.
381 */
382bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr)
383{
384 struct kernfs_node *parent = kobj->sd;
385 struct kernfs_node *kn;
386 bool ret;
387
388 kn = kernfs_find_and_get(parent, attr->name);
389 if (WARN_ON_ONCE(!kn))
390 return false;
391
392 ret = kernfs_remove_self(kn);
393
394 kernfs_put(kn);
395 return ret;
396}
397
375void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr) 398void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
376{ 399{
377 int i; 400 int i;
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 6b579387c67a..aa0406895b53 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -70,8 +70,11 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
70 if (grp->bin_attrs) { 70 if (grp->bin_attrs) {
71 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { 71 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) {
72 if (update) 72 if (update)
73 sysfs_remove_bin_file(kobj, *bin_attr); 73 kernfs_remove_by_name(parent,
74 error = sysfs_create_bin_file(kobj, *bin_attr); 74 (*bin_attr)->attr.name);
75 error = sysfs_add_file_mode_ns(parent,
76 &(*bin_attr)->attr, true,
77 (*bin_attr)->attr.mode, NULL);
75 if (error) 78 if (error)
76 break; 79 break;
77 } 80 }
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 3eaf5c6622eb..a66ad6196f59 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -63,7 +63,7 @@ int __init sysfs_init(void)
63{ 63{
64 int err; 64 int err;
65 65
66 sysfs_root = kernfs_create_root(NULL, NULL); 66 sysfs_root = kernfs_create_root(NULL, 0, NULL);
67 if (IS_ERR(sysfs_root)) 67 if (IS_ERR(sysfs_root))
68 return PTR_ERR(sysfs_root); 68 return PTR_ERR(sysfs_root);
69 69