Blame view
fs/sysfs/dir.c
4.12 KB
619daeeeb sysfs: use SPDX i... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
6d66f5cd2 sysfs: add copyri... |
3 4 5 6 7 8 |
* fs/sysfs/dir.c - sysfs core and dir operation implementation * * Copyright (c) 2001-3 Patrick Mochel * Copyright (c) 2007 SUSE Linux Products GmbH * Copyright (c) 2007 Tejun Heo <teheo@suse.de> * |
0c1bc6b84 docs: filesystems... |
9 |
* Please see Documentation/filesystems/sysfs.rst for more information. |
1da177e4c Linux-2.6.12-rc2 |
10 |
*/ |
5d54f948a sysfs: turn WARN(... |
11 |
#define pr_fmt(fmt) "sysfs: " fmt |
1da177e4c Linux-2.6.12-rc2 |
12 13 |
#include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/kobject.h> |
c6f877338 SYSFS: Explicitly... |
15 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include "sysfs.h" |
0cae60f91 sysfs: rename sys... |
17 |
DEFINE_SPINLOCK(sysfs_symlink_target_lock); |
1da177e4c Linux-2.6.12-rc2 |
18 |
|
324a56e16 kernfs: s/sysfs_d... |
19 |
void sysfs_warn_dup(struct kernfs_node *parent, const char *name) |
d1c1459e4 sysfs: separate o... |
20 |
{ |
3abb1d90f kernfs: make kern... |
21 |
char *buf; |
d1c1459e4 sysfs: separate o... |
22 |
|
3eef34ad7 kernfs: implement... |
23 24 |
buf = kzalloc(PATH_MAX, GFP_KERNEL); if (buf) |
3abb1d90f kernfs: make kern... |
25 |
kernfs_path(parent, buf, PATH_MAX); |
d1c1459e4 sysfs: separate o... |
26 |
|
5d54f948a sysfs: turn WARN(... |
27 28 29 |
pr_warn("cannot create duplicate filename '%s/%s' ", buf, name); dump_stack(); |
d1c1459e4 sysfs: separate o... |
30 |
|
3eef34ad7 kernfs: implement... |
31 |
kfree(buf); |
d1c1459e4 sysfs: separate o... |
32 |
} |
425cb0291 sysfs: sysfs_add_... |
33 |
/** |
e34ff4906 sysfs: remove kty... |
34 35 36 |
* sysfs_create_dir_ns - create a directory for an object with a namespace tag * @kobj: object we're creating directory for * @ns: the namespace tag to use |
1da177e4c Linux-2.6.12-rc2 |
37 |
*/ |
e34ff4906 sysfs: remove kty... |
38 |
int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) |
1da177e4c Linux-2.6.12-rc2 |
39 |
{ |
324a56e16 kernfs: s/sysfs_d... |
40 |
struct kernfs_node *parent, *kn; |
5f81880d5 sysfs, kobject: a... |
41 42 |
kuid_t uid; kgid_t gid; |
1da177e4c Linux-2.6.12-rc2 |
43 |
|
de96e9fea sysfs: convert BU... |
44 45 |
if (WARN_ON(!kobj)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
46 |
|
90bc61359 sysfs: Remove fir... |
47 |
if (kobj->parent) |
324a56e16 kernfs: s/sysfs_d... |
48 |
parent = kobj->parent->sd; |
1da177e4c Linux-2.6.12-rc2 |
49 |
else |
324a56e16 kernfs: s/sysfs_d... |
50 |
parent = sysfs_root_kn; |
1da177e4c Linux-2.6.12-rc2 |
51 |
|
324a56e16 kernfs: s/sysfs_d... |
52 |
if (!parent) |
3a198886a sysfs: handle 'pa... |
53 |
return -ENOENT; |
5f81880d5 sysfs, kobject: a... |
54 |
kobject_get_ownership(kobj, &uid, &gid); |
bb8b9d095 kernfs: add @mode... |
55 |
kn = kernfs_create_dir_ns(parent, kobject_name(kobj), |
5f81880d5 sysfs, kobject: a... |
56 |
S_IRWXU | S_IRUGO | S_IXUGO, uid, gid, |
488dee96b kernfs: allow cre... |
57 |
kobj, ns); |
324a56e16 kernfs: s/sysfs_d... |
58 59 60 61 |
if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, kobject_name(kobj)); return PTR_ERR(kn); |
93b2b8e4a sysfs, kernfs: in... |
62 |
} |
324a56e16 kernfs: s/sysfs_d... |
63 |
kobj->sd = kn; |
93b2b8e4a sysfs, kernfs: in... |
64 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
65 |
} |
7eed6ecb0 sysfs: move sysfs... |
66 |
/** |
b592fcfe7 sysfs: Shadow dir... |
67 68 69 70 71 72 73 |
* sysfs_remove_dir - remove an object's directory. * @kobj: object. * * The only thing special about this is that we remove any files in * the directory before we remove the directory, and we've inlined * what used to be sysfs_rmdir() below, instead of calling separately. */ |
1b18dc2be sysfs: fix up spa... |
74 |
void sysfs_remove_dir(struct kobject *kobj) |
b592fcfe7 sysfs: Shadow dir... |
75 |
{ |
324a56e16 kernfs: s/sysfs_d... |
76 |
struct kernfs_node *kn = kobj->sd; |
aecdcedaa sysfs: implement ... |
77 |
|
0cae60f91 sysfs: rename sys... |
78 79 80 81 82 |
/* * In general, kboject owner is responsible for ensuring removal * doesn't race with other operations and sysfs doesn't provide any * protection; however, when @kobj is used as a symlink target, the * symlinking entity usually doesn't own @kobj and thus has no |
324a56e16 kernfs: s/sysfs_d... |
83 84 |
* control over removal. @kobj->sd may be removed anytime * and symlink code may end up dereferencing an already freed node. |
0cae60f91 sysfs: rename sys... |
85 |
* |
324a56e16 kernfs: s/sysfs_d... |
86 87 88 |
* sysfs_symlink_target_lock synchronizes @kobj->sd * disassociation against symlink operations so that symlink code * can safely dereference @kobj->sd. |
0cae60f91 sysfs: rename sys... |
89 90 |
*/ spin_lock(&sysfs_symlink_target_lock); |
608e266a2 sysfs: make kobj ... |
91 |
kobj->sd = NULL; |
0cae60f91 sysfs: rename sys... |
92 |
spin_unlock(&sysfs_symlink_target_lock); |
aecdcedaa sysfs: implement ... |
93 |
|
324a56e16 kernfs: s/sysfs_d... |
94 |
if (kn) { |
df23fc39b kernfs: s/sysfs/k... |
95 |
WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR); |
324a56e16 kernfs: s/sysfs_d... |
96 |
kernfs_remove(kn); |
250f7c3fe sysfs: introduce ... |
97 |
} |
1da177e4c Linux-2.6.12-rc2 |
98 |
} |
e34ff4906 sysfs: remove kty... |
99 100 |
int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, const void *new_ns) |
ca1bab381 sysfs: Factor out... |
101 |
{ |
3eef34ad7 kernfs: implement... |
102 103 |
struct kernfs_node *parent; int ret; |
3ff195b01 sysfs: Implement ... |
104 |
|
3eef34ad7 kernfs: implement... |
105 106 107 108 |
parent = kernfs_get_parent(kobj->sd); ret = kernfs_rename_ns(kobj->sd, parent, new_name, new_ns); kernfs_put(parent); return ret; |
ca1bab381 sysfs: Factor out... |
109 |
} |
e34ff4906 sysfs: remove kty... |
110 111 |
int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj, const void *new_ns) |
8a82472f8 driver core: Intr... |
112 |
{ |
324a56e16 kernfs: s/sysfs_d... |
113 114 |
struct kernfs_node *kn = kobj->sd; struct kernfs_node *new_parent; |
8a82472f8 driver core: Intr... |
115 |
|
324a56e16 kernfs: s/sysfs_d... |
116 117 |
new_parent = new_parent_kobj && new_parent_kobj->sd ? new_parent_kobj->sd : sysfs_root_kn; |
51225039f sysfs: make direc... |
118 |
|
adc5e8b58 kernfs: drop s_ p... |
119 |
return kernfs_rename_ns(kn, new_parent, kn->name, new_ns); |
8a82472f8 driver core: Intr... |
120 |
} |
87d2846fc sysfs: Add suppor... |
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
/** * sysfs_create_mount_point - create an always empty directory * @parent_kobj: kobject that will contain this always empty directory * @name: The name of the always empty directory to add */ int sysfs_create_mount_point(struct kobject *parent_kobj, const char *name) { struct kernfs_node *kn, *parent = parent_kobj->sd; kn = kernfs_create_empty_dir(parent, name); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, name); return PTR_ERR(kn); } return 0; } EXPORT_SYMBOL_GPL(sysfs_create_mount_point); /** * sysfs_remove_mount_point - remove an always empty directory. * @parent_kobj: kobject that will contain this always empty directory * @name: The name of the always empty directory to remove * */ void sysfs_remove_mount_point(struct kobject *parent_kobj, const char *name) { struct kernfs_node *parent = parent_kobj->sd; kernfs_remove_by_name_ns(parent, name, NULL); } EXPORT_SYMBOL_GPL(sysfs_remove_mount_point); |