diff options
Diffstat (limited to 'fs/sysfs/sysfs.h')
-rw-r--r-- | fs/sysfs/sysfs.h | 236 |
1 files changed, 12 insertions, 224 deletions
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 0af09fbfb3f6..0e2f1cccb812 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -8,248 +8,36 @@ | |||
8 | * This file is released under the GPLv2. | 8 | * This file is released under the GPLv2. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/lockdep.h> | 11 | #ifndef __SYSFS_INTERNAL_H |
12 | #include <linux/kobject_ns.h> | 12 | #define __SYSFS_INTERNAL_H |
13 | #include <linux/fs.h> | ||
14 | #include <linux/rbtree.h> | ||
15 | 13 | ||
16 | struct sysfs_open_dirent; | 14 | #include <linux/sysfs.h> |
17 | |||
18 | /* type-specific structures for sysfs_dirent->s_* union members */ | ||
19 | struct sysfs_elem_dir { | ||
20 | struct kobject *kobj; | ||
21 | |||
22 | unsigned long subdirs; | ||
23 | /* children rbtree starts here and goes through sd->s_rb */ | ||
24 | struct rb_root children; | ||
25 | }; | ||
26 | |||
27 | struct sysfs_elem_symlink { | ||
28 | struct sysfs_dirent *target_sd; | ||
29 | }; | ||
30 | |||
31 | struct sysfs_elem_attr { | ||
32 | union { | ||
33 | struct attribute *attr; | ||
34 | struct bin_attribute *bin_attr; | ||
35 | }; | ||
36 | struct sysfs_open_dirent *open; | ||
37 | }; | ||
38 | |||
39 | struct sysfs_inode_attrs { | ||
40 | struct iattr ia_iattr; | ||
41 | void *ia_secdata; | ||
42 | u32 ia_secdata_len; | ||
43 | }; | ||
44 | |||
45 | /* | ||
46 | * sysfs_dirent - the building block of sysfs hierarchy. Each and | ||
47 | * every sysfs node is represented by single sysfs_dirent. | ||
48 | * | ||
49 | * As long as s_count reference is held, the sysfs_dirent itself is | ||
50 | * accessible. Dereferencing s_elem or any other outer entity | ||
51 | * requires s_active reference. | ||
52 | */ | ||
53 | struct sysfs_dirent { | ||
54 | atomic_t s_count; | ||
55 | atomic_t s_active; | ||
56 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
57 | struct lockdep_map dep_map; | ||
58 | #endif | ||
59 | struct sysfs_dirent *s_parent; | ||
60 | const char *s_name; | ||
61 | |||
62 | struct rb_node s_rb; | ||
63 | |||
64 | union { | ||
65 | struct completion *completion; | ||
66 | struct sysfs_dirent *removed_list; | ||
67 | } u; | ||
68 | |||
69 | const void *s_ns; /* namespace tag */ | ||
70 | unsigned int s_hash; /* ns + name hash */ | ||
71 | union { | ||
72 | struct sysfs_elem_dir s_dir; | ||
73 | struct sysfs_elem_symlink s_symlink; | ||
74 | struct sysfs_elem_attr s_attr; | ||
75 | }; | ||
76 | |||
77 | unsigned short s_flags; | ||
78 | umode_t s_mode; | ||
79 | unsigned int s_ino; | ||
80 | struct sysfs_inode_attrs *s_iattr; | ||
81 | }; | ||
82 | |||
83 | #define SD_DEACTIVATED_BIAS INT_MIN | ||
84 | |||
85 | #define SYSFS_TYPE_MASK 0x00ff | ||
86 | #define SYSFS_DIR 0x0001 | ||
87 | #define SYSFS_KOBJ_ATTR 0x0002 | ||
88 | #define SYSFS_KOBJ_BIN_ATTR 0x0004 | ||
89 | #define SYSFS_KOBJ_LINK 0x0008 | ||
90 | #define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) | ||
91 | #define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR) | ||
92 | |||
93 | /* identify any namespace tag on sysfs_dirents */ | ||
94 | #define SYSFS_NS_TYPE_MASK 0xf00 | ||
95 | #define SYSFS_NS_TYPE_SHIFT 8 | ||
96 | |||
97 | #define SYSFS_FLAG_MASK ~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK) | ||
98 | #define SYSFS_FLAG_REMOVED 0x02000 | ||
99 | |||
100 | static inline unsigned int sysfs_type(struct sysfs_dirent *sd) | ||
101 | { | ||
102 | return sd->s_flags & SYSFS_TYPE_MASK; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Return any namespace tags on this dirent. | ||
107 | * enum kobj_ns_type is defined in linux/kobject.h | ||
108 | */ | ||
109 | static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd) | ||
110 | { | ||
111 | return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT; | ||
112 | } | ||
113 | |||
114 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
115 | |||
116 | #define sysfs_dirent_init_lockdep(sd) \ | ||
117 | do { \ | ||
118 | struct attribute *attr = sd->s_attr.attr; \ | ||
119 | struct lock_class_key *key = attr->key; \ | ||
120 | if (!key) \ | ||
121 | key = &attr->skey; \ | ||
122 | \ | ||
123 | lockdep_init_map(&sd->dep_map, "s_active", key, 0); \ | ||
124 | } while (0) | ||
125 | |||
126 | /* Test for attributes that want to ignore lockdep for read-locking */ | ||
127 | static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd) | ||
128 | { | ||
129 | int type = sysfs_type(sd); | ||
130 | |||
131 | return (type == SYSFS_KOBJ_ATTR || type == SYSFS_KOBJ_BIN_ATTR) && | ||
132 | sd->s_attr.attr->ignore_lockdep; | ||
133 | } | ||
134 | |||
135 | #else | ||
136 | |||
137 | #define sysfs_dirent_init_lockdep(sd) do {} while (0) | ||
138 | |||
139 | static inline bool sysfs_ignore_lockdep(struct sysfs_dirent *sd) | ||
140 | { | ||
141 | return true; | ||
142 | } | ||
143 | |||
144 | #endif | ||
145 | |||
146 | /* | ||
147 | * Context structure to be used while adding/removing nodes. | ||
148 | */ | ||
149 | struct sysfs_addrm_cxt { | ||
150 | struct sysfs_dirent *removed; | ||
151 | }; | ||
152 | 15 | ||
153 | /* | 16 | /* |
154 | * mount.c | 17 | * mount.c |
155 | */ | 18 | */ |
156 | 19 | extern struct kernfs_node *sysfs_root_kn; | |
157 | /* | ||
158 | * Each sb is associated with a set of namespace tags (i.e. | ||
159 | * the network namespace of the task which mounted this sysfs | ||
160 | * instance). | ||
161 | */ | ||
162 | struct sysfs_super_info { | ||
163 | void *ns[KOBJ_NS_TYPES]; | ||
164 | }; | ||
165 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) | ||
166 | extern struct sysfs_dirent sysfs_root; | ||
167 | extern struct kmem_cache *sysfs_dir_cachep; | ||
168 | 20 | ||
169 | /* | 21 | /* |
170 | * dir.c | 22 | * dir.c |
171 | */ | 23 | */ |
172 | extern struct mutex sysfs_mutex; | ||
173 | extern spinlock_t sysfs_symlink_target_lock; | 24 | extern spinlock_t sysfs_symlink_target_lock; |
174 | extern const struct dentry_operations sysfs_dentry_ops; | ||
175 | |||
176 | extern const struct file_operations sysfs_dir_operations; | ||
177 | extern const struct inode_operations sysfs_dir_inode_operations; | ||
178 | 25 | ||
179 | struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd); | 26 | void sysfs_warn_dup(struct kernfs_node *parent, const char *name); |
180 | void sysfs_put_active(struct sysfs_dirent *sd); | ||
181 | void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt); | ||
182 | void sysfs_warn_dup(struct sysfs_dirent *parent, const char *name); | ||
183 | int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, | ||
184 | struct sysfs_dirent *parent_sd); | ||
185 | int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd, | ||
186 | struct sysfs_dirent *parent_sd); | ||
187 | void sysfs_remove(struct sysfs_dirent *sd); | ||
188 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name, | ||
189 | const void *ns); | ||
190 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); | ||
191 | |||
192 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | ||
193 | const unsigned char *name, | ||
194 | const void *ns); | ||
195 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); | ||
196 | |||
197 | void release_sysfs_dirent(struct sysfs_dirent *sd); | ||
198 | |||
199 | int sysfs_create_subdir(struct kobject *kobj, const char *name, | ||
200 | struct sysfs_dirent **p_sd); | ||
201 | |||
202 | int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd, | ||
203 | const char *new_name, const void *new_ns); | ||
204 | |||
205 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) | ||
206 | { | ||
207 | if (sd) { | ||
208 | WARN_ON(!atomic_read(&sd->s_count)); | ||
209 | atomic_inc(&sd->s_count); | ||
210 | } | ||
211 | return sd; | ||
212 | } | ||
213 | #define sysfs_get(sd) __sysfs_get(sd) | ||
214 | |||
215 | static inline void __sysfs_put(struct sysfs_dirent *sd) | ||
216 | { | ||
217 | if (sd && atomic_dec_and_test(&sd->s_count)) | ||
218 | release_sysfs_dirent(sd); | ||
219 | } | ||
220 | #define sysfs_put(sd) __sysfs_put(sd) | ||
221 | |||
222 | /* | ||
223 | * inode.c | ||
224 | */ | ||
225 | struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd); | ||
226 | void sysfs_evict_inode(struct inode *inode); | ||
227 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); | ||
228 | int sysfs_permission(struct inode *inode, int mask); | ||
229 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | ||
230 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
231 | struct kstat *stat); | ||
232 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, | ||
233 | size_t size, int flags); | ||
234 | int sysfs_inode_init(void); | ||
235 | 27 | ||
236 | /* | 28 | /* |
237 | * file.c | 29 | * file.c |
238 | */ | 30 | */ |
239 | extern const struct file_operations sysfs_file_operations; | 31 | int sysfs_add_file(struct kernfs_node *parent, |
240 | extern const struct file_operations sysfs_bin_operations; | 32 | const struct attribute *attr, bool is_bin); |
241 | 33 | int sysfs_add_file_mode_ns(struct kernfs_node *parent, | |
242 | int sysfs_add_file(struct sysfs_dirent *dir_sd, | 34 | const struct attribute *attr, bool is_bin, |
243 | const struct attribute *attr, int type); | ||
244 | |||
245 | int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, | ||
246 | const struct attribute *attr, int type, | ||
247 | umode_t amode, const void *ns); | 35 | umode_t amode, const void *ns); |
248 | void sysfs_unmap_bin_file(struct sysfs_dirent *sd); | ||
249 | 36 | ||
250 | /* | 37 | /* |
251 | * symlink.c | 38 | * symlink.c |
252 | */ | 39 | */ |
253 | extern const struct inode_operations sysfs_symlink_inode_operations; | 40 | int sysfs_create_link_sd(struct kernfs_node *kn, struct kobject *target, |
254 | int sysfs_create_link_sd(struct sysfs_dirent *sd, struct kobject *target, | ||
255 | const char *name); | 41 | const char *name); |
42 | |||
43 | #endif /* __SYSFS_INTERNAL_H */ | ||