kernfs, sysfs, driver-core: implement kernfs_remove_self() and its wrappers
[linux-2.6-block.git] / include / linux / kernfs.h
1 /*
2  * kernfs.h - pseudo filesystem decoupled from vfs locking
3  *
4  * This file is released under the GPLv2.
5  */
6
7 #ifndef __LINUX_KERNFS_H
8 #define __LINUX_KERNFS_H
9
10 #include <linux/kernel.h>
11 #include <linux/err.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/idr.h>
15 #include <linux/lockdep.h>
16 #include <linux/rbtree.h>
17 #include <linux/atomic.h>
18 #include <linux/wait.h>
19
20 struct file;
21 struct dentry;
22 struct iattr;
23 struct seq_file;
24 struct vm_area_struct;
25 struct super_block;
26 struct file_system_type;
27
28 struct kernfs_open_node;
29 struct kernfs_iattrs;
30
31 enum kernfs_node_type {
32         KERNFS_DIR              = 0x0001,
33         KERNFS_FILE             = 0x0002,
34         KERNFS_LINK             = 0x0004,
35 };
36
37 #define KERNFS_TYPE_MASK        0x000f
38 #define KERNFS_FLAG_MASK        ~KERNFS_TYPE_MASK
39
40 enum kernfs_node_flag {
41         KERNFS_NS               = 0x0020,
42         KERNFS_HAS_SEQ_SHOW     = 0x0040,
43         KERNFS_HAS_MMAP         = 0x0080,
44         KERNFS_LOCKDEP          = 0x0100,
45         KERNFS_STATIC_NAME      = 0x0200,
46         KERNFS_SUICIDAL         = 0x0400,
47         KERNFS_SUICIDED         = 0x0800,
48 };
49
50 /* type-specific structures for kernfs_node union members */
51 struct kernfs_elem_dir {
52         unsigned long           subdirs;
53         /* children rbtree starts here and goes through kn->rb */
54         struct rb_root          children;
55
56         /*
57          * The kernfs hierarchy this directory belongs to.  This fits
58          * better directly in kernfs_node but is here to save space.
59          */
60         struct kernfs_root      *root;
61 };
62
63 struct kernfs_elem_symlink {
64         struct kernfs_node      *target_kn;
65 };
66
67 struct kernfs_elem_attr {
68         const struct kernfs_ops *ops;
69         struct kernfs_open_node *open;
70         loff_t                  size;
71 };
72
73 /*
74  * kernfs_node - the building block of kernfs hierarchy.  Each and every
75  * kernfs node is represented by single kernfs_node.  Most fields are
76  * private to kernfs and shouldn't be accessed directly by kernfs users.
77  *
78  * As long as s_count reference is held, the kernfs_node itself is
79  * accessible.  Dereferencing elem or any other outer entity requires
80  * active reference.
81  */
82 struct kernfs_node {
83         atomic_t                count;
84         atomic_t                active;
85 #ifdef CONFIG_DEBUG_LOCK_ALLOC
86         struct lockdep_map      dep_map;
87 #endif
88         /* the following two fields are published */
89         struct kernfs_node      *parent;
90         const char              *name;
91
92         struct rb_node          rb;
93
94         const void              *ns;    /* namespace tag */
95         unsigned int            hash;   /* ns + name hash */
96         union {
97                 struct kernfs_elem_dir          dir;
98                 struct kernfs_elem_symlink      symlink;
99                 struct kernfs_elem_attr         attr;
100         };
101
102         void                    *priv;
103
104         unsigned short          flags;
105         umode_t                 mode;
106         unsigned int            ino;
107         struct kernfs_iattrs    *iattr;
108 };
109
110 /*
111  * kernfs_dir_ops may be specified on kernfs_create_root() to support
112  * directory manipulation syscalls.  These optional callbacks are invoked
113  * on the matching syscalls and can perform any kernfs operations which
114  * don't necessarily have to be the exact operation requested.
115  */
116 struct kernfs_dir_ops {
117         int (*mkdir)(struct kernfs_node *parent, const char *name,
118                      umode_t mode);
119         int (*rmdir)(struct kernfs_node *kn);
120         int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent,
121                       const char *new_name);
122 };
123
124 struct kernfs_root {
125         /* published fields */
126         struct kernfs_node      *kn;
127
128         /* private fields, do not use outside kernfs proper */
129         struct ida              ino_ida;
130         struct kernfs_dir_ops   *dir_ops;
131         wait_queue_head_t       deactivate_waitq;
132 };
133
134 struct kernfs_open_file {
135         /* published fields */
136         struct kernfs_node      *kn;
137         struct file             *file;
138
139         /* private fields, do not use outside kernfs proper */
140         struct mutex            mutex;
141         int                     event;
142         struct list_head        list;
143
144         bool                    mmapped;
145         const struct vm_operations_struct *vm_ops;
146 };
147
148 struct kernfs_ops {
149         /*
150          * Read is handled by either seq_file or raw_read().
151          *
152          * If seq_show() is present, seq_file path is active.  Other seq
153          * operations are optional and if not implemented, the behavior is
154          * equivalent to single_open().  @sf->private points to the
155          * associated kernfs_open_file.
156          *
157          * read() is bounced through kernel buffer and a read larger than
158          * PAGE_SIZE results in partial operation of PAGE_SIZE.
159          */
160         int (*seq_show)(struct seq_file *sf, void *v);
161
162         void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
163         void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
164         void (*seq_stop)(struct seq_file *sf, void *v);
165
166         ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes,
167                         loff_t off);
168
169         /*
170          * write() is bounced through kernel buffer and a write larger than
171          * PAGE_SIZE results in partial operation of PAGE_SIZE.
172          */
173         ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes,
174                          loff_t off);
175
176         int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
177
178 #ifdef CONFIG_DEBUG_LOCK_ALLOC
179         struct lock_class_key   lockdep_key;
180 #endif
181 };
182
183 #ifdef CONFIG_SYSFS
184
185 static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
186 {
187         return kn->flags & KERNFS_TYPE_MASK;
188 }
189
190 /**
191  * kernfs_enable_ns - enable namespace under a directory
192  * @kn: directory of interest, should be empty
193  *
194  * This is to be called right after @kn is created to enable namespace
195  * under it.  All children of @kn must have non-NULL namespace tags and
196  * only the ones which match the super_block's tag will be visible.
197  */
198 static inline void kernfs_enable_ns(struct kernfs_node *kn)
199 {
200         WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR);
201         WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children));
202         kn->flags |= KERNFS_NS;
203 }
204
205 /**
206  * kernfs_ns_enabled - test whether namespace is enabled
207  * @kn: the node to test
208  *
209  * Test whether namespace filtering is enabled for the children of @ns.
210  */
211 static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
212 {
213         return kn->flags & KERNFS_NS;
214 }
215
216 struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
217                                            const char *name, const void *ns);
218 void kernfs_get(struct kernfs_node *kn);
219 void kernfs_put(struct kernfs_node *kn);
220
221 struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops,
222                                        void *priv);
223 void kernfs_destroy_root(struct kernfs_root *root);
224
225 struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
226                                          const char *name, umode_t mode,
227                                          void *priv, const void *ns);
228 struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
229                                          const char *name,
230                                          umode_t mode, loff_t size,
231                                          const struct kernfs_ops *ops,
232                                          void *priv, const void *ns,
233                                          bool name_is_static,
234                                          struct lock_class_key *key);
235 struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
236                                        const char *name,
237                                        struct kernfs_node *target);
238 void kernfs_remove(struct kernfs_node *kn);
239 void kernfs_break_active_protection(struct kernfs_node *kn);
240 void kernfs_unbreak_active_protection(struct kernfs_node *kn);
241 bool kernfs_remove_self(struct kernfs_node *kn);
242 int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
243                              const void *ns);
244 int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
245                      const char *new_name, const void *new_ns);
246 int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
247 void kernfs_notify(struct kernfs_node *kn);
248
249 const void *kernfs_super_ns(struct super_block *sb);
250 struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
251                                struct kernfs_root *root, const void *ns);
252 void kernfs_kill_sb(struct super_block *sb);
253
254 void kernfs_init(void);
255
256 #else   /* CONFIG_SYSFS */
257
258 static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
259 { return 0; }   /* whatever */
260
261 static inline void kernfs_enable_ns(struct kernfs_node *kn) { }
262
263 static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
264 { return false; }
265
266 static inline struct kernfs_node *
267 kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
268                        const void *ns)
269 { return NULL; }
270
271 static inline void kernfs_get(struct kernfs_node *kn) { }
272 static inline void kernfs_put(struct kernfs_node *kn) { }
273
274 static inline struct kernfs_root *
275 kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv)
276 { return ERR_PTR(-ENOSYS); }
277
278 static inline void kernfs_destroy_root(struct kernfs_root *root) { }
279
280 static inline struct kernfs_node *
281 kernfs_create_dir_ns(struct kernfs_node *parent, const char *name,
282                      umode_t mode, void *priv, const void *ns)
283 { return ERR_PTR(-ENOSYS); }
284
285 static inline struct kernfs_node *
286 __kernfs_create_file(struct kernfs_node *parent, const char *name,
287                      umode_t mode, loff_t size, const struct kernfs_ops *ops,
288                      void *priv, const void *ns, bool name_is_static,
289                      struct lock_class_key *key)
290 { return ERR_PTR(-ENOSYS); }
291
292 static inline struct kernfs_node *
293 kernfs_create_link(struct kernfs_node *parent, const char *name,
294                    struct kernfs_node *target)
295 { return ERR_PTR(-ENOSYS); }
296
297 static inline void kernfs_remove(struct kernfs_node *kn) { }
298
299 static inline bool kernfs_remove_self(struct kernfs_node *kn)
300 { return false; }
301
302 static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn,
303                                            const char *name, const void *ns)
304 { return -ENOSYS; }
305
306 static inline int kernfs_rename_ns(struct kernfs_node *kn,
307                                    struct kernfs_node *new_parent,
308                                    const char *new_name, const void *new_ns)
309 { return -ENOSYS; }
310
311 static inline int kernfs_setattr(struct kernfs_node *kn,
312                                  const struct iattr *iattr)
313 { return -ENOSYS; }
314
315 static inline void kernfs_notify(struct kernfs_node *kn) { }
316
317 static inline const void *kernfs_super_ns(struct super_block *sb)
318 { return NULL; }
319
320 static inline struct dentry *
321 kernfs_mount_ns(struct file_system_type *fs_type, int flags,
322                 struct kernfs_root *root, const void *ns)
323 { return ERR_PTR(-ENOSYS); }
324
325 static inline void kernfs_kill_sb(struct super_block *sb) { }
326
327 static inline void kernfs_init(void) { }
328
329 #endif  /* CONFIG_SYSFS */
330
331 static inline struct kernfs_node *
332 kernfs_find_and_get(struct kernfs_node *kn, const char *name)
333 {
334         return kernfs_find_and_get_ns(kn, name, NULL);
335 }
336
337 static inline struct kernfs_node *
338 kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode,
339                   void *priv)
340 {
341         return kernfs_create_dir_ns(parent, name, mode, priv, NULL);
342 }
343
344 static inline struct kernfs_node *
345 kernfs_create_file_ns(struct kernfs_node *parent, const char *name,
346                       umode_t mode, loff_t size, const struct kernfs_ops *ops,
347                       void *priv, const void *ns)
348 {
349         struct lock_class_key *key = NULL;
350
351 #ifdef CONFIG_DEBUG_LOCK_ALLOC
352         key = (struct lock_class_key *)&ops->lockdep_key;
353 #endif
354         return __kernfs_create_file(parent, name, mode, size, ops, priv, ns,
355                                     false, key);
356 }
357
358 static inline struct kernfs_node *
359 kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode,
360                    loff_t size, const struct kernfs_ops *ops, void *priv)
361 {
362         return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
363 }
364
365 static inline int kernfs_remove_by_name(struct kernfs_node *parent,
366                                         const char *name)
367 {
368         return kernfs_remove_by_name_ns(parent, name, NULL);
369 }
370
371 static inline struct dentry *
372 kernfs_mount(struct file_system_type *fs_type, int flags,
373              struct kernfs_root *root)
374 {
375         return kernfs_mount_ns(fs_type, flags, root, NULL);
376 }
377
378 #endif  /* __LINUX_KERNFS_H */