]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - include/linux/kernfs.h
fd8f574ef2fe56c78ebb5db42df410a651961ec1
[karo-tx-linux.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/lockdep.h>
15
16 struct file;
17 struct iattr;
18 struct seq_file;
19 struct vm_area_struct;
20
21 struct sysfs_dirent;
22
23 struct sysfs_open_file {
24         /* published fields */
25         struct sysfs_dirent     *sd;
26         struct file             *file;
27
28         /* private fields, do not use outside kernfs proper */
29         struct mutex            mutex;
30         int                     event;
31         struct list_head        list;
32
33         bool                    mmapped;
34         const struct vm_operations_struct *vm_ops;
35 };
36
37 struct kernfs_ops {
38         /*
39          * Read is handled by either seq_file or raw_read().
40          *
41          * If seq_show() is present, seq_file path is active.  Other seq
42          * operations are optional and if not implemented, the behavior is
43          * equivalent to single_open().  @sf->private points to the
44          * associated sysfs_open_file.
45          *
46          * read() is bounced through kernel buffer and a read larger than
47          * PAGE_SIZE results in partial operation of PAGE_SIZE.
48          */
49         int (*seq_show)(struct seq_file *sf, void *v);
50
51         void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
52         void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
53         void (*seq_stop)(struct seq_file *sf, void *v);
54
55         ssize_t (*read)(struct sysfs_open_file *of, char *buf, size_t bytes,
56                         loff_t off);
57
58         /*
59          * write() is bounced through kernel buffer and a write larger than
60          * PAGE_SIZE results in partial operation of PAGE_SIZE.
61          */
62         ssize_t (*write)(struct sysfs_open_file *of, char *buf, size_t bytes,
63                          loff_t off);
64
65         int (*mmap)(struct sysfs_open_file *of, struct vm_area_struct *vma);
66
67 #ifdef CONFIG_DEBUG_LOCK_ALLOC
68         struct lock_class_key   lockdep_key;
69 #endif
70 };
71
72 #ifdef CONFIG_SYSFS
73
74 struct sysfs_dirent *kernfs_find_and_get_ns(struct sysfs_dirent *parent,
75                                             const char *name, const void *ns);
76 void kernfs_get(struct sysfs_dirent *sd);
77 void kernfs_put(struct sysfs_dirent *sd);
78
79 struct sysfs_dirent *kernfs_create_dir_ns(struct sysfs_dirent *parent,
80                                           const char *name, void *priv,
81                                           const void *ns);
82 struct sysfs_dirent *kernfs_create_file_ns_key(struct sysfs_dirent *parent,
83                                                const char *name,
84                                                umode_t mode, loff_t size,
85                                                const struct kernfs_ops *ops,
86                                                void *priv, const void *ns,
87                                                struct lock_class_key *key);
88 struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent,
89                                         const char *name,
90                                         struct sysfs_dirent *target);
91 void kernfs_remove(struct sysfs_dirent *sd);
92 int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name,
93                              const void *ns);
94 int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent,
95                      const char *new_name, const void *new_ns);
96 void kernfs_enable_ns(struct sysfs_dirent *sd);
97 int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr);
98 void kernfs_notify(struct sysfs_dirent *sd);
99
100 #else   /* CONFIG_SYSFS */
101
102 static inline struct sysfs_dirent *
103 kernfs_find_and_get_ns(struct sysfs_dirent *parent, const char *name,
104                        const void *ns)
105 { return NULL; }
106
107 static inline void kernfs_get(struct sysfs_dirent *sd) { }
108 static inline void kernfs_put(struct sysfs_dirent *sd) { }
109
110 static inline struct sysfs_dirent *
111 kernfs_create_dir_ns(struct sysfs_dirent *parent, const char *name, void *priv,
112                      const void *ns)
113 { return ERR_PTR(-ENOSYS); }
114
115 static inline struct sysfs_dirent *
116 kernfs_create_file_ns_key(struct sysfs_dirent *parent, const char *name,
117                           umode_t mode, loff_t size,
118                           const struct kernfs_ops *ops, void *priv,
119                           const void *ns, struct lock_class_key *key)
120 { return ERR_PTR(-ENOSYS); }
121
122 static inline struct sysfs_dirent *
123 kernfs_create_link(struct sysfs_dirent *parent, const char *name,
124                    struct sysfs_dirent *target)
125 { return ERR_PTR(-ENOSYS); }
126
127 static inline void kernfs_remove(struct sysfs_dirent *sd) { }
128
129 static inline int kernfs_remove_by_name_ns(struct sysfs_dirent *parent,
130                                            const char *name, const void *ns)
131 { return -ENOSYS; }
132
133 static inline int kernfs_rename_ns(struct sysfs_dirent *sd,
134                                    struct sysfs_dirent *new_parent,
135                                    const char *new_name, const void *new_ns)
136 { return -ENOSYS; }
137
138 static inline void kernfs_enable_ns(struct sysfs_dirent *sd) { }
139
140 static inline int kernfs_setattr(struct sysfs_dirent *sd,
141                                  const struct iattr *iattr)
142 { return -ENOSYS; }
143
144 static inline void kernfs_notify(struct sysfs_dirent *sd) { }
145
146 #endif  /* CONFIG_SYSFS */
147
148 static inline struct sysfs_dirent *
149 kernfs_find_and_get(struct sysfs_dirent *sd, const char *name)
150 {
151         return kernfs_find_and_get_ns(sd, name, NULL);
152 }
153
154 static inline struct sysfs_dirent *
155 kernfs_create_dir(struct sysfs_dirent *parent, const char *name, void *priv)
156 {
157         return kernfs_create_dir_ns(parent, name, priv, NULL);
158 }
159
160 static inline struct sysfs_dirent *
161 kernfs_create_file_ns(struct sysfs_dirent *parent, const char *name,
162                       umode_t mode, loff_t size, const struct kernfs_ops *ops,
163                       void *priv, const void *ns)
164 {
165         struct lock_class_key *key = NULL;
166
167 #ifdef CONFIG_DEBUG_LOCK_ALLOC
168         key = (struct lock_class_key *)&ops->lockdep_key;
169 #endif
170         return kernfs_create_file_ns_key(parent, name, mode, size, ops, priv,
171                                          ns, key);
172 }
173
174 static inline struct sysfs_dirent *
175 kernfs_create_file(struct sysfs_dirent *parent, const char *name, umode_t mode,
176                    loff_t size, const struct kernfs_ops *ops, void *priv)
177 {
178         return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
179 }
180
181 static inline int kernfs_remove_by_name(struct sysfs_dirent *parent,
182                                         const char *name)
183 {
184         return kernfs_remove_by_name_ns(parent, name, NULL);
185 }
186
187 #endif  /* __LINUX_KERNFS_H */