xref: /dragonfly/sys/sys/devfs.h (revision d4ef6694)
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #ifndef _SYS_DEVFS_H_
35 #define	_SYS_DEVFS_H_
36 
37 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
38 
39 #ifndef _SYS_QUEUE_H_
40 #include <sys/queue.h>
41 #endif
42 #ifndef _SYS_LOCK_H_
43 #include <sys/lock.h>
44 #endif
45 #ifndef _SYS_CONF_H_
46 #include <sys/conf.h>
47 #endif
48 #ifndef _SYS_MSGPORT_H_
49 #include <sys/msgport.h>
50 #endif
51 #ifndef _SYS_DIRENT_H_
52 #include <sys/dirent.h>
53 #endif
54 #ifndef _SYS_DEVICE_H_
55 #include <sys/device.h>
56 #endif
57 #ifndef _SYS_UCRED_H_
58 #include <sys/ucred.h>
59 #endif
60 
61 
62 typedef enum {
63 	Nroot,		/* the filesystem root */
64 	Nlink,
65 	Nreg,
66 	Ndir,
67 	Ndev
68 } devfs_nodetype;
69 
70 struct devfs_dirent {
71 	ino_t		d_ino;		/* file number of entry */
72 	uint16_t	d_namlen;	/* strlen(d_name) */
73 	uint8_t		d_type;		/* file type */
74 	char		*d_name;
75 };
76 
77 struct devfs_fid {
78 	uint16_t	fid_len;	/* Length of structure. */
79 	uint16_t	fid_pad;	/* Force 32-bit alignment. */
80 	uint32_t	fid_gen;
81 	ino_t		fid_ino;	/* File number (ino). */
82 };
83 
84 struct devfs_node {
85 	cdev_t		d_dev;		/* device associated with this node */
86 
87 	struct mount 	*mp;		/* mount point of this node */
88 	struct devfs_dirent d_dir;	/* dirent data (name, inode, ...) */
89 	struct vnode 	*v_node;	/* associated vnode */
90 	struct devfs_node *parent;	/* parent of this node */
91 	devfs_nodetype	node_type;	/* devfs node type */
92 
93 	u_int64_t	refs;		/* number of open references */
94 	size_t		nchildren;	/* number of children of a parent */
95 	u_int64_t	cookie_jar;	/* cookie pool for children */
96 	u_int64_t	cookie;		/* directory entry cookie for readdir */
97 
98 	struct devfs_node *link_target;	/* target of this autolink-type node */
99 	size_t		nlinks;		/* hard links */
100 
101 	char		*symlink_name;	/* symlink name for readlink */
102 	size_t		symlink_namelen; /* symlink name length for readlink */
103 
104 	u_short		mode;		/* files access mode and type */
105 	uid_t		uid;		/* owner user id */
106 	gid_t		gid;		/* owner group id */
107 	u_long		flags;
108 
109 	struct timespec	atime;		/* time of last access */
110 	struct timespec	mtime;		/* time of last modification */
111 	struct timespec	ctime;		/* time file changed */
112 
113 	TAILQ_ENTRY(devfs_node) link;
114 	TAILQ_HEAD(, devfs_node) list;	/* linked list of children */
115 };
116 
117 struct devfs_orphan {
118 	struct devfs_node *node;
119 	TAILQ_ENTRY(devfs_orphan) link;
120 };
121 
122 struct devfs_mnt_data {
123 	TAILQ_HEAD(, devfs_orphan) orphan_list;
124 	TAILQ_ENTRY(devfs_mnt_data) link;
125 
126 	struct devfs_node *root_node;
127 	struct mount	*mp;
128 	uint32_t	mnt_type;
129 	long		leak_count;
130 	long		file_count;
131 	int		jailed;
132 	size_t		mntonnamelen;
133 };
134 
135 struct devfs_clone_handler {
136 	char		*name;
137 	u_char		namlen;
138 	d_clone_t	*nhandler;
139 	TAILQ_ENTRY(devfs_clone_handler) link;
140 };
141 
142 
143 struct devfs_alias {
144 	char		*name;
145 	size_t		namlen;
146 	cdev_t		dev_target;
147 	TAILQ_ENTRY(devfs_alias) link;
148 };
149 
150 struct devfs_dev_ops {
151 	struct dev_ops *ops;
152 	int	ref_count;
153 	int id;
154 	TAILQ_ENTRY(devfs_dev_ops) link;
155 };
156 
157 typedef struct devfs_msg {
158 	struct lwkt_msg	hdr;
159 
160 	union {
161 		struct {
162 			cdev_t	dev;
163 			uid_t	uid;
164 			gid_t	gid;
165 			int	perms;
166 		} __m_dev;
167 		struct {
168 			struct devfs_mnt_data *mnt;
169 		} __m_mnt;
170 		struct {
171 			const char	*name;
172 			d_clone_t	*nhandler;
173 		} __m_chandler;
174 		struct {
175 			void *load;
176 			void *load2;
177 		} __m_gen;
178 		struct {
179 			void *resp;
180 		} __m_resp;
181 		struct {
182 			udev_t	udev;
183 		} __m_udev;
184 		struct {
185 			cdev_t	cdev;
186 		} __m_cdev;
187 		struct {
188 			char	*name;
189 		} __m_name;
190 		struct {
191 			char	*basename;
192 			u_char	unit;
193 			struct vnode *vp;
194 		} __m_clone;
195 		struct {
196 			struct devfs_node *node;
197 		} __m_node;
198 		struct {
199 			char	*name;
200 			char	*target;
201 			struct mount *mp;
202 		} __m_link;
203 		struct {
204 			struct dev_ops *ops;
205 			int	minor;
206 		} __m_ops;
207 		struct {
208 			cdev_t		dev;
209 			uint32_t	flag;
210 		} __m_flags;
211 		struct {
212 			ino_t	ino;
213 			struct vnode *vp;
214 			struct mount *mp;
215 		} __m_ino;
216 	} __m_u;
217 } *devfs_msg_t;
218 
219 #define mdv_chandler	__m_u.__m_chandler
220 #define mdv_mnt		__m_u.__m_mnt.mnt
221 #define mdv_load	__m_u.__m_gen.load
222 #define mdv_load2	__m_u.__m_gen.load2
223 #define mdv_response	__m_u.__m_resp.resp
224 #define mdv_dev		__m_u.__m_dev
225 #define mdv_link	__m_u.__m_link
226 #define mdv_udev	__m_u.__m_udev.udev
227 #define mdv_cdev	__m_u.__m_cdev.cdev
228 #define mdv_name	__m_u.__m_name.name
229 #define mdv_clone	__m_u.__m_clone
230 #define mdv_node	__m_u.__m_node.node
231 #define mdv_ops		__m_u.__m_ops
232 #define mdv_flags	__m_u.__m_flags
233 #define mdv_ino		__m_u.__m_ino
234 
235 
236 typedef struct devfs_core_args {
237 	thread_t     td;
238 } *devfs_core_args_t;
239 
240 TAILQ_HEAD(devfs_node_head, devfs_node);
241 TAILQ_HEAD(devfs_dev_head, cdev);
242 TAILQ_HEAD(devfs_mnt_head, devfs_mnt_data);
243 TAILQ_HEAD(devfs_chandler_head, devfs_clone_handler);
244 TAILQ_HEAD(devfs_alias_head, devfs_alias);
245 TAILQ_HEAD(devfs_dev_ops_head, devfs_dev_ops);
246 
247 typedef void (devfs_scan_t)(char *, cdev_t, bool, void *);
248 typedef void* (devfs_iterate_callback_t)(struct devfs_node *, void *);
249 
250 #define DEVFS_NODE(x)		((struct devfs_node *)((x)->v_data))
251 #define DEVFS_MNTDATA(x)	((struct devfs_mnt_data *)((x)->mnt_data))
252 #define DEVFS_ORPHANLIST(x)	(&(DEVFS_MNTDATA(x)->orphan_list))
253 #define DEVFS_DENODE_HEAD(x)	(&((x)->list))
254 #define DEVFS_ISDIGIT(x)	((x >= '0') && (x <= '9'))
255 
256 /*
257  * -rwxr-xr-x
258  */
259 #define DEVFS_DEFAULT_MODE	((VREAD|VWRITE|VEXEC) | ((VREAD|VEXEC)>>3) | \
260 				 ((VREAD|VEXEC)>>6));
261 
262 #define DEVFS_DEFAULT_UID	0	/* root */
263 #define DEVFS_DEFAULT_GID	0	/* wheel */
264 
265 /*
266  * debug levels
267  */
268 #define DEVFS_DEBUG_SHOW	0x00
269 #define DEVFS_DEBUG_WARNING	0x01
270 #define DEVFS_DEBUG_INFO	0x02
271 #define DEVFS_DEBUG_DEBUG	0x03
272 
273 /*
274  * Message ids
275  */
276 #define DEVFS_TERMINATE_CORE		0x01
277 #define DEVFS_DEVICE_CREATE		0x02
278 #define DEVFS_DEVICE_DESTROY		0x03
279 #define DEVFS_MOUNT_ADD			0x04
280 #define DEVFS_MOUNT_DEL			0x05
281 #define DEVFS_CREATE_ALL_DEV		0x06
282 #define DEVFS_DESTROY_RELATED		0x07
283 #define DEVFS_DESTROY_DEV_BY_OPS	0x08
284 #define DEVFS_CHANDLER_ADD		0x09
285 #define DEVFS_CHANDLER_DEL		0x0A
286 #define DEVFS_FIND_DEVICE_BY_UDEV	0x0B
287 #define DEVFS_FIND_DEVICE_BY_NAME	0x0C
288 #define DEVFS_MAKE_ALIAS		0x0D
289 #define DEVFS_DESTROY_ALIAS		0x0E
290 #define DEVFS_APPLY_RULES		0x0F
291 #define	DEVFS_RESET_RULES		0x10
292 #define DEVFS_SCAN_CALLBACK		0x11
293 #define DEVFS_CLR_RELATED_FLAG		0x12
294 #define DEVFS_DESTROY_RELATED_WO_FLAG	0x13
295 #define DEVFS_INODE_TO_VNODE		0x14
296 #define DEVFS_SYNC			0x99
297 
298 /*
299  * Node flags
300  *
301  * HIDDEN	Makes node inaccessible, apart from already allocated vnodes
302  * INVISIBLE	Makes node invisible in a readdir()
303  */
304 #define DEVFS_NODE_LINKED		0x001	/* Linked into topology */
305 #define	DEVFS_USER_CREATED		0x002	/* Node was user-created */
306 #define DEVFS_ORPHANED			0x004	/* on orphan list */
307 #define DEVFS_CLONED			0x008	/* Created by cloning code */
308 #define DEVFS_HIDDEN			0x010	/* Makes node inaccessible */
309 #define DEVFS_INVISIBLE			0x020	/* Makes node invisible */
310 #define	DEVFS_PTY			0x040	/* PTY device */
311 #define DEVFS_DESTROYED			0x080	/* Sanity check */
312 #define DEVFS_RULE_CREATED		0x100	/* Node was rule-created */
313 #define DEVFS_RULE_HIDDEN		0x200	/* Node was hidden by a rule */
314 
315 /*
316  * Clone helper stuff
317  */
318 #define DEVFS_BITMAP_INITIAL_SIZE	1
319 #define DEVFS_CLONE_BITMAP(name)	devfs_ ## name ## _clone_bitmap
320 #define DEVFS_DECLARE_CLONE_BITMAP(name) \
321 				struct devfs_bitmap DEVFS_CLONE_BITMAP(name)
322 
323 struct devfs_bitmap {
324 	int		chunks;
325 	unsigned long	*bitmap;
326 };
327 
328 struct devfs_unit_hash {
329         struct devfs_unit_hash *next;
330         int		unit_no;
331 	cdev_t		dev;
332 };
333 
334 void devfs_clone_bitmap_init(struct devfs_bitmap *);
335 void devfs_clone_bitmap_uninit(struct devfs_bitmap *);
336 void devfs_clone_bitmap_resize(struct devfs_bitmap *, int);
337 int devfs_clone_bitmap_fff(struct devfs_bitmap *);
338 void devfs_clone_bitmap_set(struct devfs_bitmap *, int);
339 int devfs_clone_bitmap_get(struct devfs_bitmap *, int);
340 int devfs_clone_bitmap_chk(struct devfs_bitmap *, int);
341 void devfs_clone_bitmap_put(struct devfs_bitmap *, int);
342 
343 /*
344  * Prototypes
345  */
346 int devfs_debug(int level, char *fmt, ...) __printflike(2, 3);
347 int devfs_allocv(struct vnode **, struct devfs_node *);
348 struct devfs_node *devfs_allocp(devfs_nodetype, char *, struct devfs_node *,
349 				struct mount *, cdev_t);
350 int devfs_allocvp(struct mount *, struct vnode **, devfs_nodetype, char *,
351 				struct devfs_node *, cdev_t);
352 
353 int devfs_freep(struct devfs_node *);
354 
355 int devfs_unlinkp(struct devfs_node *);
356 
357 void devfs_tracer_add_orphan(struct devfs_node *);
358 void devfs_tracer_del_orphan(struct devfs_node *);
359 size_t devfs_tracer_orphan_count(struct mount *, int);
360 
361 int devfs_set_perms(struct devfs_node *, uid_t, gid_t, u_short, u_long);
362 int devfs_gc(struct devfs_node *);
363 
364 int devfs_create_dev(cdev_t, uid_t, gid_t, int);
365 int devfs_destroy_dev(cdev_t);
366 
367 devfs_msg_t devfs_msg_send_sync(uint32_t, devfs_msg_t);
368 void devfs_msg_send(uint32_t, devfs_msg_t);
369 void devfs_msg_send_dev(uint32_t, cdev_t dev, uid_t, gid_t, int);
370 void devfs_msg_send_mount(uint32_t, struct devfs_mnt_data *);
371 void devfs_msg_send_ops(uint32_t, struct dev_ops *, int);
372 void devfs_msg_send_chandler(uint32_t, char *, d_clone_t);
373 void devfs_msg_send_generic(uint32_t, void *);
374 void devfs_msg_send_name(uint32_t, char *);
375 void devfs_msg_send_link(uint32_t, char *, char *, struct mount *);
376 
377 devfs_msg_t devfs_msg_get(void);
378 int devfs_msg_put(devfs_msg_t);
379 
380 int devfs_mount_add(struct devfs_mnt_data *);
381 int devfs_mount_del(struct devfs_mnt_data *);
382 
383 int devfs_create_all_dev(struct devfs_node *);
384 
385 struct devfs_node *devfs_resolve_or_create_path(
386 				struct devfs_node *, char *, int);
387 int devfs_resolve_name_path(char *, char *, char **, char **);
388 struct devfs_node *devfs_create_device_node(struct devfs_node *, cdev_t,
389 		      char *, char *, ...) __printf0like(4, 5);
390 
391 int devfs_destroy_device_node(struct devfs_node *, cdev_t);
392 int devfs_destroy_node(struct devfs_node *, char *);
393 int devfs_destroy_related(cdev_t);
394 int devfs_destroy_dev_by_ops(struct dev_ops *, int);
395 struct devfs_node *devfs_find_device_node_by_name(struct devfs_node *, char *);
396 
397 cdev_t devfs_new_cdev(struct dev_ops *, int, struct dev_ops *);
398 void devfs_assume_knotes(cdev_t dev, struct kqinfo *kqi);
399 
400 cdev_t devfs_find_device_by_name(const char *, ...) __printflike(1, 2);
401 cdev_t devfs_find_device_by_udev(udev_t);
402 
403 struct vnode *devfs_inode_to_vnode(struct mount *, ino_t);
404 
405 int devfs_clone_handler_add(const char *, d_clone_t *);
406 int devfs_clone_handler_del(const char *);
407 cdev_t devfs_clone(cdev_t, const char *, size_t, int, struct ucred *);
408 
409 int devfs_link_dev(cdev_t);
410 
411 int devfs_make_alias(const char *, cdev_t);
412 int devfs_destroy_alias(const char *, cdev_t);
413 
414 int devfs_alias_create(char *, struct devfs_node *, int);
415 
416 int devfs_apply_rules(char *);
417 int devfs_reset_rules(char *);
418 
419 int devfs_scan_callback(devfs_scan_t *, void *);
420 
421 int devfs_clr_related_flag(cdev_t, uint32_t);
422 int devfs_destroy_related_without_flag(cdev_t, uint32_t);
423 int devfs_node_is_accessible(struct devfs_node *);
424 
425 int devfs_reference_ops(struct dev_ops *);
426 void devfs_release_ops(struct dev_ops *);
427 
428 void devfs_config(void);
429 
430 void *devfs_iterate_topology(struct devfs_node *node,
431 		devfs_iterate_callback_t *callback, void *arg1);
432 
433 void *devfs_find_device_node_callback(struct devfs_node *, cdev_t);
434 
435 typedef void (*cdevpriv_dtr_t)(void *data);
436 int devfs_get_cdevpriv(struct file *file, void **datap);
437 int devfs_set_cdevpriv(struct file *file, void *priv, cdevpriv_dtr_t dtr);
438 void devfs_clear_cdevpriv(struct file *file);
439 
440 int devfs_WildCmp(const char *w, const char *s);
441 int devfs_WildCaseCmp(const char *w, const char *s);
442 
443 #endif /* KERNEL */
444 
445 #define DEVFS_MNT_RULESET	0x01
446 #define DEVFS_MNT_JAIL		0x02
447 
448 struct devfs_mount_info {
449 	int flags;
450 };
451 
452 #endif /* _SYS_DEVFS_H_ */
453