xref: /linux-6.15/include/linux/kernfs.h (revision bd727816)
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/completion.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_ACTIVE_REF	KERNFS_FILE
39 #define KERNFS_FLAG_MASK	~KERNFS_TYPE_MASK
40 
41 enum kernfs_node_flag {
42 	KERNFS_REMOVED		= 0x0010,
43 	KERNFS_NS		= 0x0020,
44 	KERNFS_HAS_SEQ_SHOW	= 0x0040,
45 	KERNFS_HAS_MMAP		= 0x0080,
46 	KERNFS_LOCKDEP		= 0x0100,
47 	KERNFS_STATIC_NAME	= 0x0200,
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 	union {
95 		struct completion	*completion;
96 		struct kernfs_node	*removed_list;
97 	} u;
98 
99 	const void		*ns;	/* namespace tag */
100 	unsigned int		hash;	/* ns + name hash */
101 	union {
102 		struct kernfs_elem_dir		dir;
103 		struct kernfs_elem_symlink	symlink;
104 		struct kernfs_elem_attr		attr;
105 	};
106 
107 	void			*priv;
108 
109 	unsigned short		flags;
110 	umode_t			mode;
111 	unsigned int		ino;
112 	struct kernfs_iattrs	*iattr;
113 };
114 
115 /*
116  * kernfs_dir_ops may be specified on kernfs_create_root() to support
117  * directory manipulation syscalls.  These optional callbacks are invoked
118  * on the matching syscalls and can perform any kernfs operations which
119  * don't necessarily have to be the exact operation requested.
120  */
121 struct kernfs_dir_ops {
122 	int (*mkdir)(struct kernfs_node *parent, const char *name,
123 		     umode_t mode);
124 	int (*rmdir)(struct kernfs_node *kn);
125 	int (*rename)(struct kernfs_node *kn, struct kernfs_node *new_parent,
126 		      const char *new_name);
127 };
128 
129 struct kernfs_root {
130 	/* published fields */
131 	struct kernfs_node	*kn;
132 
133 	/* private fields, do not use outside kernfs proper */
134 	struct ida		ino_ida;
135 	struct kernfs_dir_ops	*dir_ops;
136 };
137 
138 struct kernfs_open_file {
139 	/* published fields */
140 	struct kernfs_node	*kn;
141 	struct file		*file;
142 
143 	/* private fields, do not use outside kernfs proper */
144 	struct mutex		mutex;
145 	int			event;
146 	struct list_head	list;
147 
148 	bool			mmapped;
149 	const struct vm_operations_struct *vm_ops;
150 };
151 
152 struct kernfs_ops {
153 	/*
154 	 * Read is handled by either seq_file or raw_read().
155 	 *
156 	 * If seq_show() is present, seq_file path is active.  Other seq
157 	 * operations are optional and if not implemented, the behavior is
158 	 * equivalent to single_open().  @sf->private points to the
159 	 * associated kernfs_open_file.
160 	 *
161 	 * read() is bounced through kernel buffer and a read larger than
162 	 * PAGE_SIZE results in partial operation of PAGE_SIZE.
163 	 */
164 	int (*seq_show)(struct seq_file *sf, void *v);
165 
166 	void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
167 	void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
168 	void (*seq_stop)(struct seq_file *sf, void *v);
169 
170 	ssize_t (*read)(struct kernfs_open_file *of, char *buf, size_t bytes,
171 			loff_t off);
172 
173 	/*
174 	 * write() is bounced through kernel buffer and a write larger than
175 	 * PAGE_SIZE results in partial operation of PAGE_SIZE.
176 	 */
177 	ssize_t (*write)(struct kernfs_open_file *of, char *buf, size_t bytes,
178 			 loff_t off);
179 
180 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
181 
182 #ifdef CONFIG_DEBUG_LOCK_ALLOC
183 	struct lock_class_key	lockdep_key;
184 #endif
185 };
186 
187 #ifdef CONFIG_SYSFS
188 
189 static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
190 {
191 	return kn->flags & KERNFS_TYPE_MASK;
192 }
193 
194 /**
195  * kernfs_enable_ns - enable namespace under a directory
196  * @kn: directory of interest, should be empty
197  *
198  * This is to be called right after @kn is created to enable namespace
199  * under it.  All children of @kn must have non-NULL namespace tags and
200  * only the ones which match the super_block's tag will be visible.
201  */
202 static inline void kernfs_enable_ns(struct kernfs_node *kn)
203 {
204 	WARN_ON_ONCE(kernfs_type(kn) != KERNFS_DIR);
205 	WARN_ON_ONCE(!RB_EMPTY_ROOT(&kn->dir.children));
206 	kn->flags |= KERNFS_NS;
207 }
208 
209 /**
210  * kernfs_ns_enabled - test whether namespace is enabled
211  * @kn: the node to test
212  *
213  * Test whether namespace filtering is enabled for the children of @ns.
214  */
215 static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
216 {
217 	return kn->flags & KERNFS_NS;
218 }
219 
220 struct kernfs_node *kernfs_find_and_get_ns(struct kernfs_node *parent,
221 					   const char *name, const void *ns);
222 void kernfs_get(struct kernfs_node *kn);
223 void kernfs_put(struct kernfs_node *kn);
224 
225 struct kernfs_root *kernfs_create_root(struct kernfs_dir_ops *kdops,
226 				       void *priv);
227 void kernfs_destroy_root(struct kernfs_root *root);
228 
229 struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
230 					 const char *name, umode_t mode,
231 					 void *priv, const void *ns);
232 struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
233 					 const char *name,
234 					 umode_t mode, loff_t size,
235 					 const struct kernfs_ops *ops,
236 					 void *priv, const void *ns,
237 					 bool name_is_static,
238 					 struct lock_class_key *key);
239 struct kernfs_node *kernfs_create_link(struct kernfs_node *parent,
240 				       const char *name,
241 				       struct kernfs_node *target);
242 void kernfs_remove(struct kernfs_node *kn);
243 int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
244 			     const void *ns);
245 int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
246 		     const char *new_name, const void *new_ns);
247 int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
248 void kernfs_notify(struct kernfs_node *kn);
249 
250 const void *kernfs_super_ns(struct super_block *sb);
251 struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags,
252 			       struct kernfs_root *root, const void *ns);
253 void kernfs_kill_sb(struct super_block *sb);
254 
255 void kernfs_init(void);
256 
257 #else	/* CONFIG_SYSFS */
258 
259 static inline enum kernfs_node_type kernfs_type(struct kernfs_node *kn)
260 { return 0; }	/* whatever */
261 
262 static inline void kernfs_enable_ns(struct kernfs_node *kn) { }
263 
264 static inline bool kernfs_ns_enabled(struct kernfs_node *kn)
265 { return false; }
266 
267 static inline struct kernfs_node *
268 kernfs_find_and_get_ns(struct kernfs_node *parent, const char *name,
269 		       const void *ns)
270 { return NULL; }
271 
272 static inline void kernfs_get(struct kernfs_node *kn) { }
273 static inline void kernfs_put(struct kernfs_node *kn) { }
274 
275 static inline struct kernfs_root *
276 kernfs_create_root(struct kernfs_dir_ops *kdops, void *priv)
277 { return ERR_PTR(-ENOSYS); }
278 
279 static inline void kernfs_destroy_root(struct kernfs_root *root) { }
280 
281 static inline struct kernfs_node *
282 kernfs_create_dir_ns(struct kernfs_node *parent, const char *name,
283 		     umode_t mode, void *priv, const void *ns)
284 { return ERR_PTR(-ENOSYS); }
285 
286 static inline struct kernfs_node *
287 __kernfs_create_file(struct kernfs_node *parent, const char *name,
288 		     umode_t mode, loff_t size, const struct kernfs_ops *ops,
289 		     void *priv, const void *ns, bool name_is_static,
290 		     struct lock_class_key *key)
291 { return ERR_PTR(-ENOSYS); }
292 
293 static inline struct kernfs_node *
294 kernfs_create_link(struct kernfs_node *parent, const char *name,
295 		   struct kernfs_node *target)
296 { return ERR_PTR(-ENOSYS); }
297 
298 static inline void kernfs_remove(struct kernfs_node *kn) { }
299 
300 static inline int kernfs_remove_by_name_ns(struct kernfs_node *kn,
301 					   const char *name, const void *ns)
302 { return -ENOSYS; }
303 
304 static inline int kernfs_rename_ns(struct kernfs_node *kn,
305 				   struct kernfs_node *new_parent,
306 				   const char *new_name, const void *new_ns)
307 { return -ENOSYS; }
308 
309 static inline int kernfs_setattr(struct kernfs_node *kn,
310 				 const struct iattr *iattr)
311 { return -ENOSYS; }
312 
313 static inline void kernfs_notify(struct kernfs_node *kn) { }
314 
315 static inline const void *kernfs_super_ns(struct super_block *sb)
316 { return NULL; }
317 
318 static inline struct dentry *
319 kernfs_mount_ns(struct file_system_type *fs_type, int flags,
320 		struct kernfs_root *root, const void *ns)
321 { return ERR_PTR(-ENOSYS); }
322 
323 static inline void kernfs_kill_sb(struct super_block *sb) { }
324 
325 static inline void kernfs_init(void) { }
326 
327 #endif	/* CONFIG_SYSFS */
328 
329 static inline struct kernfs_node *
330 kernfs_find_and_get(struct kernfs_node *kn, const char *name)
331 {
332 	return kernfs_find_and_get_ns(kn, name, NULL);
333 }
334 
335 static inline struct kernfs_node *
336 kernfs_create_dir(struct kernfs_node *parent, const char *name, umode_t mode,
337 		  void *priv)
338 {
339 	return kernfs_create_dir_ns(parent, name, mode, priv, NULL);
340 }
341 
342 static inline struct kernfs_node *
343 kernfs_create_file_ns(struct kernfs_node *parent, const char *name,
344 		      umode_t mode, loff_t size, const struct kernfs_ops *ops,
345 		      void *priv, const void *ns)
346 {
347 	struct lock_class_key *key = NULL;
348 
349 #ifdef CONFIG_DEBUG_LOCK_ALLOC
350 	key = (struct lock_class_key *)&ops->lockdep_key;
351 #endif
352 	return __kernfs_create_file(parent, name, mode, size, ops, priv, ns,
353 				    false, key);
354 }
355 
356 static inline struct kernfs_node *
357 kernfs_create_file(struct kernfs_node *parent, const char *name, umode_t mode,
358 		   loff_t size, const struct kernfs_ops *ops, void *priv)
359 {
360 	return kernfs_create_file_ns(parent, name, mode, size, ops, priv, NULL);
361 }
362 
363 static inline int kernfs_remove_by_name(struct kernfs_node *parent,
364 					const char *name)
365 {
366 	return kernfs_remove_by_name_ns(parent, name, NULL);
367 }
368 
369 static inline struct dentry *
370 kernfs_mount(struct file_system_type *fs_type, int flags,
371 	     struct kernfs_root *root)
372 {
373 	return kernfs_mount_ns(fs_type, flags, root, NULL);
374 }
375 
376 #endif	/* __LINUX_KERNFS_H */
377